Skip to content

Commit

Permalink
Account for associated types in Sized bound error
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Jun 11, 2021
1 parent f338867 commit 3956224
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}
Expand Down
15 changes: 12 additions & 3 deletions compiler/rustc_typeck/src/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
},
)
};

Expand All @@ -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);
Expand Down
14 changes: 10 additions & 4 deletions src/test/ui/associated-types/issue-63593.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
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
Expand Up @@ -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

Expand Down
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

Expand Down

0 comments on commit 3956224

Please sign in to comment.