diff options
| -rw-r--r-- | src/librustc_typeck/check/wfcheck.rs | 11 | ||||
| -rw-r--r-- | src/test/run-pass/defaults-well-formedness.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/type-check-defaults.rs | 3 | ||||
| -rw-r--r-- | src/test/ui/type-check-defaults.stderr | 36 |
4 files changed, 22 insertions, 30 deletions
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 258860d3d5e..4eb3e29ec69 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -363,13 +363,16 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { let generics = self.tcx.generics_of(def_id); let is_our_default = |def: &ty::TypeParameterDef| def.has_default && def.index >= generics.parent_count() as u32; - let defaulted_params = generics.types.iter().cloned().filter(&is_our_default); - // Check that defaults are well-formed. See test `type-check-defaults.rs`. + + // Check that concrete defaults are well-formed. See test `type-check-defaults.rs`. // For example this forbids the declaration: // struct Foo<T = Vec<[u32]>> { .. } // Here the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold. - for d in defaulted_params.map(|p| p.def_id) { - fcx.register_wf_obligation(fcx.tcx.type_of(d), fcx.tcx.def_span(d), self.code.clone()); + for d in generics.types.iter().cloned().filter(is_our_default).map(|p| p.def_id) { + let ty = fcx.tcx.type_of(d); + if !ty.needs_subst() { + fcx.register_wf_obligation(ty, fcx.tcx.def_span(d), self.code.clone()); + } } // Check that trait predicates are WF when params are substituted by their defaults. diff --git a/src/test/run-pass/defaults-well-formedness.rs b/src/test/run-pass/defaults-well-formedness.rs index 552665bac4e..f3594679095 100644 --- a/src/test/run-pass/defaults-well-formedness.rs +++ b/src/test/run-pass/defaults-well-formedness.rs @@ -24,5 +24,7 @@ struct DefaultedLhs<U, V=i32>(U, V) where V: Trait<U>; // Dependent defaults are not checked. struct Dependent<T, U = T>(T, U) where U: Copy; trait SelfBound<T: Copy=Self> {} +// Not even for well-formedness. +struct WellFormedProjection<A, T=<A as Iterator>::Item>(A, T); fn main() {} diff --git a/src/test/ui/type-check-defaults.rs b/src/test/ui/type-check-defaults.rs index 65560df9f21..f916df5d32d 100644 --- a/src/test/ui/type-check-defaults.rs +++ b/src/test/ui/type-check-defaults.rs @@ -18,9 +18,6 @@ struct WellFormed<Z = Foo<i32, i32>>(Z); struct WellFormedNoBounds<Z:?Sized = Foo<i32, i32>>(Z); //~^ error: the trait bound `i32: std::iter::FromIterator<i32>` is not satisfied [E0277] -struct WellFormedProjection<A, T=<A as Iterator>::Item>(A, T); -//~^ error: the trait bound `A: std::iter::Iterator` is not satisfied [E0277] - struct Bounds<T:Copy=String>(T); //~^ error: the trait bound `std::string::String: std::marker::Copy` is not satisfied [E0277] diff --git a/src/test/ui/type-check-defaults.stderr b/src/test/ui/type-check-defaults.stderr index c73c0792f8e..4af8f5da0dd 100644 --- a/src/test/ui/type-check-defaults.stderr +++ b/src/test/ui/type-check-defaults.stderr @@ -24,61 +24,51 @@ note: required by `Foo` 15 | struct Foo<T, U: FromIterator<T>>(T, U); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `A: std::iter::Iterator` is not satisfied - --> $DIR/type-check-defaults.rs:21:32 - | -21 | struct WellFormedProjection<A, T=<A as Iterator>::Item>(A, T); - | ^ `A` is not an iterator; maybe try calling `.iter()` or a similar method - | - = help: the trait `std::iter::Iterator` is not implemented for `A` - = help: consider adding a `where A: std::iter::Iterator` bound - = note: required by `std::iter::Iterator` - error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied - --> $DIR/type-check-defaults.rs:24:1 + --> $DIR/type-check-defaults.rs:21:1 | -24 | struct Bounds<T:Copy=String>(T); +21 | struct Bounds<T:Copy=String>(T); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String` | = note: required by `std::marker::Copy` error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied - --> $DIR/type-check-defaults.rs:27:1 + --> $DIR/type-check-defaults.rs:24:1 | -27 | struct WhereClause<T=String>(T) where T: Copy; +24 | struct WhereClause<T=String>(T) where T: Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String` | = note: required by `std::marker::Copy` error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied - --> $DIR/type-check-defaults.rs:30:1 + --> $DIR/type-check-defaults.rs:27:1 | -30 | trait TraitBound<T:Copy=String> {} +27 | trait TraitBound<T:Copy=String> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String` | = note: required by `std::marker::Copy` error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied - --> $DIR/type-check-defaults.rs:34:1 + --> $DIR/type-check-defaults.rs:31:1 | -34 | trait Base<T = String>: Super<T> { } +31 | trait Base<T = String>: Super<T> { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` | = help: consider adding a `where T: std::marker::Copy` bound note: required by `Super` - --> $DIR/type-check-defaults.rs:33:1 + --> $DIR/type-check-defaults.rs:30:1 | -33 | trait Super<T: Copy> { } +30 | trait Super<T: Copy> { } | ^^^^^^^^^^^^^^^^^^^^ error[E0277]: cannot add `u8` to `i32` - --> $DIR/type-check-defaults.rs:37:1 + --> $DIR/type-check-defaults.rs:34:1 | -37 | trait ProjectionPred<T:Iterator = IntoIter<i32>> where T::Item : Add<u8> {} +34 | trait ProjectionPred<T:Iterator = IntoIter<i32>> where T::Item : Add<u8> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `i32 + u8` | = help: the trait `std::ops::Add<u8>` is not implemented for `i32` = note: required by `std::ops::Add` -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors |
