Rollup merge of #150737 - smithdb3/fix-150576, r=chenyukang
diagnostics: make implicit Sized bounds explicit in E0277 When a trait parameter depends upon Sized, the error message only referred to the full trait itself and didn't mention Sized. This makes the failure to implement Sized explicit. It also notes when the Sized trait bound is explicit or implicit. Fixes rust-lang/rust#150576
This commit is contained in:
commit
6c700ecd6a
10 changed files with 186 additions and 24 deletions
|
|
@ -1391,25 +1391,45 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
// return early in the caller.
|
||||
|
||||
let mut label = || {
|
||||
// Special case `Sized` as `old_pred` will be the trait itself instead of
|
||||
// `Sized` when the trait bound is the source of the error.
|
||||
let is_sized = match obligation.predicate.kind().skip_binder() {
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) => {
|
||||
self.tcx.is_lang_item(trait_pred.def_id(), LangItem::Sized)
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
||||
let msg = format!(
|
||||
"the trait bound `{}` is not satisfied",
|
||||
self.tcx.short_string(old_pred, err.long_ty_path()),
|
||||
);
|
||||
let self_ty_str =
|
||||
self.tcx.short_string(old_pred.self_ty().skip_binder(), err.long_ty_path());
|
||||
let self_ty_str = self.tcx.short_string(old_pred.self_ty(), err.long_ty_path());
|
||||
let trait_path = self
|
||||
.tcx
|
||||
.short_string(old_pred.print_modifiers_and_trait_path(), err.long_ty_path());
|
||||
|
||||
if has_custom_message {
|
||||
let msg = if is_sized {
|
||||
"the trait bound `Sized` is not satisfied".into()
|
||||
} else {
|
||||
msg
|
||||
};
|
||||
err.note(msg);
|
||||
} else {
|
||||
err.messages = vec![(rustc_errors::DiagMessage::from(msg), Style::NoStyle)];
|
||||
}
|
||||
err.span_label(
|
||||
span,
|
||||
format!("the trait `{trait_path}` is not implemented for `{self_ty_str}`"),
|
||||
);
|
||||
if is_sized {
|
||||
err.span_label(
|
||||
span,
|
||||
format!("the trait `Sized` is not implemented for `{self_ty_str}`"),
|
||||
);
|
||||
} else {
|
||||
err.span_label(
|
||||
span,
|
||||
format!("the trait `{trait_path}` is not implemented for `{self_ty_str}`"),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let mut sugg_prefixes = vec![];
|
||||
|
|
@ -3578,10 +3598,27 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
"unsatisfied trait bound introduced in this `derive` macro",
|
||||
);
|
||||
} else if !data.span.is_dummy() && !data.span.overlaps(self_ty.span) {
|
||||
spans.push_span_label(
|
||||
data.span,
|
||||
"unsatisfied trait bound introduced here",
|
||||
);
|
||||
// `Sized` may be an explicit or implicit trait bound. If it is
|
||||
// implicit, mention it as such.
|
||||
if let Some(pred) = predicate.as_trait_clause()
|
||||
&& self.tcx.is_lang_item(pred.def_id(), LangItem::Sized)
|
||||
&& self
|
||||
.tcx
|
||||
.generics_of(data.impl_or_alias_def_id)
|
||||
.own_params
|
||||
.iter()
|
||||
.any(|param| self.tcx.def_span(param.def_id) == data.span)
|
||||
{
|
||||
spans.push_span_label(
|
||||
data.span,
|
||||
"unsatisfied trait bound implicitly introduced here",
|
||||
);
|
||||
} else {
|
||||
spans.push_span_label(
|
||||
data.span,
|
||||
"unsatisfied trait bound introduced here",
|
||||
);
|
||||
}
|
||||
}
|
||||
err.span_note(spans, msg);
|
||||
point_at_assoc_type_restriction(
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ note: required for `str` to implement `Foo<'_, '_, u8>`
|
|||
LL | impl<'a, 'b, T, S> Foo<'a, 'b, S> for T {}
|
||||
| - ^^^^^^^^^^^^^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
| unsatisfied trait bound implicitly introduced here
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ note: required for `str` to implement `Foo<'?0, '?1, u8>`
|
|||
LL | impl<'a, 'b, T, S> Foo<'a, 'b, S> for T {}
|
||||
| - ^^^^^^^^^^^^^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
| unsatisfied trait bound implicitly introduced here
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
|
|
|||
50
tests/ui/error-codes/E0277-4.rs
Normal file
50
tests/ui/error-codes/E0277-4.rs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
trait ImplicitTrait {
|
||||
fn foo(&self);
|
||||
}
|
||||
|
||||
trait ExplicitTrait {
|
||||
fn foo(&self);
|
||||
}
|
||||
|
||||
trait DisplayTrait {
|
||||
fn foo(&self);
|
||||
}
|
||||
|
||||
trait UnimplementedTrait {
|
||||
fn foo(&self);
|
||||
}
|
||||
|
||||
// Implicitly requires `T: Sized`.
|
||||
impl<T> ImplicitTrait for T {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
||||
// Explicitly requires `T: Sized`.
|
||||
impl<T: Sized> ExplicitTrait for T {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
||||
// Requires `T: Display`.
|
||||
impl<T: Display> DisplayTrait for T {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// `[u8]` does not implement `Sized`.
|
||||
let x: &[u8] = &[];
|
||||
ImplicitTrait::foo(x);
|
||||
//~^ ERROR: the trait bound `[u8]: ImplicitTrait` is not satisfied [E0277]
|
||||
ExplicitTrait::foo(x);
|
||||
//~^ ERROR: the trait bound `[u8]: ExplicitTrait` is not satisfied [E0277]
|
||||
|
||||
// `UnimplementedTrait` has no implementations.
|
||||
UnimplementedTrait::foo(x);
|
||||
//~^ ERROR: the trait bound `[u8]: UnimplementedTrait` is not satisfied [E0277]
|
||||
|
||||
// `[u8; 0]` implements `Sized` but not `Display`.
|
||||
let x: &[u8; 0] = &[];
|
||||
DisplayTrait::foo(x);
|
||||
//~^ ERROR: the trait bound `[u8; 0]: DisplayTrait` is not satisfied [E0277]
|
||||
}
|
||||
77
tests/ui/error-codes/E0277-4.stderr
Normal file
77
tests/ui/error-codes/E0277-4.stderr
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
error[E0277]: the trait bound `[u8]: ImplicitTrait` is not satisfied
|
||||
--> $DIR/E0277-4.rs:37:24
|
||||
|
|
||||
LL | ImplicitTrait::foo(x);
|
||||
| ------------------ ^ the trait `Sized` is not implemented for `[u8]`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required for `[u8]` to implement `ImplicitTrait`
|
||||
--> $DIR/E0277-4.rs:20:9
|
||||
|
|
||||
LL | impl<T> ImplicitTrait for T {
|
||||
| - ^^^^^^^^^^^^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound implicitly introduced here
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | ImplicitTrait::foo(&x);
|
||||
| +
|
||||
LL | ImplicitTrait::foo(&mut x);
|
||||
| ++++
|
||||
|
||||
error[E0277]: the trait bound `[u8]: ExplicitTrait` is not satisfied
|
||||
--> $DIR/E0277-4.rs:39:24
|
||||
|
|
||||
LL | ExplicitTrait::foo(x);
|
||||
| ------------------ ^ the trait `Sized` is not implemented for `[u8]`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required for `[u8]` to implement `ExplicitTrait`
|
||||
--> $DIR/E0277-4.rs:25:16
|
||||
|
|
||||
LL | impl<T: Sized> ExplicitTrait for T {
|
||||
| ----- ^^^^^^^^^^^^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | ExplicitTrait::foo(&x);
|
||||
| +
|
||||
LL | ExplicitTrait::foo(&mut x);
|
||||
| ++++
|
||||
|
||||
error[E0277]: the trait bound `[u8]: UnimplementedTrait` is not satisfied
|
||||
--> $DIR/E0277-4.rs:43:29
|
||||
|
|
||||
LL | UnimplementedTrait::foo(x);
|
||||
| ----------------------- ^ the trait `UnimplementedTrait` is not implemented for `[u8]`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/E0277-4.rs:15:1
|
||||
|
|
||||
LL | trait UnimplementedTrait {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0277]: the trait bound `[u8; 0]: DisplayTrait` is not satisfied
|
||||
--> $DIR/E0277-4.rs:48:23
|
||||
|
|
||||
LL | DisplayTrait::foo(x);
|
||||
| ----------------- ^ the trait `std::fmt::Display` is not implemented for `[u8; 0]`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required for `[u8; 0]` to implement `DisplayTrait`
|
||||
--> $DIR/E0277-4.rs:30:18
|
||||
|
|
||||
LL | impl<T: Display> DisplayTrait for T {
|
||||
| ------- ^^^^^^^^^^^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
@ -11,7 +11,7 @@ note: required for `GetNext<<<<... as Next>::Next as Next>::Next as Next>::Next>
|
|||
LL | impl<T: Next> Next for GetNext<T> {
|
||||
| - ^^^^ ^^^^^^^^^^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
| unsatisfied trait bound implicitly introduced here
|
||||
= note: the full name for the type has been written to '$TEST_BUILD_DIR/issue-23122-2.long-type-$LONG_TYPE_HASH.txt'
|
||||
= note: consider using `--verbose` to print the full type name to the console
|
||||
|
||||
|
|
|
|||
|
|
@ -17,11 +17,10 @@ error[E0277]: `[i32]` is not an iterator
|
|||
--> $DIR/slice-issue-87994.rs:3:12
|
||||
|
|
||||
LL | for _ in v[1..] {
|
||||
| ^^^^^^ the trait `IntoIterator` is not implemented for `[i32]`
|
||||
| ^^^^^^ the trait `Sized` is not implemented for `[i32]`
|
||||
|
|
||||
= note: the trait bound `[i32]: IntoIterator` is not satisfied
|
||||
= note: the trait bound `Sized` is not satisfied
|
||||
= note: required for `[i32]` to implement `IntoIterator`
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | for _ in &v[1..] {
|
||||
|
|
@ -48,11 +47,10 @@ error[E0277]: `[K]` is not an iterator
|
|||
--> $DIR/slice-issue-87994.rs:11:13
|
||||
|
|
||||
LL | for i2 in v2[1..] {
|
||||
| ^^^^^^^ the trait `IntoIterator` is not implemented for `[K]`
|
||||
| ^^^^^^^ the trait `Sized` is not implemented for `[K]`
|
||||
|
|
||||
= note: the trait bound `[K]: IntoIterator` is not satisfied
|
||||
= note: the trait bound `Sized` is not satisfied
|
||||
= note: required for `[K]` to implement `IntoIterator`
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | for i2 in &v2[1..] {
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ error[E0277]: `dyn Iterator<Item = &'a mut u8>` is not an iterator
|
|||
--> $DIR/dyn-iterator-deref-in-for-loop.rs:9:17
|
||||
|
|
||||
LL | for item in *things {
|
||||
| ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>`
|
||||
| ^^^^^^^ the trait `Sized` is not implemented for `dyn Iterator<Item = &'a mut u8>`
|
||||
|
|
||||
= note: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied
|
||||
= note: the trait bound `Sized` is not satisfied
|
||||
= note: required for `dyn Iterator<Item = &'a mut u8>` to implement `IntoIterator`
|
||||
help: consider mutably borrowing here
|
||||
|
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ error[E0277]: `dyn Iterator<Item = &'a mut u8>` is not an iterator
|
|||
--> $DIR/dyn-iterator-deref-in-for-loop.rs:9:17
|
||||
|
|
||||
LL | for item in *things {
|
||||
| ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>`
|
||||
| ^^^^^^^ the trait `Sized` is not implemented for `dyn Iterator<Item = &'a mut u8>`
|
||||
|
|
||||
= note: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied
|
||||
= note: the trait bound `Sized` is not satisfied
|
||||
= note: required for `dyn Iterator<Item = &'a mut u8>` to implement `IntoIterator`
|
||||
help: consider mutably borrowing here
|
||||
|
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ note: required for `{integer}` to implement `Set<&[_]>`
|
|||
LL | impl<'a, T, S> Set<&'a [T]> for S where
|
||||
| - ^^^^^^^^^^^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
| unsatisfied trait bound implicitly introduced here
|
||||
= note: 128 redundant requirements hidden
|
||||
= note: required for `{integer}` to implement `Set<&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[_]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]>`
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue