Check WF of defaults even when there are no bounds.
This commit is contained in:
parent
4d9703373d
commit
a6bb32c9cc
@ -359,6 +359,16 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
use ty::subst::Subst;
|
||||
use ty::Predicate;
|
||||
|
||||
let generics = self.tcx.generics_of(def_id);
|
||||
let defaults = generics.types.iter().filter_map(|p| match p.has_default {
|
||||
true => Some(p.def_id),
|
||||
false => None,
|
||||
});
|
||||
// Defaults must be well-formed.
|
||||
for d in defaults {
|
||||
fcx.register_wf_obligation(fcx.tcx.type_of(d), fcx.tcx.def_span(d), self.code.clone());
|
||||
}
|
||||
|
||||
// Check that each default fulfills the bounds on it's parameter.
|
||||
// We go over each predicate and duplicate it, substituting defaults in the self type.
|
||||
let mut predicates = fcx.tcx.predicates_of(def_id);
|
||||
@ -377,7 +387,6 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
|
||||
let mut skip = false;
|
||||
let mut no_default = true;
|
||||
let generics = self.tcx.generics_of(def_id);
|
||||
let substs = ty::subst::Substs::for_item(fcx.tcx, def_id, |def, _| {
|
||||
// All regions are identity.
|
||||
fcx.tcx.mk_region(ty::ReEarlyBound(def.to_early_bound_region_data()))
|
||||
|
@ -15,6 +15,7 @@ use std::ops::Add;
|
||||
|
||||
struct Foo<T, U: FromIterator<T>>(T, U);
|
||||
struct WellFormed<Z = Foo<i32, i32>>(Z);
|
||||
struct WellFormedNoBounds<Z:?Sized = Foo<i32, i32>>(Z);
|
||||
|
||||
struct WellFormedProjection<A, T=<A as Iterator>::Item>(A, T);
|
||||
|
||||
|
@ -1,62 +1,71 @@
|
||||
error[E0277]: the trait bound `i32: std::iter::FromIterator<i32>` is not satisfied
|
||||
--> $DIR/type-check-defaults.rs:17:1
|
||||
--> $DIR/type-check-defaults.rs:17:19
|
||||
|
|
||||
17 | struct WellFormed<Z = Foo<i32, i32>>(Z);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a collection of type `i32` cannot be built from an iterator over elements of type `i32`
|
||||
| ^ a collection of type `i32` cannot be built from an iterator over elements of type `i32`
|
||||
|
|
||||
= help: the trait `std::iter::FromIterator<i32>` is not implemented for `i32`
|
||||
= note: required by `Foo`
|
||||
|
||||
error[E0277]: the trait bound `i32: std::iter::FromIterator<i32>` is not satisfied
|
||||
--> $DIR/type-check-defaults.rs:18:27
|
||||
|
|
||||
18 | struct WellFormedNoBounds<Z:?Sized = Foo<i32, i32>>(Z);
|
||||
| ^ a collection of type `i32` cannot be built from an iterator over elements of type `i32`
|
||||
|
|
||||
= help: the trait `std::iter::FromIterator<i32>` is not implemented for `i32`
|
||||
= note: required by `Foo`
|
||||
|
||||
error[E0277]: the trait bound `A: std::iter::Iterator` is not satisfied
|
||||
--> $DIR/type-check-defaults.rs:19:1
|
||||
--> $DIR/type-check-defaults.rs:20:1
|
||||
|
|
||||
19 | struct WellFormedProjection<A, T=<A as Iterator>::Item>(A, T);
|
||||
20 | 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
|
||||
|
||||
error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied
|
||||
--> $DIR/type-check-defaults.rs:21:1
|
||||
--> $DIR/type-check-defaults.rs:22:1
|
||||
|
|
||||
21 | struct Bounds<T:Copy=String>(T);
|
||||
22 | 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:23:1
|
||||
--> $DIR/type-check-defaults.rs:24:1
|
||||
|
|
||||
23 | 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:25:1
|
||||
--> $DIR/type-check-defaults.rs:26:1
|
||||
|
|
||||
25 | trait TraitBound<T:Copy=String> {}
|
||||
26 | 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 `Self: std::marker::Copy` is not satisfied
|
||||
--> $DIR/type-check-defaults.rs:27:1
|
||||
--> $DIR/type-check-defaults.rs:28:1
|
||||
|
|
||||
27 | trait SelfBound<T:Copy=Self> {}
|
||||
28 | trait SelfBound<T:Copy=Self> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `Self`
|
||||
|
|
||||
= help: consider adding a `where Self: std::marker::Copy` bound
|
||||
= note: required by `std::marker::Copy`
|
||||
|
||||
error[E0277]: the trait bound `i32: std::ops::Add<u8>` is not satisfied
|
||||
--> $DIR/type-check-defaults.rs:29:1
|
||||
--> $DIR/type-check-defaults.rs:30:1
|
||||
|
|
||||
29 | trait FooTrait<T:Iterator = IntoIter<i32>> where T::Item : Add<u8> {}
|
||||
30 | trait FooTrait<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 7 previous errors
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user