Expand comments, address nits.
This commit is contained in:
parent
7c1b6848db
commit
35499aa9fc
@ -381,12 +381,20 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
let defaulted_params = generics.types.iter()
|
||||
.filter(|def| def.has_default &&
|
||||
def.index >= generics.parent_count() as u32);
|
||||
// WF checks for type parameter defaults. See test `type-check-defaults.rs` for examples.
|
||||
for param_def in defaulted_params {
|
||||
// Defaults must be well-formed.
|
||||
// This parameter has a default value. Check that this default value is well-formed.
|
||||
// For example this forbids the declaration:
|
||||
// struct Foo<T = Vec<[u32]>> { .. }
|
||||
// Here `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold.
|
||||
let d = param_def.def_id;
|
||||
fcx.register_wf_obligation(fcx.tcx.type_of(d), fcx.tcx.def_span(d), self.code.clone());
|
||||
|
||||
// Check the clauses are well-formed when the param is substituted by it's default.
|
||||
// In trait definitions, the predicate `Self: Trait` is problematic.
|
||||
// For example this forbids the following declaration because `String` is not `Copy`:
|
||||
// struct Foo<T: Copy = String> { .. }
|
||||
//
|
||||
// In `trait Trait: Super`, checking `Self: Trait` or `Self: Super` is problematic.
|
||||
// Therefore we skip such predicates. This means we check less than we could.
|
||||
for pred in predicates.predicates.iter().filter(|p| !(is_trait && p.has_self_ty())) {
|
||||
let mut skip = true;
|
||||
@ -394,9 +402,9 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
// All regions are identity.
|
||||
fcx.tcx.mk_region(ty::ReEarlyBound(def.to_early_bound_region_data()))
|
||||
}, |def, _| {
|
||||
let identity_substs = fcx.tcx.mk_param_from_def(def);
|
||||
let identity_ty = fcx.tcx.mk_param_from_def(def);
|
||||
if def.index != param_def.index {
|
||||
identity_substs
|
||||
identity_ty
|
||||
} else {
|
||||
let sized = fcx.tcx.lang_items().sized_trait();
|
||||
let pred_is_sized = match pred {
|
||||
@ -410,7 +418,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
};
|
||||
// In trait defs, skip `Self: Sized` when `Self` is the default.
|
||||
if is_trait && pred_is_sized && default_is_self {
|
||||
identity_substs
|
||||
identity_ty
|
||||
} else {
|
||||
skip = false;
|
||||
default_ty
|
||||
@ -420,6 +428,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
if skip { continue; }
|
||||
substituted_predicates.push(match pred {
|
||||
// In trait predicates, substitute defaults only for the LHS.
|
||||
// See test `defaults-well-formedness.rs` for why substituting the RHS is bad.
|
||||
ty::Predicate::Trait(t_pred) => {
|
||||
let trait_ref = t_pred.map_bound(|t_pred| {
|
||||
let mut trait_subs = t_pred.trait_ref.substs.to_vec();
|
||||
|
@ -44,4 +44,8 @@ struct Bogus<T = i32, U = i32>(TwoParams<T, U>) where TwoParams<T, U>: Trait;
|
||||
//~^ error: the trait bound `TwoParams<i32, U>: Trait` is not satisfied [E0277]
|
||||
//~^^ error: the trait bound `TwoParams<T, i32>: Trait` is not satisfied [E0277]
|
||||
|
||||
trait Super<T: Copy> { }
|
||||
trait Base<T = String>: Super<T> { }
|
||||
//~^ error: the trait bound `T: std::marker::Copy` is not satisfied [E0277]
|
||||
|
||||
fn main() { }
|
||||
|
@ -5,7 +5,11 @@ error[E0277]: the trait bound `i32: std::iter::FromIterator<i32>` is not satisfi
|
||||
| ^ 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`
|
||||
note: required by `Foo`
|
||||
--> $DIR/type-check-defaults.rs:15:1
|
||||
|
|
||||
15 | struct Foo<T, U: FromIterator<T>>(T, U);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0277]: the trait bound `i32: std::iter::FromIterator<i32>` is not satisfied
|
||||
--> $DIR/type-check-defaults.rs:18:27
|
||||
@ -14,7 +18,11 @@ error[E0277]: the trait bound `i32: std::iter::FromIterator<i32>` is not satisfi
|
||||
| ^ 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`
|
||||
note: required by `Foo`
|
||||
--> $DIR/type-check-defaults.rs:15:1
|
||||
|
|
||||
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:1
|
||||
@ -74,7 +82,11 @@ error[E0277]: the trait bound `TwoParams<i32, U>: Trait` is not satisfied
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `TwoParams<i32, U>`
|
||||
|
|
||||
= help: consider adding a `where TwoParams<i32, U>: Trait` bound
|
||||
= note: required by `Trait`
|
||||
note: required by `Trait`
|
||||
--> $DIR/type-check-defaults.rs:39:1
|
||||
|
|
||||
39 | trait Trait {}
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error[E0277]: the trait bound `TwoParams<T, i32>: Trait` is not satisfied
|
||||
--> $DIR/type-check-defaults.rs:43:1
|
||||
@ -83,7 +95,24 @@ error[E0277]: the trait bound `TwoParams<T, i32>: Trait` is not satisfied
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `TwoParams<T, i32>`
|
||||
|
|
||||
= help: consider adding a `where TwoParams<T, i32>: Trait` bound
|
||||
= note: required by `Trait`
|
||||
note: required by `Trait`
|
||||
--> $DIR/type-check-defaults.rs:39:1
|
||||
|
|
||||
39 | trait Trait {}
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
|
||||
--> $DIR/type-check-defaults.rs:48:1
|
||||
|
|
||||
48 | 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:47:1
|
||||
|
|
||||
47 | trait Super<T: Copy> { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user