Check only concrete defaults for well formedness
This commit is contained in:
parent
c74f85f935
commit
a7c7c8a4d7
4 changed files with 24 additions and 32 deletions
src
librustc_typeck/check
test
|
@ -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.
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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
|
||||
error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied
|
||||
--> $DIR/type-check-defaults.rs:21:1
|
||||
|
|
||||
21 | struct WellFormedProjection<A, T=<A as Iterator>::Item>(A, T);
|
||||
| ^ `A` is not an iterator; maybe try calling `.iter()` or a similar method
|
||||
21 | struct Bounds<T:Copy=String>(T);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String`
|
||||
|
|
||||
= 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`
|
||||
= 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:24:1
|
||||
|
|
||||
24 | struct Bounds<T:Copy=String>(T);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String`
|
||||
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:27:1
|
||||
|
|
||||
27 | 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
|
||||
|
|
||||
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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue