From 545320a22ff61c30e932200c07466ba3f2be76aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 22 Apr 2020 16:03:39 -0700 Subject: [PATCH 1/4] Suggest adding super trait constraints --- .../traits/error_reporting/suggestions.rs | 45 +++++++++++++++++-- .../defaults-unsound-62211-1.stderr | 16 +++++-- .../defaults-unsound-62211-2.stderr | 16 +++++-- .../ui/associated-types/issue-63593.stderr | 4 +- ...ait-with-supertraits-needing-sized-self.rs | 11 +++++ ...with-supertraits-needing-sized-self.stderr | 17 +++++++ 6 files changed, 96 insertions(+), 13 deletions(-) create mode 100644 src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.rs create mode 100644 src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.stderr diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs index e0b99333fd10b..5abae7ed68b99 100644 --- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs +++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::{ self, suggest_constraining_type_param, AdtKind, DefIdTree, Infer, InferTy, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, }; -use rustc_span::symbol::{kw, sym, Symbol}; +use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{MultiSpan, Span, DUMMY_SP}; use std::fmt; @@ -173,6 +173,7 @@ fn suggest_restriction( fn_sig: Option<&hir::FnSig<'_>>, projection: Option<&ty::ProjectionTy<'_>>, trait_ref: ty::PolyTraitRef<'_>, + super_traits: Option<(&Ident, &hir::GenericBounds<'_>)>, ) { let span = generics.where_clause.span_for_predicates_or_empty_place(); if span.from_expansion() || span.desugaring_kind().is_some() { @@ -262,8 +263,22 @@ fn suggest_restriction( ); } else { // Trivial case: `T` needs an extra bound: `T: Bound`. - let (sp, sugg) = - predicate_constraint(generics, trait_ref.without_const().to_predicate().to_string()); + let (sp, sugg) = match super_traits { + None => { + predicate_constraint(generics, trait_ref.without_const().to_predicate().to_string()) + } + Some((ident, bounds)) => match bounds { + [.., bound] => ( + bound.span().shrink_to_hi(), + format!(" + {}", trait_ref.print_only_trait_path().to_string()), + ), + [] => ( + ident.span.shrink_to_hi(), + format!(": {}", trait_ref.print_only_trait_path().to_string()), + ), + }, + }; + let appl = Applicability::MachineApplicable; err.span_suggestion(sp, &format!("consider further restricting {}", msg), sugg, appl); } @@ -288,13 +303,33 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let mut hir_id = body_id; while let Some(node) = self.tcx.hir().find(hir_id) { match node { + hir::Node::Item(hir::Item { + ident, + kind: hir::ItemKind::Trait(_, _, generics, bounds, _), + .. + }) if param_ty && self_ty == self.tcx.types.self_param => { + // Restricting `Self` for a single method. + suggest_restriction( + &generics, + "`Self`", + err, + None, + projection, + trait_ref, + Some((ident, bounds)), + ); + return; + } + hir::Node::TraitItem(hir::TraitItem { generics, kind: hir::TraitItemKind::Fn(..), .. }) if param_ty && self_ty == self.tcx.types.self_param => { // Restricting `Self` for a single method. - suggest_restriction(&generics, "`Self`", err, None, projection, trait_ref); + suggest_restriction( + &generics, "`Self`", err, None, projection, trait_ref, None, + ); return; } @@ -319,6 +354,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { Some(fn_sig), projection, trait_ref, + None, ); return; } @@ -336,6 +372,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { None, projection, trait_ref, + None, ); return; } diff --git a/src/test/ui/associated-types/defaults-unsound-62211-1.stderr b/src/test/ui/associated-types/defaults-unsound-62211-1.stderr index 856d513d60bd3..c804bc3d833fa 100644 --- a/src/test/ui/associated-types/defaults-unsound-62211-1.stderr +++ b/src/test/ui/associated-types/defaults-unsound-62211-1.stderr @@ -2,7 +2,9 @@ error[E0277]: the trait bound `Self: std::marker::Copy` is not satisfied --> $DIR/defaults-unsound-62211-1.rs:21:18 | LL | trait UncheckedCopy: Sized { - | -------------------------- required by `UncheckedCopy` + | --------------------------- help: consider further restricting `Self`: `+ std::marker::Copy` + | | + | required by `UncheckedCopy` ... LL | type Output: Copy | ^^^^ the trait `std::marker::Copy` is not implemented for `Self` @@ -11,7 +13,9 @@ error[E0277]: cannot add-assign `&'static str` to `Self` --> $DIR/defaults-unsound-62211-1.rs:25:7 | LL | trait UncheckedCopy: Sized { - | -------------------------- required by `UncheckedCopy` + | --------------------------- help: consider further restricting `Self`: `+ std::ops::AddAssign<&'static str>` + | | + | required by `UncheckedCopy` ... LL | + AddAssign<&'static str> | ^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `Self += &'static str` @@ -22,7 +26,9 @@ error[E0277]: the trait bound `Self: std::ops::Deref` is not satisfied --> $DIR/defaults-unsound-62211-1.rs:23:7 | LL | trait UncheckedCopy: Sized { - | -------------------------- required by `UncheckedCopy` + | --------------------------- help: consider further restricting `Self`: `+ std::ops::Deref` + | | + | required by `UncheckedCopy` ... LL | + Deref | ^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `Self` @@ -31,7 +37,9 @@ error[E0277]: `Self` doesn't implement `std::fmt::Display` --> $DIR/defaults-unsound-62211-1.rs:28:7 | LL | trait UncheckedCopy: Sized { - | -------------------------- required by `UncheckedCopy` + | --------------------------- help: consider further restricting `Self`: `+ std::fmt::Display` + | | + | required by `UncheckedCopy` ... LL | + Display = Self; | ^^^^^^^ `Self` cannot be formatted with the default formatter diff --git a/src/test/ui/associated-types/defaults-unsound-62211-2.stderr b/src/test/ui/associated-types/defaults-unsound-62211-2.stderr index 1060c82fec22a..aee5e4b28ca6d 100644 --- a/src/test/ui/associated-types/defaults-unsound-62211-2.stderr +++ b/src/test/ui/associated-types/defaults-unsound-62211-2.stderr @@ -2,7 +2,9 @@ error[E0277]: the trait bound `Self: std::marker::Copy` is not satisfied --> $DIR/defaults-unsound-62211-2.rs:21:18 | LL | trait UncheckedCopy: Sized { - | -------------------------- required by `UncheckedCopy` + | --------------------------- help: consider further restricting `Self`: `+ std::marker::Copy` + | | + | required by `UncheckedCopy` ... LL | type Output: Copy | ^^^^ the trait `std::marker::Copy` is not implemented for `Self` @@ -11,7 +13,9 @@ error[E0277]: cannot add-assign `&'static str` to `Self` --> $DIR/defaults-unsound-62211-2.rs:25:7 | LL | trait UncheckedCopy: Sized { - | -------------------------- required by `UncheckedCopy` + | --------------------------- help: consider further restricting `Self`: `+ std::ops::AddAssign<&'static str>` + | | + | required by `UncheckedCopy` ... LL | + AddAssign<&'static str> | ^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `Self += &'static str` @@ -22,7 +26,9 @@ error[E0277]: the trait bound `Self: std::ops::Deref` is not satisfied --> $DIR/defaults-unsound-62211-2.rs:23:7 | LL | trait UncheckedCopy: Sized { - | -------------------------- required by `UncheckedCopy` + | --------------------------- help: consider further restricting `Self`: `+ std::ops::Deref` + | | + | required by `UncheckedCopy` ... LL | + Deref | ^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `Self` @@ -31,7 +37,9 @@ error[E0277]: `Self` doesn't implement `std::fmt::Display` --> $DIR/defaults-unsound-62211-2.rs:28:7 | LL | trait UncheckedCopy: Sized { - | -------------------------- required by `UncheckedCopy` + | --------------------------- help: consider further restricting `Self`: `+ std::fmt::Display` + | | + | required by `UncheckedCopy` ... LL | + Display = Self; | ^^^^^^^ `Self` cannot be formatted with the default formatter diff --git a/src/test/ui/associated-types/issue-63593.stderr b/src/test/ui/associated-types/issue-63593.stderr index c27800f5a3fb1..42529fd2b220e 100644 --- a/src/test/ui/associated-types/issue-63593.stderr +++ b/src/test/ui/associated-types/issue-63593.stderr @@ -2,7 +2,9 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation --> $DIR/issue-63593.rs:9:5 | LL | trait MyTrait { - | ------------- required by `MyTrait` + | -------------- help: consider further restricting `Self`: `: std::marker::Sized` + | | + | required by `MyTrait` LL | type This = Self; | ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | diff --git a/src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.rs b/src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.rs new file mode 100644 index 0000000000000..0474bf0a33944 --- /dev/null +++ b/src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.rs @@ -0,0 +1,11 @@ +use std::ops::{Add, Sub, Mul, Div}; + +trait ArithmeticOps: Add + Sub + Mul + Div {} +//~^ ERROR the size for values of type `Self` cannot be known at compilation time + +impl ArithmeticOps for T where T: Add + Sub + Mul + Div { + // Nothing to implement, since T already supports the other traits. + // It has the functions it needs already +} + +fn main() {} diff --git a/src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.stderr b/src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.stderr new file mode 100644 index 0000000000000..707bcf5e2feb7 --- /dev/null +++ b/src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.stderr @@ -0,0 +1,17 @@ +error[E0277]: the size for values of type `Self` cannot be known at compilation time + --> $DIR/trait-with-supertraits-needing-sized-self.rs:3:22 + | +LL | trait ArithmeticOps: Add + Sub + Mul + Div {} + | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - help: consider further restricting `Self`: `+ std::marker::Sized` + | + ::: $SRC_DIR/libcore/ops/arith.rs:LL:COL + | +LL | pub trait Add { + | --- required by this bound in `std::ops::Add` + | + = help: the trait `std::marker::Sized` is not implemented for `Self` + = note: to learn more, visit + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From 45738e8cd1b026836f6cf161843971459bc1334e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 22 Apr 2020 16:31:58 -0700 Subject: [PATCH 2/4] Increase verbosity of bound restriction suggestions - Make the bound restriction suggestion `span_suggestion_verbose`. - Fix whitespace typo. --- .../traits/error_reporting/suggestions.rs | 12 ++++--- .../bad-bounds-on-assoc-in-trait.stderr | 24 ++++++++----- .../associated-types-bound-failure.fixed | 2 +- .../associated-types-bound-failure.stderr | 8 +++-- .../associated-types-for-unimpl-trait.fixed | 2 +- .../associated-types-for-unimpl-trait.stderr | 10 +++--- ...ated-types-no-suitable-supertrait-2.stderr | 10 +++--- ...ciated-types-no-suitable-supertrait.stderr | 10 +++--- ...ated-trait-in-method-without-default.fixed | 2 +- ...ted-trait-in-method-without-default.stderr | 10 +++--- .../associated-types-unsized.fixed | 2 +- .../associated-types-unsized.stderr | 6 ++-- .../defaults-suitability.stderr | 16 +++++---- .../defaults-unsound-62211-1.stderr | 34 ++++++++++++------- .../defaults-unsound-62211-2.stderr | 34 ++++++++++++------- .../ui/associated-types/issue-63593.stderr | 8 +++-- ...with-supertraits-needing-sized-self.stderr | 6 +++- src/test/ui/issues/issue-22872.stderr | 6 ++-- src/test/ui/issues/issue-27078.stderr | 8 +++-- src/test/ui/issues/issue-42312.stderr | 8 +++-- .../impl-trait-with-missing-bounds.stderr | 10 +++--- ...issing-assoc-type-bound-restriction.stderr | 24 ++++++++----- .../type-params-in-different-spaces-2.stderr | 14 +++++--- ...typeck-default-trait-impl-assoc-type.fixed | 2 +- ...ypeck-default-trait-impl-assoc-type.stderr | 6 ++-- .../wf/wf-trait-associated-type-trait.stderr | 10 +++--- src/test/ui/wf/wf-trait-default-fn-arg.stderr | 9 +++-- src/test/ui/wf/wf-trait-default-fn-ret.stderr | 9 +++-- .../wf-trait-default-fn-where-clause.stderr | 9 +++-- src/test/ui/wf/wf-trait-fn-arg.stderr | 9 +++-- src/test/ui/wf/wf-trait-fn-ret.stderr | 9 +++-- .../ui/wf/wf-trait-fn-where-clause.stderr | 9 +++-- 32 files changed, 215 insertions(+), 123 deletions(-) diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs index 5abae7ed68b99..c9eb2ee6c5a33 100644 --- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs +++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs @@ -156,7 +156,7 @@ fn predicate_constraint(generics: &hir::Generics<'_>, pred: String) -> (Span, St ( generics.where_clause.span_for_predicates_or_empty_place().shrink_to_hi(), format!( - "{} {} ", + "{} {}", if !generics.where_clause.predicates.is_empty() { "," } else { " where" }, pred, ), @@ -263,7 +263,7 @@ fn suggest_restriction( ); } else { // Trivial case: `T` needs an extra bound: `T: Bound`. - let (sp, sugg) = match super_traits { + let (sp, suggestion) = match super_traits { None => { predicate_constraint(generics, trait_ref.without_const().to_predicate().to_string()) } @@ -279,8 +279,12 @@ fn suggest_restriction( }, }; - let appl = Applicability::MachineApplicable; - err.span_suggestion(sp, &format!("consider further restricting {}", msg), sugg, appl); + err.span_suggestion_verbose( + sp, + &format!("consider further restricting {}", msg), + suggestion, + Applicability::MachineApplicable, + ); } } diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr index f65ae32c01c99..cbacc3610dcf7 100644 --- a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr +++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr @@ -16,11 +16,13 @@ error[E0277]: `<::C as std::iter::Iterator>::Item` is not an iterato --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:20 | LL | fn assume_case1() { - | ^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::iter::Iterator` - | | - | `<::C as std::iter::Iterator>::Item` is not an iterator + | ^^^^^ `<::C as std::iter::Iterator>::Item` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `<::C as std::iter::Iterator>::Item` +help: consider further restricting the associated type + | +LL | fn assume_case1() where <::C as std::iter::Iterator>::Item: std::iter::Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:20 @@ -32,11 +34,13 @@ LL | Send + Iterator() { - | ^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::marker::Send` - | | - | `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely + | ^^^^^ `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely | = help: the trait `std::marker::Send` is not implemented for `<::C as std::iter::Iterator>::Item` +help: consider further restricting the associated type + | +LL | fn assume_case1() where <::C as std::iter::Iterator>::Item: std::marker::Send { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:20 @@ -48,11 +52,13 @@ LL | > + Sync>; | ---- required by this bound in `Case1` ... LL | fn assume_case1() { - | ^^^^^ - help: consider further restricting the associated type: `where <::C as std::iter::Iterator>::Item: std::marker::Sync` - | | - | `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely + | ^^^^^ `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely | = help: the trait `std::marker::Sync` is not implemented for `<::C as std::iter::Iterator>::Item` +help: consider further restricting the associated type + | +LL | fn assume_case1() where <::C as std::iter::Iterator>::Item: std::marker::Sync { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: `<_ as Lam<&'a u8>>::App` doesn't implement `std::fmt::Debug` --> $DIR/bad-bounds-on-assoc-in-trait.rs:36:20 diff --git a/src/test/ui/associated-types/associated-types-bound-failure.fixed b/src/test/ui/associated-types/associated-types-bound-failure.fixed index cc47f31d00456..68ee38d16b3f3 100644 --- a/src/test/ui/associated-types/associated-types-bound-failure.fixed +++ b/src/test/ui/associated-types/associated-types-bound-failure.fixed @@ -14,7 +14,7 @@ pub trait GetToInt } fn foo(g: G) -> isize - where G : GetToInt, ::R: ToInt + where G : GetToInt, ::R: ToInt { ToInt::to_int(&g.get()) //~ ERROR E0277 } diff --git a/src/test/ui/associated-types/associated-types-bound-failure.stderr b/src/test/ui/associated-types/associated-types-bound-failure.stderr index c420c86a2758f..ab8909d1092ba 100644 --- a/src/test/ui/associated-types/associated-types-bound-failure.stderr +++ b/src/test/ui/associated-types/associated-types-bound-failure.stderr @@ -4,11 +4,13 @@ error[E0277]: the trait bound `::R: ToInt` is not satisfied LL | fn to_int(&self) -> isize; | -------------------------- required by `ToInt::to_int` ... -LL | where G : GetToInt - | - help: consider further restricting the associated type: `, ::R: ToInt` -LL | { LL | ToInt::to_int(&g.get()) | ^^^^^^^^ the trait `ToInt` is not implemented for `::R` + | +help: consider further restricting the associated type + | +LL | where G : GetToInt, ::R: ToInt + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/associated-types/associated-types-for-unimpl-trait.fixed b/src/test/ui/associated-types/associated-types-for-unimpl-trait.fixed index aa23326506f63..80bbef17469db 100644 --- a/src/test/ui/associated-types/associated-types-for-unimpl-trait.fixed +++ b/src/test/ui/associated-types/associated-types-for-unimpl-trait.fixed @@ -7,7 +7,7 @@ trait Get { } trait Other { - fn uhoh(&self, foo: U, bar: ::Value) where Self: Get {} + fn uhoh(&self, foo: U, bar: ::Value) where Self: Get {} //~^ ERROR the trait bound `Self: Get` is not satisfied } diff --git a/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr b/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr index 83d5390417e77..6d7289bd0712b 100644 --- a/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr +++ b/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr @@ -2,10 +2,12 @@ error[E0277]: the trait bound `Self: Get` is not satisfied --> $DIR/associated-types-for-unimpl-trait.rs:10:5 | LL | fn uhoh(&self, foo: U, bar: ::Value) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^ - | | | - | | help: consider further restricting `Self`: `where Self: Get` - | the trait `Get` is not implemented for `Self` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn uhoh(&self, foo: U, bar: ::Value) where Self: Get {} + | ^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr b/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr index 6aa0403088d3c..dfe62aa5d6b00 100644 --- a/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr +++ b/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr @@ -2,10 +2,12 @@ error[E0277]: the trait bound `Self: Get` is not satisfied --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:5 | LL | fn uhoh(&self, foo: U, bar: ::Value) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^ - | | | - | | help: consider further restricting `Self`: `where Self: Get` - | the trait `Get` is not implemented for `Self` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn uhoh(&self, foo: U, bar: ::Value) where Self: Get {} + | ^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr index 8c242be979611..f0f2451a1ecea 100644 --- a/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr +++ b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr @@ -2,10 +2,12 @@ error[E0277]: the trait bound `Self: Get` is not satisfied --> $DIR/associated-types-no-suitable-supertrait.rs:17:5 | LL | fn uhoh(&self, foo: U, bar: ::Value) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^ - | | | - | | help: consider further restricting `Self`: `where Self: Get` - | the trait `Get` is not implemented for `Self` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn uhoh(&self, foo: U, bar: ::Value) where Self: Get {} + | ^^^^^^^^^^^^^^^ error[E0277]: the trait bound `(T, U): Get` is not satisfied --> $DIR/associated-types-no-suitable-supertrait.rs:22:5 diff --git a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.fixed b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.fixed index f357045a456e6..9bc308465ebdd 100644 --- a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.fixed +++ b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.fixed @@ -7,7 +7,7 @@ trait Get { } trait Other { - fn okay(&self, foo: U, bar: ::Value) where Self: Get ; + fn okay(&self, foo: U, bar: ::Value) where Self: Get; //~^ ERROR E0277 } diff --git a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr index cb01488fa34d4..4528f03c54a63 100644 --- a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr +++ b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr @@ -2,10 +2,12 @@ error[E0277]: the trait bound `Self: Get` is not satisfied --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:5 | LL | fn okay(&self, foo: U, bar: ::Value); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- - | | | - | | help: consider further restricting `Self`: `where Self: Get` - | the trait `Get` is not implemented for `Self` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn okay(&self, foo: U, bar: ::Value) where Self: Get; + | ^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/associated-types/associated-types-unsized.fixed b/src/test/ui/associated-types/associated-types-unsized.fixed index f780d171fee8e..9837796e308de 100644 --- a/src/test/ui/associated-types/associated-types-unsized.fixed +++ b/src/test/ui/associated-types/associated-types-unsized.fixed @@ -6,7 +6,7 @@ trait Get { fn get(&self) -> ::Value; } -fn foo(t: T) where ::Value: std::marker::Sized { +fn foo(t: T) where ::Value: std::marker::Sized { let x = t.get(); //~ ERROR the size for values of type } diff --git a/src/test/ui/associated-types/associated-types-unsized.stderr b/src/test/ui/associated-types/associated-types-unsized.stderr index 2352ac4ad3822..6daba54ac6969 100644 --- a/src/test/ui/associated-types/associated-types-unsized.stderr +++ b/src/test/ui/associated-types/associated-types-unsized.stderr @@ -1,8 +1,6 @@ error[E0277]: the size for values of type `::Value` cannot be known at compilation time --> $DIR/associated-types-unsized.rs:10:9 | -LL | fn foo(t: T) { - | - help: consider further restricting the associated type: `where ::Value: std::marker::Sized` LL | let x = t.get(); | ^ doesn't have a size known at compile-time | @@ -10,6 +8,10 @@ LL | let x = t.get(); = note: to learn more, visit = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature +help: consider further restricting the associated type + | +LL | fn foo(t: T) where ::Value: std::marker::Sized { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/associated-types/defaults-suitability.stderr b/src/test/ui/associated-types/defaults-suitability.stderr index 3f6702da2a4a2..8676c1fa22319 100644 --- a/src/test/ui/associated-types/defaults-suitability.stderr +++ b/src/test/ui/associated-types/defaults-suitability.stderr @@ -85,25 +85,29 @@ error[E0277]: the trait bound `>::Baz: std::clone::Clone` is not --> $DIR/defaults-suitability.rs:72:15 | LL | trait Foo2 { - | -------------- help: consider further restricting the associated type: `where >::Baz: std::clone::Clone` - | | - | required by `Foo2` + | ------------- required by `Foo2` LL | type Bar: Clone = Vec; | ^^^^^ the trait `std::clone::Clone` is not implemented for `>::Baz` | = note: required because of the requirements on the impl of `std::clone::Clone` for `std::vec::Vec<>::Baz>` +help: consider further restricting the associated type + | +LL | trait Foo2 where >::Baz: std::clone::Clone { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `>::Baz: std::clone::Clone` is not satisfied --> $DIR/defaults-suitability.rs:81:15 | LL | trait Foo25 { - | ---------------------- help: consider further restricting the associated type: `where >::Baz: std::clone::Clone` - | | - | required by `Foo25` + | --------------------- required by `Foo25` LL | type Bar: Clone = Vec; | ^^^^^ the trait `std::clone::Clone` is not implemented for `>::Baz` | = note: required because of the requirements on the impl of `std::clone::Clone` for `std::vec::Vec<>::Baz>` +help: consider further restricting the associated type + | +LL | trait Foo25 where >::Baz: std::clone::Clone { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `T: std::clone::Clone` is not satisfied --> $DIR/defaults-suitability.rs:90:16 diff --git a/src/test/ui/associated-types/defaults-unsound-62211-1.stderr b/src/test/ui/associated-types/defaults-unsound-62211-1.stderr index c804bc3d833fa..69c310766c1cc 100644 --- a/src/test/ui/associated-types/defaults-unsound-62211-1.stderr +++ b/src/test/ui/associated-types/defaults-unsound-62211-1.stderr @@ -2,50 +2,60 @@ error[E0277]: the trait bound `Self: std::marker::Copy` is not satisfied --> $DIR/defaults-unsound-62211-1.rs:21:18 | LL | trait UncheckedCopy: Sized { - | --------------------------- help: consider further restricting `Self`: `+ std::marker::Copy` - | | - | required by `UncheckedCopy` + | -------------------------- required by `UncheckedCopy` ... LL | type Output: Copy | ^^^^ the trait `std::marker::Copy` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | trait UncheckedCopy: Sized + std::marker::Copy { + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: cannot add-assign `&'static str` to `Self` --> $DIR/defaults-unsound-62211-1.rs:25:7 | LL | trait UncheckedCopy: Sized { - | --------------------------- help: consider further restricting `Self`: `+ std::ops::AddAssign<&'static str>` - | | - | required by `UncheckedCopy` + | -------------------------- required by `UncheckedCopy` ... LL | + AddAssign<&'static str> | ^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `Self += &'static str` | = help: the trait `std::ops::AddAssign<&'static str>` is not implemented for `Self` +help: consider further restricting `Self` + | +LL | trait UncheckedCopy: Sized + std::ops::AddAssign<&'static str> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `Self: std::ops::Deref` is not satisfied --> $DIR/defaults-unsound-62211-1.rs:23:7 | LL | trait UncheckedCopy: Sized { - | --------------------------- help: consider further restricting `Self`: `+ std::ops::Deref` - | | - | required by `UncheckedCopy` + | -------------------------- required by `UncheckedCopy` ... LL | + Deref | ^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | trait UncheckedCopy: Sized + std::ops::Deref { + | ^^^^^^^^^^^^^^^^^ error[E0277]: `Self` doesn't implement `std::fmt::Display` --> $DIR/defaults-unsound-62211-1.rs:28:7 | LL | trait UncheckedCopy: Sized { - | --------------------------- help: consider further restricting `Self`: `+ std::fmt::Display` - | | - | required by `UncheckedCopy` + | -------------------------- required by `UncheckedCopy` ... LL | + Display = Self; | ^^^^^^^ `Self` cannot be formatted with the default formatter | = help: the trait `std::fmt::Display` is not implemented for `Self` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +help: consider further restricting `Self` + | +LL | trait UncheckedCopy: Sized + std::fmt::Display { + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: `T` doesn't implement `std::fmt::Display` --> $DIR/defaults-unsound-62211-1.rs:41:9 diff --git a/src/test/ui/associated-types/defaults-unsound-62211-2.stderr b/src/test/ui/associated-types/defaults-unsound-62211-2.stderr index aee5e4b28ca6d..84f0ba7529ea2 100644 --- a/src/test/ui/associated-types/defaults-unsound-62211-2.stderr +++ b/src/test/ui/associated-types/defaults-unsound-62211-2.stderr @@ -2,50 +2,60 @@ error[E0277]: the trait bound `Self: std::marker::Copy` is not satisfied --> $DIR/defaults-unsound-62211-2.rs:21:18 | LL | trait UncheckedCopy: Sized { - | --------------------------- help: consider further restricting `Self`: `+ std::marker::Copy` - | | - | required by `UncheckedCopy` + | -------------------------- required by `UncheckedCopy` ... LL | type Output: Copy | ^^^^ the trait `std::marker::Copy` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | trait UncheckedCopy: Sized + std::marker::Copy { + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: cannot add-assign `&'static str` to `Self` --> $DIR/defaults-unsound-62211-2.rs:25:7 | LL | trait UncheckedCopy: Sized { - | --------------------------- help: consider further restricting `Self`: `+ std::ops::AddAssign<&'static str>` - | | - | required by `UncheckedCopy` + | -------------------------- required by `UncheckedCopy` ... LL | + AddAssign<&'static str> | ^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `Self += &'static str` | = help: the trait `std::ops::AddAssign<&'static str>` is not implemented for `Self` +help: consider further restricting `Self` + | +LL | trait UncheckedCopy: Sized + std::ops::AddAssign<&'static str> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `Self: std::ops::Deref` is not satisfied --> $DIR/defaults-unsound-62211-2.rs:23:7 | LL | trait UncheckedCopy: Sized { - | --------------------------- help: consider further restricting `Self`: `+ std::ops::Deref` - | | - | required by `UncheckedCopy` + | -------------------------- required by `UncheckedCopy` ... LL | + Deref | ^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | trait UncheckedCopy: Sized + std::ops::Deref { + | ^^^^^^^^^^^^^^^^^ error[E0277]: `Self` doesn't implement `std::fmt::Display` --> $DIR/defaults-unsound-62211-2.rs:28:7 | LL | trait UncheckedCopy: Sized { - | --------------------------- help: consider further restricting `Self`: `+ std::fmt::Display` - | | - | required by `UncheckedCopy` + | -------------------------- required by `UncheckedCopy` ... LL | + Display = Self; | ^^^^^^^ `Self` cannot be formatted with the default formatter | = help: the trait `std::fmt::Display` is not implemented for `Self` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +help: consider further restricting `Self` + | +LL | trait UncheckedCopy: Sized + std::fmt::Display { + | ^^^^^^^^^^^^^^^^^^^ error[E0277]: `T` doesn't implement `std::fmt::Display` --> $DIR/defaults-unsound-62211-2.rs:41:9 diff --git a/src/test/ui/associated-types/issue-63593.stderr b/src/test/ui/associated-types/issue-63593.stderr index 42529fd2b220e..82e76ff0b7cb5 100644 --- a/src/test/ui/associated-types/issue-63593.stderr +++ b/src/test/ui/associated-types/issue-63593.stderr @@ -2,14 +2,16 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation --> $DIR/issue-63593.rs:9:5 | LL | trait MyTrait { - | -------------- help: consider further restricting `Self`: `: std::marker::Sized` - | | - | required by `MyTrait` + | ------------- required by `MyTrait` LL | type This = Self; | ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `Self` = note: to learn more, visit +help: consider further restricting `Self` + | +LL | trait MyTrait: std::marker::Sized { + | ^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.stderr b/src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.stderr index 707bcf5e2feb7..a37573dffff44 100644 --- a/src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.stderr +++ b/src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.stderr @@ -2,7 +2,7 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation --> $DIR/trait-with-supertraits-needing-sized-self.rs:3:22 | LL | trait ArithmeticOps: Add + Sub + Mul + Div {} - | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - help: consider further restricting `Self`: `+ std::marker::Sized` + | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | ::: $SRC_DIR/libcore/ops/arith.rs:LL:COL | @@ -11,6 +11,10 @@ LL | pub trait Add { | = help: the trait `std::marker::Sized` is not implemented for `Self` = note: to learn more, visit +help: consider further restricting `Self` + | +LL | trait ArithmeticOps: Add + Sub + Mul + Div + std::marker::Sized {} + | ^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-22872.stderr b/src/test/ui/issues/issue-22872.stderr index 283a5e04a8b6f..038490bbd7c7b 100644 --- a/src/test/ui/issues/issue-22872.stderr +++ b/src/test/ui/issues/issue-22872.stderr @@ -1,14 +1,16 @@ error[E0277]: `

>::Item` is not an iterator --> $DIR/issue-22872.rs:20:40 | -LL | fn push_process

(process: P) where P: Process<'static> { - | - help: consider further restricting the associated type: `,

>::Item: std::iter::Iterator` LL | let _: Box Wrap<'b>> = Box::new(Wrapper(process)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `

>::Item` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `

>::Item` = note: required because of the requirements on the impl of `for<'b> Wrap<'b>` for `Wrapper

` = note: required for the cast to the object type `dyn for<'b> Wrap<'b>` +help: consider further restricting the associated type + | +LL | fn push_process

(process: P) where P: Process<'static>,

>::Item: std::iter::Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-27078.stderr b/src/test/ui/issues/issue-27078.stderr index fbc72d063f37c..3eb9d3c62039f 100644 --- a/src/test/ui/issues/issue-27078.stderr +++ b/src/test/ui/issues/issue-27078.stderr @@ -2,14 +2,16 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation --> $DIR/issue-27078.rs:5:12 | LL | fn foo(self) -> &'static i32 { - | ^^^^ - help: consider further restricting `Self`: `where Self: std::marker::Sized` - | | - | doesn't have a size known at compile-time + | ^^^^ doesn't have a size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `Self` = note: to learn more, visit = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature +help: consider further restricting `Self` + | +LL | fn foo(self) -> &'static i32 where Self: std::marker::Sized { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-42312.stderr b/src/test/ui/issues/issue-42312.stderr index 915bfffd6d592..0d4797a7a0673 100644 --- a/src/test/ui/issues/issue-42312.stderr +++ b/src/test/ui/issues/issue-42312.stderr @@ -2,14 +2,16 @@ error[E0277]: the size for values of type `::Target` ca --> $DIR/issue-42312.rs:4:12 | LL | fn baz(_: Self::Target) where Self: Deref {} - | ^ - help: consider further restricting the associated type: `, ::Target: std::marker::Sized` - | | - | doesn't have a size known at compile-time + | ^ doesn't have a size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `::Target` = note: to learn more, visit = note: all function arguments must have a statically known size = help: unsized locals are gated as an unstable feature +help: consider further restricting the associated type + | +LL | fn baz(_: Self::Target) where Self: Deref, ::Target: std::marker::Sized {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the size for values of type `(dyn std::string::ToString + 'static)` cannot be known at compilation time --> $DIR/issue-42312.rs:8:10 diff --git a/src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr b/src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr index 6fc629b33a21e..fb0914a8743e8 100644 --- a/src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr +++ b/src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr @@ -10,7 +10,7 @@ LL | fn qux(_: impl std::fmt::Debug) {} = help: the trait `std::fmt::Debug` is not implemented for `::Item` help: introduce a type parameter with a trait bound instead of using `impl Trait` | -LL | fn foo(constraints: I) where ::Item: std::fmt::Debug { +LL | fn foo(constraints: I) where ::Item: std::fmt::Debug { | ^^^^^^^^^^^^^ ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: `::Item` doesn't implement `std::fmt::Debug` @@ -25,7 +25,7 @@ LL | fn qux(_: impl std::fmt::Debug) {} = help: the trait `std::fmt::Debug` is not implemented for `::Item` help: introduce a type parameter with a trait bound instead of using `impl Trait` | -LL | fn bar(t: T, constraints: I) where T: std::fmt::Debug, ::Item: std::fmt::Debug { +LL | fn bar(t: T, constraints: I) where T: std::fmt::Debug, ::Item: std::fmt::Debug { | ^^^^^^^^^^^^^ ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: `::Item` doesn't implement `std::fmt::Debug` @@ -40,7 +40,7 @@ LL | fn qux(_: impl std::fmt::Debug) {} = help: the trait `std::fmt::Debug` is not implemented for `::Item` help: introduce a type parameter with a trait bound instead of using `impl Trait` | -LL | fn baz(t: impl std::fmt::Debug, constraints: I) where ::Item: std::fmt::Debug { +LL | fn baz(t: impl std::fmt::Debug, constraints: I) where ::Item: std::fmt::Debug { | ^^^^^^^^^^^^^ ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: `::Item` doesn't implement `std::fmt::Debug` @@ -55,7 +55,7 @@ LL | fn qux(_: impl std::fmt::Debug) {} = help: the trait `std::fmt::Debug` is not implemented for `::Item` help: introduce a type parameter with a trait bound instead of using `impl Trait` | -LL | fn bat(t: T, constraints: U, _: I) where ::Item: std::fmt::Debug { +LL | fn bat(t: T, constraints: U, _: I) where ::Item: std::fmt::Debug { | ^^^^^^^^^^^^^ ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: `::Item` doesn't implement `std::fmt::Debug` @@ -70,7 +70,7 @@ LL | fn qux(_: impl std::fmt::Debug) {} = help: the trait `std::fmt::Debug` is not implemented for `::Item` help: introduce a type parameter with a trait bound instead of using `impl Trait` | -LL | fn bak(constraints: I) where ::Item: std::fmt::Debug { +LL | fn bak(constraints: I) where ::Item: std::fmt::Debug { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 5 previous errors diff --git a/src/test/ui/suggestions/missing-assoc-type-bound-restriction.stderr b/src/test/ui/suggestions/missing-assoc-type-bound-restriction.stderr index ef484e94729e8..a8ea214796183 100644 --- a/src/test/ui/suggestions/missing-assoc-type-bound-restriction.stderr +++ b/src/test/ui/suggestions/missing-assoc-type-bound-restriction.stderr @@ -8,9 +8,12 @@ LL | type Assoc: Child; | --------------- required by this bound in `Parent` ... LL | impl> Parent for ParentWrapper { - | ^^^^^^ - help: consider further restricting the associated type: `where ::Assoc: Child` - | | - | the trait `Child` is not implemented for `::Assoc` + | ^^^^^^ the trait `Child` is not implemented for `::Assoc` + | +help: consider further restricting the associated type + | +LL | impl> Parent for ParentWrapper where ::Assoc: Child { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `::Assoc: Child` is not satisfied --> $DIR/missing-assoc-type-bound-restriction.rs:20:18 @@ -21,13 +24,14 @@ LL | type Ty; LL | type Assoc: Child; | --------------- required by this bound in `Parent` ... -LL | impl> Parent for ParentWrapper { - | - help: consider further restricting the associated type: `where ::Assoc: Child` -... LL | type Assoc = ChildWrapper; | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Child` is not implemented for `::Assoc` | = note: required because of the requirements on the impl of `Child` for `ChildWrapper<::Assoc>` +help: consider further restricting the associated type + | +LL | impl> Parent for ParentWrapper where ::Assoc: Child { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `::Assoc: Child` is not satisfied --> $DIR/missing-assoc-type-bound-restriction.rs:20:5 @@ -38,11 +42,13 @@ LL | type Ty; LL | type Assoc: Child; | --------------- required by this bound in `Parent` ... -LL | impl> Parent for ParentWrapper { - | - help: consider further restricting the associated type: `where ::Assoc: Child` -... LL | type Assoc = ChildWrapper; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Child` is not implemented for `::Assoc` + | +help: consider further restricting the associated type + | +LL | impl> Parent for ParentWrapper where ::Assoc: Child { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/type/type-params-in-different-spaces-2.stderr b/src/test/ui/type/type-params-in-different-spaces-2.stderr index 7ce249a60b85e..e0039f2a31602 100644 --- a/src/test/ui/type/type-params-in-different-spaces-2.stderr +++ b/src/test/ui/type/type-params-in-different-spaces-2.stderr @@ -4,10 +4,13 @@ error[E0277]: the trait bound `Self: Tr` is not satisfied LL | fn op(_: T) -> Self; | -------------------- required by `Tr::op` ... -LL | fn test(u: U) -> Self { - | - help: consider further restricting `Self`: `where Self: Tr` LL | Tr::op(u) | ^^^^^^ the trait `Tr` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn test(u: U) -> Self where Self: Tr { + | ^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `Self: Tr` is not satisfied --> $DIR/type-params-in-different-spaces-2.rs:16:9 @@ -15,10 +18,13 @@ error[E0277]: the trait bound `Self: Tr` is not satisfied LL | fn op(_: T) -> Self; | -------------------- required by `Tr::op` ... -LL | fn test(u: U) -> Self { - | - help: consider further restricting `Self`: `where Self: Tr` LL | Tr::op(u) | ^^^^^^ the trait `Tr` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn test(u: U) -> Self where Self: Tr { + | ^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.fixed b/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.fixed index 7a108d880bed3..dd1195b99f694 100644 --- a/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.fixed +++ b/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.fixed @@ -7,7 +7,7 @@ trait Trait { type AssocType; fn dummy(&self) { } } -fn bar() where ::AssocType: std::marker::Send { +fn bar() where ::AssocType: std::marker::Send { is_send::(); //~ ERROR E0277 } diff --git a/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.stderr b/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.stderr index e64acfc54ff2a..f97d41637ba04 100644 --- a/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.stderr +++ b/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.stderr @@ -1,8 +1,6 @@ error[E0277]: `::AssocType` cannot be sent between threads safely --> $DIR/typeck-default-trait-impl-assoc-type.rs:11:5 | -LL | fn bar() { - | - help: consider further restricting the associated type: `where ::AssocType: std::marker::Send` LL | is_send::(); | ^^^^^^^^^^^^^^^^^^^^^^^ `::AssocType` cannot be sent between threads safely ... @@ -10,6 +8,10 @@ LL | fn is_send() { | ---- required by this bound in `is_send` | = help: the trait `std::marker::Send` is not implemented for `::AssocType` +help: consider further restricting the associated type + | +LL | fn bar() where ::AssocType: std::marker::Send { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-associated-type-trait.stderr b/src/test/ui/wf/wf-trait-associated-type-trait.stderr index 70cf88f262fdc..e2892e3d24888 100644 --- a/src/test/ui/wf/wf-trait-associated-type-trait.stderr +++ b/src/test/ui/wf/wf-trait-associated-type-trait.stderr @@ -3,12 +3,14 @@ error[E0277]: the trait bound `::Type1: std::marker::Copy` is | LL | struct IsCopy { x: T } | ---- required by this bound in `IsCopy` -LL | -LL | trait SomeTrait { - | - help: consider further restricting the associated type: `where ::Type1: std::marker::Copy` -LL | type Type1; +... LL | type Type2 = IsCopy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `::Type1` + | +help: consider further restricting the associated type + | +LL | trait SomeTrait where ::Type1: std::marker::Copy { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-default-fn-arg.stderr b/src/test/ui/wf/wf-trait-default-fn-arg.stderr index ed563af592816..23d886e25ff15 100644 --- a/src/test/ui/wf/wf-trait-default-fn-arg.stderr +++ b/src/test/ui/wf/wf-trait-default-fn-arg.stderr @@ -5,9 +5,12 @@ LL | struct Bar { value: Box } | -- required by this bound in `Bar` ... LL | fn bar(&self, x: &Bar) { - | ^^^^^^^^^^ - help: consider further restricting `Self`: `where Self: std::cmp::Eq` - | | - | the trait `std::cmp::Eq` is not implemented for `Self` + | ^^^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn bar(&self, x: &Bar) where Self: std::cmp::Eq { + | ^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-default-fn-ret.stderr b/src/test/ui/wf/wf-trait-default-fn-ret.stderr index 57cf1e9e6dae3..0214064017204 100644 --- a/src/test/ui/wf/wf-trait-default-fn-ret.stderr +++ b/src/test/ui/wf/wf-trait-default-fn-ret.stderr @@ -5,9 +5,12 @@ LL | struct Bar { value: Box } | -- required by this bound in `Bar` ... LL | fn bar(&self) -> Bar { - | ^^^^^^^^^- help: consider further restricting `Self`: `where Self: std::cmp::Eq` - | | - | the trait `std::cmp::Eq` is not implemented for `Self` + | ^^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn bar(&self) -> Bar where Self: std::cmp::Eq { + | ^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr b/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr index 534bf4d344836..3664c8b25aaef 100644 --- a/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr @@ -5,9 +5,12 @@ LL | trait Bar { } | -- required by this bound in `Bar` ... LL | fn bar(&self) where A: Bar { - | ^^^^^^^^^- help: consider further restricting `Self`: `, Self: std::cmp::Eq` - | | - | the trait `std::cmp::Eq` is not implemented for `Self` + | ^^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn bar(&self) where A: Bar, Self: std::cmp::Eq { + | ^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-fn-arg.stderr b/src/test/ui/wf/wf-trait-fn-arg.stderr index 494619a2f291e..b5f5f70ce8176 100644 --- a/src/test/ui/wf/wf-trait-fn-arg.stderr +++ b/src/test/ui/wf/wf-trait-fn-arg.stderr @@ -5,9 +5,12 @@ LL | struct Bar { value: Box } | -- required by this bound in `Bar` ... LL | fn bar(&self, x: &Bar); - | ^^^^^^^^^^ - help: consider further restricting `Self`: `where Self: std::cmp::Eq` - | | - | the trait `std::cmp::Eq` is not implemented for `Self` + | ^^^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn bar(&self, x: &Bar) where Self: std::cmp::Eq; + | ^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-fn-ret.stderr b/src/test/ui/wf/wf-trait-fn-ret.stderr index 6a3381d9a22f6..5e7d8cbfea610 100644 --- a/src/test/ui/wf/wf-trait-fn-ret.stderr +++ b/src/test/ui/wf/wf-trait-fn-ret.stderr @@ -5,9 +5,12 @@ LL | struct Bar { value: Box } | -- required by this bound in `Bar` ... LL | fn bar(&self) -> &Bar; - | ^^^^^^^^^^- help: consider further restricting `Self`: `where Self: std::cmp::Eq` - | | - | the trait `std::cmp::Eq` is not implemented for `Self` + | ^^^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn bar(&self) -> &Bar where Self: std::cmp::Eq; + | ^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-trait-fn-where-clause.stderr b/src/test/ui/wf/wf-trait-fn-where-clause.stderr index 2d6cf838f083e..2d9ba56c58548 100644 --- a/src/test/ui/wf/wf-trait-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-trait-fn-where-clause.stderr @@ -5,9 +5,12 @@ LL | struct Bar { value: Box } | -- required by this bound in `Bar` ... LL | fn bar(&self) where Self: Sized, Bar: Copy; - | ^^^^- help: consider further restricting `Self`: `, Self: std::cmp::Eq` - | | - | the trait `std::cmp::Eq` is not implemented for `Self` + | ^^^^ the trait `std::cmp::Eq` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn bar(&self) where Self: Sized, Bar: Copy, Self: std::cmp::Eq; + | ^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error From 4556130e7d9fdf03bedfa177a658808dbec16b8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 7 May 2020 12:54:05 -0700 Subject: [PATCH 3/4] fix test output after rebase --- src/test/ui/issues/issue-20005.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/issues/issue-20005.stderr b/src/test/ui/issues/issue-20005.stderr index f53489a99f3b4..775f9702401a6 100644 --- a/src/test/ui/issues/issue-20005.stderr +++ b/src/test/ui/issues/issue-20005.stderr @@ -11,7 +11,7 @@ LL | ) -> >::Result where Dst: From { = note: to learn more, visit help: consider further restricting `Self` | -LL | ) -> >::Result where Dst: From, Self: std::marker::Sized { +LL | ) -> >::Result where Dst: From, Self: std::marker::Sized { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider relaxing the implicit `Sized` restriction | From 58797b01f1b0925095986e4f42b839cdb2a99ac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 12 May 2020 11:56:11 -0700 Subject: [PATCH 4/4] review comments --- .../traits/error_reporting/suggestions.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs index c9eb2ee6c5a33..5c4ba40bf38e3 100644 --- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs +++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs @@ -175,6 +175,11 @@ fn suggest_restriction( trait_ref: ty::PolyTraitRef<'_>, super_traits: Option<(&Ident, &hir::GenericBounds<'_>)>, ) { + // When we are dealing with a trait, `super_traits` will be `Some`: + // Given `trait T: A + B + C {}` + // - ^^^^^^^^^ GenericBounds + // | + // &Ident let span = generics.where_clause.span_for_predicates_or_empty_place(); if span.from_expansion() || span.desugaring_kind().is_some() { return; @@ -311,7 +316,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ident, kind: hir::ItemKind::Trait(_, _, generics, bounds, _), .. - }) if param_ty && self_ty == self.tcx.types.self_param => { + }) if self_ty == self.tcx.types.self_param => { + assert!(param_ty); // Restricting `Self` for a single method. suggest_restriction( &generics, @@ -329,7 +335,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { generics, kind: hir::TraitItemKind::Fn(..), .. - }) if param_ty && self_ty == self.tcx.types.self_param => { + }) if self_ty == self.tcx.types.self_param => { + assert!(param_ty); // Restricting `Self` for a single method. suggest_restriction( &generics, "`Self`", err, None, projection, trait_ref, None,