Skip to content

Commit 3956224

Browse files
committed
Account for associated types in Sized bound error
1 parent f338867 commit 3956224

File tree

5 files changed

+94
-17
lines changed

5 files changed

+94
-17
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+53-3
Original file line numberDiff line numberDiff line change
@@ -1935,8 +1935,58 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
19351935
ObligationCauseCode::ImplicitSizedObligation(item_def_id, span) => {
19361936
let item_name = tcx.def_path_str(item_def_id);
19371937
let mut sp: MultiSpan = span.into();
1938-
sp.push_span_label(span, format!("required by this bound in `{}`", item_name));
1939-
err.span_note(sp, "type parameters have an implicit `Sized` obligation");
1938+
match self.tcx.hir().get_if_local(item_def_id) {
1939+
Some(hir::Node::TraitItem(hir::TraitItem {
1940+
kind: hir::TraitItemKind::Type(bounds, _),
1941+
ident,
1942+
..
1943+
})) => {
1944+
sp.push_span_label(
1945+
span,
1946+
format!("required by associated type `{}`", item_name),
1947+
);
1948+
err.span_note(sp, "associated types have an implicit `Sized` obligation");
1949+
1950+
let sized_trait = self.tcx.lang_items().sized_trait();
1951+
if bounds.len() == 0 {
1952+
err.span_suggestion_verbose(
1953+
ident.span.shrink_to_hi(),
1954+
"consider relaxing the `Sized` obligation",
1955+
": ?Sized".to_string(),
1956+
Applicability::MaybeIncorrect,
1957+
);
1958+
} else if bounds.iter().all(|bound| {
1959+
bound.trait_ref().and_then(|tr| tr.trait_def_id()) != sized_trait
1960+
}) {
1961+
err.span_suggestion_verbose(
1962+
bounds.iter().last().unwrap().span().shrink_to_hi(),
1963+
"consider relaxing the `Sized` obligation",
1964+
" + ?Sized".to_string(),
1965+
Applicability::MaybeIncorrect,
1966+
);
1967+
}
1968+
}
1969+
Some(hir::Node::ImplItem(hir::ImplItem {
1970+
kind: hir::ImplItemKind::TyAlias(_),
1971+
..
1972+
})) => {
1973+
let msg = "associated types on `impl` blocks for types, have an implicit \
1974+
mandatory `Sized` obligation; associated types from `trait`s can be \
1975+
relaxed to `?Sized`";
1976+
sp.push_span_label(
1977+
span,
1978+
format!("required by associated type `{}`", item_name),
1979+
);
1980+
err.span_note(sp, msg);
1981+
}
1982+
_ => {
1983+
sp.push_span_label(
1984+
span,
1985+
format!("required by this bound in `{}`", item_name),
1986+
);
1987+
err.span_note(sp, "type parameters have an implicit `Sized` obligation");
1988+
}
1989+
}
19401990
}
19411991
ObligationCauseCode::BindingObligation(item_def_id, span) => {
19421992
let item_name = tcx.def_path_str(item_def_id);
@@ -1953,7 +2003,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
19532003
}
19542004
}
19552005
if span != DUMMY_SP {
1956-
err.span_label(span, &msg);
2006+
err.span_label(span, &msg);
19572007
} else {
19582008
err.note(&msg);
19592009
}

compiler/rustc_typeck/src/check/compare_method.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -1239,11 +1239,16 @@ pub fn check_type_bounds<'tcx>(
12391239

