From 35499aa9fcef2cab965f0c1e04da1b97ec715d64 Mon Sep 17 00:00:00 2001 From: "leonardo.yvens" Date: Sat, 20 Jan 2018 13:33:44 -0200 Subject: [PATCH] Expand comments, address nits. --- src/librustc_typeck/check/wfcheck.rs | 19 +++++++++---- src/test/ui/type-check-defaults.rs | 4 +++ src/test/ui/type-check-defaults.stderr | 39 ++++++++++++++++++++++---- 3 files changed, 52 insertions(+), 10 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 7648feea457d..91c5b8703c28 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -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> { .. } + // 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 { .. } + // + // 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(); diff --git a/src/test/ui/type-check-defaults.rs b/src/test/ui/type-check-defaults.rs index 7c379a1f1bc9..8f0714ebc3b1 100644 --- a/src/test/ui/type-check-defaults.rs +++ b/src/test/ui/type-check-defaults.rs @@ -44,4 +44,8 @@ struct Bogus(TwoParams) where TwoParams: Trait; //~^ error: the trait bound `TwoParams: Trait` is not satisfied [E0277] //~^^ error: the trait bound `TwoParams: Trait` is not satisfied [E0277] +trait Super { } +trait Base: Super { } +//~^ error: the trait bound `T: std::marker::Copy` is not satisfied [E0277] + fn main() { } diff --git a/src/test/ui/type-check-defaults.stderr b/src/test/ui/type-check-defaults.stderr index 3ac6e4c26b4f..8be46a53370e 100644 --- a/src/test/ui/type-check-defaults.stderr +++ b/src/test/ui/type-check-defaults.stderr @@ -5,7 +5,11 @@ error[E0277]: the trait bound `i32: std::iter::FromIterator` 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` 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); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `i32: std::iter::FromIterator` is not satisfied --> $DIR/type-check-defaults.rs:18:27 @@ -14,7 +18,11 @@ error[E0277]: the trait bound `i32: std::iter::FromIterator` 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` 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); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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: Trait` is not satisfied | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `TwoParams` | = help: consider adding a `where TwoParams: 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: Trait` is not satisfied --> $DIR/type-check-defaults.rs:43:1 @@ -83,7 +95,24 @@ error[E0277]: the trait bound `TwoParams: Trait` is not satisfied | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `TwoParams` | = help: consider adding a `where TwoParams: 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: Super { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 { } + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 11 previous errors