diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index 0ea0f271fd60..0b627f9d15e0 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -1340,6 +1340,44 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { &obligation.cause.code, &mut vec![], ); + self.suggest_unsized_bound_if_applicable(err, obligation); + } + } + + fn suggest_unsized_bound_if_applicable( + &self, + err: &mut DiagnosticBuilder<'_>, + obligation: &PredicateObligation<'tcx>, + ) { + if let ( + ty::Predicate::Trait(pred, _), + ObligationCauseCode::BindingObligation(item_def_id, span), + ) = (&obligation.predicate, &obligation.cause.code) + { + if let (Some(generics), true) = ( + self.tcx.hir().get_if_local(*item_def_id).as_ref().and_then(|n| n.generics()), + Some(pred.def_id()) == self.tcx.lang_items().sized_trait(), + ) { + for param in generics.params { + if param.span == *span + && !param.bounds.iter().any(|bound| { + bound.trait_def_id() == self.tcx.lang_items().sized_trait() + }) + { + let (span, separator) = match param.bounds { + [] => (span.shrink_to_hi(), ":"), + [.., bound] => (bound.span().shrink_to_hi(), " + "), + }; + err.span_suggestion( + span, + "consider relaxing the implicit `Sized` restriction", + format!("{} ?Sized", separator), + Applicability::MachineApplicable, + ); + return; + } + } + } } } diff --git a/src/test/ui/extern/extern-types-unsized.stderr b/src/test/ui/extern/extern-types-unsized.stderr index 0417186eed34..0c9165fd9585 100644 --- a/src/test/ui/extern/extern-types-unsized.stderr +++ b/src/test/ui/extern/extern-types-unsized.stderr @@ -2,7 +2,9 @@ error[E0277]: the size for values of type `A` cannot be known at compilation tim --> $DIR/extern-types-unsized.rs:22:20 | LL | fn assert_sized() { } - | ------------ - required by this bound in `assert_sized` + | ------------ -- help: consider relaxing the implicit `Sized` restriction: `: ?Sized` + | | + | required by this bound in `assert_sized` ... LL | assert_sized::(); | ^ doesn't have a size known at compile-time diff --git a/src/test/ui/str/str-mut-idx.stderr b/src/test/ui/str/str-mut-idx.stderr index 3c957970e51c..a9ec6b9c02fe 100644 --- a/src/test/ui/str/str-mut-idx.stderr +++ b/src/test/ui/str/str-mut-idx.stderr @@ -2,7 +2,9 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t --> $DIR/str-mut-idx.rs:4:15 | LL | fn bot() -> T { loop {} } - | --- - required by this bound in `bot` + | --- -- help: consider relaxing the implicit `Sized` restriction: `: ?Sized` + | | + | required by this bound in `bot` ... LL | s[1..2] = bot(); | ^^^ doesn't have a size known at compile-time diff --git a/src/test/ui/unsized3.stderr b/src/test/ui/unsized3.stderr index 232296ad0912..0c37828229e3 100644 --- a/src/test/ui/unsized3.stderr +++ b/src/test/ui/unsized3.stderr @@ -1,8 +1,6 @@ error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized3.rs:7:13 | -LL | fn f1(x: &X) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` LL | f2::(x); | ^ doesn't have a size known at compile-time ... @@ -11,12 +9,18 @@ LL | fn f2(x: &X) { | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit +help: consider further restricting this bound + | +LL | fn f1(x: &X) { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: consider relaxing the implicit `Sized` restriction + | +LL | fn f2(x: &X) { + | ^^^^^^^^ error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized3.rs:18:13 | -LL | fn f3(x: &X) { - | -- help: consider further restricting this bound: `X: std::marker::Sized +` LL | f4::(x); | ^ doesn't have a size known at compile-time ... @@ -25,6 +29,14 @@ LL | fn f4(x: &X) { | = help: the trait `std::marker::Sized` is not implemented for `X` = note: to learn more, visit +help: consider further restricting this bound + | +LL | fn f3(x: &X) { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: consider relaxing the implicit `Sized` restriction + | +LL | fn f4(x: &X) { + | ^^^^^^^^^ error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized3.rs:33:8