12401240
let impl_ty_hir_id = tcx.hir().local_def_id_to_hir_id(impl_ty.def_id.expect_local());
12411241
let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_hir_id);
1242-
let mk_cause = |span| {
1242+
let mk_cause = |bound, span| {
12431243
ObligationCause::new(
12441244
impl_ty_span,
12451245
impl_ty_hir_id,
1246-
ObligationCauseCode::BindingObligation(trait_ty.def_id, span),
1246+
match bound {
1247+
ty::PredicateKind::Trait(_, _, ty::ImplicitTraitPredicate::Yes) => {
1248+
traits::ImplicitSizedObligation(trait_ty.def_id, span)
1249+
}
1250+
_ => ObligationCauseCode::BindingObligation(trait_ty.def_id, span),
1251+
},
12471252
)
12481253
};
12491254

@@ -1254,7 +1259,11 @@ pub fn check_type_bounds<'tcx>(
12541259
let concrete_ty_bound = bound.subst(tcx, rebased_substs);
12551260
debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound);
12561261

1257-
traits::Obligation::new(mk_cause(span), param_env, concrete_ty_bound)
1262+
traits::Obligation::new(
1263+
mk_cause(bound.kind().skip_binder(), span),
1264+
param_env,
1265+
concrete_ty_bound,
1266+
)
12581267
})
12591268
.collect();
12601269
debug!("check_type_bounds: item_bounds={:?}", obligations);

src/test/ui/associated-types/issue-63593.stderr

+10-4
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,21 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation
22
--> $DIR/issue-63593.rs:9:17
33
|
44
LL | type This = Self;
5-
| ------------^^^^-
6-
| | |
7-
| | doesn't have a size known at compile-time
8-
| required by this bound in `MyTrait::This`
5+
| ^^^^ doesn't have a size known at compile-time
96
|
7+
note: associated types have an implicit `Sized` obligation
8+
--> $DIR/issue-63593.rs:9:5
9+
|
10+
LL | type This = Self;
11+
| ^^^^^^^^^^^^^^^^^ required by associated type `MyTrait::This`
1012
help: consider further restricting `Self`
1113
|
1214
LL | trait MyTrait: Sized {
1315
| ^^^^^^^
16+
help: consider relaxing the `Sized` obligation
17+
|
18+
LL | type This: ?Sized = Self;
19+
| ^^^^^^^^
1420

1521
error: aborting due to previous error
1622

src/test/ui/generic-associated-types/issue-74816.stderr

+10-4
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,21 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation
1515
--> $DIR/issue-74816.rs:10:31
1616
|
1717
LL | type Associated: Trait1 = Self;
18-
| --------------------------^^^^-
19-
| | |
20-
| | doesn't have a size known at compile-time
21-
| required by this bound in `Trait2::Associated`
18+
| ^^^^ doesn't have a size known at compile-time
2219
|
20+
note: associated types have an implicit `Sized` obligation
21+
--> $DIR/issue-74816.rs:10:5
22+
|
23+
LL | type Associated: Trait1 = Self;
24+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by associated type `Trait2::Associated`
2325
help: consider further restricting `Self`
2426
|
2527
LL | trait Trait2: Sized {
2628
| ^^^^^^^
29+
help: consider relaxing the `Sized` obligation
30+
|
31+
LL | type Associated: Trait1 + ?Sized = Self;
32+
| ^^^^^^^^
2733

2834
error: aborting due to 2 previous errors
2935

src/test/ui/traits/issue-65673.stderr

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
22
--> $DIR/issue-65673.rs:9:16
33
|
4-
LL | type Ctx;
5-
| --------- required by this bound in `WithType::Ctx`
6-
...
74
LL | type Ctx = dyn Alias<T>;
85
| ^^^^^^^^^^^^ doesn't have a size known at compile-time
96
|
107
= help: the trait `Sized` is not implemented for `(dyn Trait + 'static)`
8+
note: associated types have an implicit `Sized` obligation
9+
--> $DIR/issue-65673.rs:4:5
10+
|
11+
LL | type Ctx;
12+
| ^^^^^^^^^ required by associated type `WithType::Ctx`
13+
help: consider relaxing the `Sized` obligation
14+
|
15+
LL | type Ctx: ?Sized;
16+
| ^^^^^^^^
1117

1218
error: aborting due to previous error
1319

0 commit comments

Comments
 (0)