Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explain origin of implicit Sized obligations and provide suggestions when possible #85947

Closed
wants to merge 11 commits into from
Prev Previous commit
Account for associated types in Sized bound error
  • Loading branch information
estebank committed Jun 11, 2021
commit 3956224f0c8ea4bcbe1c87d79471491c2f59a1cc
Original file line number Diff line number Diff line change
@@ -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);
}
15 changes: 12 additions & 3 deletions compiler/rustc_typeck/src/check/compare_method.rs
Original file line number Diff line number Diff line change
@@ -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);
14 changes: 10 additions & 4 deletions src/test/ui/associated-types/issue-63593.stderr
Original file line number Diff line number Diff line change
@@ -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

14 changes: 10 additions & 4 deletions src/test/ui/generic-associated-types/issue-74816.stderr
Original file line number Diff line number Diff line change
@@ -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

12 changes: 9 additions & 3 deletions src/test/ui/traits/issue-65673.stderr
Original file line number Diff line number Diff line change
@@ -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<T>;
| ^^^^^^^^^^^^ 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