Skip to content

Commit 35499aa

Browse files
committed
Expand comments, address nits.
1 parent 7c1b684 commit 35499aa

File tree

3 files changed

+52
-10
lines changed

3 files changed

+52
-10
lines changed

src/librustc_typeck/check/wfcheck.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -381,22 +381,30 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
381381
let defaulted_params = generics.types.iter()
382382
.filter(|def| def.has_default &&
383383
def.index >= generics.parent_count() as u32);
384+
// WF checks for type parameter defaults. See test `type-check-defaults.rs` for examples.
384385
for param_def in defaulted_params {
385-
// Defaults must be well-formed.
386+
// This parameter has a default value. Check that this default value is well-formed.
387+
// For example this forbids the declaration:
388+
// struct Foo<T = Vec<[u32]>> { .. }
389+
// Here `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold.
386390
let d = param_def.def_id;
387391
fcx.register_wf_obligation(fcx.tcx.type_of(d), fcx.tcx.def_span(d), self.code.clone());
392+
388393
// Check the clauses are well-formed when the param is substituted by it's default.
389-
// In trait definitions, the predicate `Self: Trait` is problematic.
394+
// For example this forbids the following declaration because `String` is not `Copy`:
395+
// struct Foo<T: Copy = String> { .. }
396+
//
397+
// In `trait Trait: Super`, checking `Self: Trait` or `Self: Super` is problematic.
390398
// Therefore we skip such predicates. This means we check less than we could.
391399
for pred in predicates.predicates.iter().filter(|p| !(is_trait && p.has_self_ty())) {
392400
let mut skip = true;
393401
let substs = ty::subst::Substs::for_item(fcx.tcx, def_id, |def, _| {
394402
// All regions are identity.
395403
fcx.tcx.mk_region(ty::ReEarlyBound(def.to_early_bound_region_data()))
396404
}, |def, _| {
397-
let identity_substs = fcx.tcx.mk_param_from_def(def);
405+
let identity_ty = fcx.tcx.mk_param_from_def(def);
398406
if def.index != param_def.index {
399-
identity_substs
407+
identity_ty
400408
} else {
401409
let sized = fcx.tcx.lang_items().sized_trait();
402410
let pred_is_sized = match pred {
@@ -410,7 +418,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
410418
};
411419
// In trait defs, skip `Self: Sized` when `Self` is the default.
412420
if is_trait && pred_is_sized && default_is_self {
413-
identity_substs
421+
identity_ty
414422
} else {
415423
skip = false;
416424
default_ty
@@ -420,6 +428,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
420428
if skip { continue; }
421429
substituted_predicates.push(match pred {
422430
// In trait predicates, substitute defaults only for the LHS.
431+
// See test `defaults-well-formedness.rs` for why substituting the RHS is bad.
423432
ty::Predicate::Trait(t_pred) => {
424433
let trait_ref = t_pred.map_bound(|t_pred| {
425434
let mut trait_subs = t_pred.trait_ref.substs.to_vec();

src/test/ui/type-check-defaults.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,8 @@ struct Bogus<T = i32, U = i32>(TwoParams<T, U>) where TwoParams<T, U>: Trait;
4444
//~^ error: the trait bound `TwoParams<i32, U>: Trait` is not satisfied [E0277]
4545
//~^^ error: the trait bound `TwoParams<T, i32>: Trait` is not satisfied [E0277]
4646

47+
trait Super<T: Copy> { }
48+
trait Base<T = String>: Super<T> { }
49+
//~^ error: the trait bound `T: std::marker::Copy` is not satisfied [E0277]
50+
4751
fn main() { }

src/test/ui/type-check-defaults.stderr

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ error[E0277]: the trait bound `i32: std::iter::FromIterator<i32>` is not satisfi
55
| ^ a collection of type `i32` cannot be built from an iterator over elements of type `i32`
66
|
77
= help: the trait `std::iter::FromIterator<i32>` is not implemented for `i32`
8-
= note: required by `Foo`
8+
note: required by `Foo`
9+
--> $DIR/type-check-defaults.rs:15:1
10+
|
11+
15 | struct Foo<T, U: FromIterator<T>>(T, U);
12+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
913

1014
error[E0277]: the trait bound `i32: std::iter::FromIterator<i32>` is not satisfied
1115
--> $DIR/type-check-defaults.rs:18:27
@@ -14,7 +18,11 @@ error[E0277]: the trait bound `i32: std::iter::FromIterator<i32>` is not satisfi
1418
| ^ a collection of type `i32` cannot be built from an iterator over elements of type `i32`
1519
|
1620
= help: the trait `std::iter::FromIterator<i32>` is not implemented for `i32`
17-
= note: required by `Foo`
21+
note: required by `Foo`
22+
--> $DIR/type-check-defaults.rs:15:1
23+
|
24+
15 | struct Foo<T, U: FromIterator<T>>(T, U);
25+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1826

1927
error[E0277]: the trait bound `A: std::iter::Iterator` is not satisfied
2028
--> $DIR/type-check-defaults.rs:21:1
@@ -74,7 +82,11 @@ error[E0277]: the trait bound `TwoParams<i32, U>: Trait` is not satisfied
7482
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `TwoParams<i32, U>`
7583
|
7684
= help: consider adding a `where TwoParams<i32, U>: Trait` bound
77-
= note: required by `Trait`
85+
note: required by `Trait`
86+
--> $DIR/type-check-defaults.rs:39:1
87+
|
88+
39 | trait Trait {}
89+
| ^^^^^^^^^^^
7890

7991
error[E0277]: the trait bound `TwoParams<T, i32>: Trait` is not satisfied
8092
--> $DIR/type-check-defaults.rs:43:1
@@ -83,7 +95,24 @@ error[E0277]: the trait bound `TwoParams<T, i32>: Trait` is not satisfied
8395
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `TwoParams<T, i32>`
8496
|
8597
= help: consider adding a `where TwoParams<T, i32>: Trait` bound
86-
= note: required by `Trait`
98+
note: required by `Trait`
99+
--> $DIR/type-check-defaults.rs:39:1
100+
|
101+
39 | trait Trait {}
102+
| ^^^^^^^^^^^
103+
104+
error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
105+
--> $DIR/type-check-defaults.rs:48:1
106+
|
107+
48 | trait Base<T = String>: Super<T> { }
108+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
109+
|
110+
= help: consider adding a `where T: std::marker::Copy` bound
111+
note: required by `Super`
112+
--> $DIR/type-check-defaults.rs:47:1
113+
|
114+
47 | trait Super<T: Copy> { }
115+
| ^^^^^^^^^^^^^^^^^^^^
87116

88-
error: aborting due to 10 previous errors
117+
error: aborting due to 11 previous errors
89118

0 commit comments

Comments
 (0)