diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 4944301990ecd..106248abc40ba 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1935,8 +1935,58 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ObligationCauseCode::ImplicitSizedObligation(item_def_id, span) => { let item_name = tcx.def_path_str(item_def_id); let mut sp: MultiSpan = span.into(); - sp.push_span_label(span, format!("required by this bound in `{}`", item_name)); - err.span_note(sp, "type parameters have an implicit `Sized` obligation"); + match self.tcx.hir().get_if_local(item_def_id) { + Some(hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Type(bounds, _), + ident, + .. + })) => { + sp.push_span_label( + span, + format!("required by associated type `{}`", item_name), + ); + err.span_note(sp, "associated types have an implicit `Sized` obligation"); + + let sized_trait = self.tcx.lang_items().sized_trait(); + if bounds.len() == 0 { + err.span_suggestion_verbose( + ident.span.shrink_to_hi(), + "consider relaxing the `Sized` obligation", + ": ?Sized".to_string(), + Applicability::MaybeIncorrect, + ); + } else if bounds.iter().all(|bound| { + bound.trait_ref().and_then(|tr| tr.trait_def_id()) != sized_trait + }) { + err.span_suggestion_verbose( + bounds.iter().last().unwrap().span().shrink_to_hi(), + "consider relaxing the `Sized` obligation", + " + ?Sized".to_string(), + Applicability::MaybeIncorrect, + ); + } + } + Some(hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::TyAlias(_), + .. + })) => { + let msg = "associated types on `impl` blocks for types, have an implicit \ + mandatory `Sized` obligation; associated types from `trait`s can be \ + relaxed to `?Sized`"; + sp.push_span_label( + span, + format!("required by associated type `{}`", item_name), + ); + err.span_note(sp, msg); + } + _ => { + sp.push_span_label( + span, + format!("required by this bound in `{}`", item_name), + ); + err.span_note(sp, "type parameters have an implicit `Sized` obligation"); + } + } } ObligationCauseCode::BindingObligation(item_def_id, span) => { let item_name = tcx.def_path_str(item_def_id); @@ -1953,7 +2003,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } } if span != DUMMY_SP { - err.span_label(span, &msg); + err.span_label(span, &msg); } else { err.note(&msg); } diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index 0d5b3ad8dbb3f..c63fe09ca66fc 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -1239,11 +1239,16 @@ pub fn check_type_bounds<'tcx>( let impl_ty_hir_id = tcx.hir().local_def_id_to_hir_id(impl_ty.def_id.expect_local()); let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_hir_id); - let mk_cause = |span| { + let mk_cause = |bound, span| { ObligationCause::new( impl_ty_span, impl_ty_hir_id, - ObligationCauseCode::BindingObligation(trait_ty.def_id, span), + match bound { + ty::PredicateKind::Trait(_, _, ty::ImplicitTraitPredicate::Yes) => { + traits::ImplicitSizedObligation(trait_ty.def_id, span) + } + _ => ObligationCauseCode::BindingObligation(trait_ty.def_id, span), + }, ) }; @@ -1254,7 +1259,11 @@ pub fn check_type_bounds<'tcx>( let concrete_ty_bound = bound.subst(tcx, rebased_substs); debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound); - traits::Obligation::new(mk_cause(span), param_env, concrete_ty_bound) + traits::Obligation::new( + mk_cause(bound.kind().skip_binder(), span), + param_env, + concrete_ty_bound, + ) }) .collect(); debug!("check_type_bounds: item_bounds={:?}", obligations); diff --git a/src/test/ui/associated-types/issue-63593.stderr b/src/test/ui/associated-types/issue-63593.stderr index d4654c7d5ace0..325d3e1ed272b 100644 --- a/src/test/ui/associated-types/issue-63593.stderr +++ b/src/test/ui/associated-types/issue-63593.stderr @@ -2,15 +2,21 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation --> $DIR/issue-63593.rs:9:17 | LL | type This = Self; - | ------------^^^^- - | | | - | | doesn't have a size known at compile-time - | required by this bound in `MyTrait::This` + | ^^^^ doesn't have a size known at compile-time | +note: associated types have an implicit `Sized` obligation + --> $DIR/issue-63593.rs:9:5 + | +LL | type This = Self; + | ^^^^^^^^^^^^^^^^^ required by associated type `MyTrait::This` help: consider further restricting `Self` | LL | trait MyTrait: Sized { | ^^^^^^^ +help: consider relaxing the `Sized` obligation + | +LL | type This: ?Sized = Self; + | ^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/generic-associated-types/issue-74816.stderr b/src/test/ui/generic-associated-types/issue-74816.stderr index ecafbfc6f0c2f..a08c51323c000 100644 --- a/src/test/ui/generic-associated-types/issue-74816.stderr +++ b/src/test/ui/generic-associated-types/issue-74816.stderr @@ -15,15 +15,21 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation --> $DIR/issue-74816.rs:10:31 | LL | type Associated: Trait1 = Self; - | --------------------------^^^^- - | | | - | | doesn't have a size known at compile-time - | required by this bound in `Trait2::Associated` + | ^^^^ doesn't have a size known at compile-time | +note: associated types have an implicit `Sized` obligation + --> $DIR/issue-74816.rs:10:5 + | +LL | type Associated: Trait1 = Self; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by associated type `Trait2::Associated` help: consider further restricting `Self` | LL | trait Trait2: Sized { | ^^^^^^^ +help: consider relaxing the `Sized` obligation + | +LL | type Associated: Trait1 + ?Sized = Self; + | ^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/issue-65673.stderr b/src/test/ui/traits/issue-65673.stderr index 6f9bb3edfe047..7dd432bae688c 100644 --- a/src/test/ui/traits/issue-65673.stderr +++ b/src/test/ui/traits/issue-65673.stderr @@ -1,13 +1,19 @@ error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time --> $DIR/issue-65673.rs:9:16 | -LL | type Ctx; - | --------- required by this bound in `WithType::Ctx` -... LL | type Ctx = dyn Alias; | ^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Trait + 'static)` +note: associated types have an implicit `Sized` obligation + --> $DIR/issue-65673.rs:4:5 + | +LL | type Ctx; + | ^^^^^^^^^ required by associated type `WithType::Ctx` +help: consider relaxing the `Sized` obligation + | +LL | type Ctx: ?Sized; + | ^^^^^^^^ error: aborting due to previous error