Rollup merge of #153967 - estebank:infer_must_implement, r=petrochenkov

Tweak wording of failed predicate in inference error

Special case message talking about `Predicate` that couldn't be satisfied when in inference errors so that we don't say "cannot satisfy `_: Trait`" and instead say "type must implement `Trait`".
This commit is contained in:
Jonathan Brouwer
2026-03-17 17:51:30 +01:00
committed by GitHub
24 changed files with 39 additions and 28 deletions
@@ -11,6 +11,7 @@
use rustc_infer::traits::{
Obligation, ObligationCause, ObligationCauseCode, PolyTraitObligation, PredicateObligation,
};
use rustc_middle::ty::print::PrintPolyTraitPredicateExt;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable as _, TypeVisitableExt as _};
use rustc_session::parse::feature_err_unstable_feature_bound;
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
@@ -306,8 +307,18 @@ pub(super) fn maybe_report_ambiguity(
err.cancel();
return e;
}
let pred = self.tcx.short_string(predicate, &mut err.long_ty_path());
err.note(format!("cannot satisfy `{pred}`"));
if let Some(clause) = predicate.as_trait_clause()
&& let ty::Infer(_) = clause.self_ty().skip_binder().kind()
{
let tr = self.tcx.short_string(
clause.print_modifiers_and_trait_path(),
&mut err.long_ty_path(),
);
err.note(format!("the type must implement `{tr}`"));
} else {
let pred = self.tcx.short_string(predicate, &mut err.long_ty_path());
err.note(format!("cannot satisfy `{pred}`"));
}
let impl_candidates =
self.find_similar_impl_candidates(predicate.as_trait_clause().unwrap());
if impl_candidates.len() < 40 {
@@ -6,7 +6,7 @@ LL | let _ = foo([0; 1]);
| |
| required by a bound introduced by this call
|
= note: cannot satisfy `_: Foo`
= note: the type must implement `Foo`
help: the trait `Foo` is implemented for `u8`
--> $DIR/issue-83249.rs:8:1
|
@@ -4,7 +4,7 @@ error[E0283]: type annotations needed
LL | cmp_eq
| ^^^^^^ cannot infer type of the type parameter `A` declared on the function `cmp_eq`
|
= note: cannot satisfy `_: Scalar`
= note: the type must implement `Scalar`
note: required by a bound in `cmp_eq`
--> $DIR/ambig-hr-projection-issue-93340.rs:10:22
|
@@ -4,7 +4,7 @@ error[E0283]: type annotations needed
LL | do_something(SomeImplementation(), test);
| ^^^^ cannot infer type of the type parameter `I` declared on the function `test`
|
= note: cannot satisfy `_: Iterable`
= note: the type must implement `Iterable`
help: the trait `Iterable` is implemented for `SomeImplementation`
--> $DIR/issue-88382.rs:13:1
|
@@ -4,7 +4,7 @@ error[E0283]: type annotations needed
LL | ().publish_typed();
| ^^^^^^^^^^^^^ cannot infer type of the type parameter `F` declared on the method `publish_typed`
|
= note: cannot satisfy `_: Clone`
= note: the type must implement `Clone`
= note: opaque types cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
note: required by a bound in `TypedClient::publish_typed::{anon_assoc#0}`
--> $DIR/not-inferred-generic.rs:4:12
@@ -7,7 +7,7 @@ LL |
LL | loop {}
| ------- return type was inferred to be `!` here
|
= note: cannot satisfy `_: Future`
= note: the type must implement `Future`
error: aborting due to 1 previous error
+1 -1
View File
@@ -4,7 +4,7 @@ error[E0283]: type annotations needed
LL | fn in_adt_in_return() -> Vec<impl Debug> { panic!() }
| ^^^^^^^^^^ cannot infer type
|
= note: cannot satisfy `_: Debug`
= note: the type must implement `Debug`
error: aborting due to 1 previous error
+1 -1
View File
@@ -374,7 +374,7 @@ error[E0283]: type annotations needed
LL | fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
| ^^^^^^^^^^ cannot infer type
|
= note: cannot satisfy `_: Debug`
= note: the type must implement `Debug`
error[E0283]: type annotations needed
--> $DIR/where-allowed.rs:65:46
+1 -1
View File
@@ -14,7 +14,7 @@ error[E0283]: type annotations needed
LL | fn main() { foo(); }
| ^^^^^ cannot infer type
|
= note: cannot satisfy `_: Foo`
= note: the type must implement `Foo`
error: aborting due to 2 previous errors
@@ -4,7 +4,7 @@ error[E0283]: type annotations needed for `Foo<i32, &str, _, _>`
LL | let foo = foo(1, "");
| ^^^ ---------- type must be known at this point
|
= note: cannot satisfy `_: Default`
= note: the type must implement `Default`
note: required by a bound in `foo`
--> $DIR/erase-type-params-in-label.rs:25:17
|
@@ -21,7 +21,7 @@ error[E0283]: type annotations needed for `Bar<i32, &str, _>`
LL | let bar = bar(1, "");
| ^^^ ---------- type must be known at this point
|
= note: cannot satisfy `_: Default`
= note: the type must implement `Default`
note: required by a bound in `bar`
--> $DIR/erase-type-params-in-label.rs:14:17
|
+1 -1
View File
@@ -6,7 +6,7 @@ LL | foo(gen()); //<- Do not suggest `foo::<impl Clone>()`!
| |
| required by a bound introduced by this call
|
= note: cannot satisfy `_: Clone`
= note: the type must implement `Clone`
note: required by a bound in `foo`
--> $DIR/issue-86162-1.rs:3:16
|
+1 -1
View File
@@ -6,7 +6,7 @@ LL | Foo::bar(gen()); //<- Do not suggest `Foo::bar::<impl Clone>()`!
| |
| required by a bound introduced by this call
|
= note: cannot satisfy `_: Clone`
= note: the type must implement `Clone`
note: required by a bound in `Foo::bar`
--> $DIR/issue-86162-2.rs:8:20
|
@@ -6,7 +6,7 @@ LL | (S {}).owo(None)
| |
| required by a bound introduced by this call
|
= note: cannot satisfy `_: T`
= note: the type must implement `T`
note: required by a bound in `S::owo`
--> $DIR/issue-113264-incorrect-impl-trait-in-path-suggestion.rs:6:35
|
@@ -4,7 +4,7 @@ error[E0283]: type annotations needed
LL | l.iter().map(f).collect()?
| ^^^^^^^ cannot infer type of the type parameter `B` declared on the method `collect`
|
= note: cannot satisfy `_: FromIterator<Result<i32, ()>>`
= note: the type must implement `FromIterator<Result<i32, ()>>`
note: required by a bound in `collect`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
help: consider specifying the generic argument
@@ -18,7 +18,7 @@ error[E0283]: type annotations needed
LL | let x = l.iter().map(f).collect()?;
| ^^^^^^^ cannot infer type of the type parameter `B` declared on the method `collect`
|
= note: cannot satisfy `_: FromIterator<Result<i32, ()>>`
= note: the type must implement `FromIterator<Result<i32, ()>>`
note: required by a bound in `collect`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
help: consider specifying the generic argument
@@ -32,7 +32,7 @@ error[E0283]: type annotations needed
LL | let x: Vec<i32> = l.iter().map(f).collect()?;
| ^^^^^^^ cannot infer type of the type parameter `B` declared on the method `collect`
|
= note: cannot satisfy `_: FromIterator<Result<i32, ()>>`
= note: the type must implement `FromIterator<Result<i32, ()>>`
note: required by a bound in `collect`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
help: consider specifying the generic argument
@@ -41,7 +41,7 @@ pub fn error2(lines: &[&str]) -> Result<Vec<Version>> {
let mut tags: Vec<Version> = lines.iter().map(|e| parse(e)).collect()?;
//~^ ERROR: type annotations needed
//~| NOTE: cannot infer type of the type parameter `B`
//~| NOTE: cannot satisfy `_: FromIterator<std::result::Result<Version, Error>>`
//~| NOTE: the type must implement `FromIterator<std::result::Result<Version, Error>>`
//~| NOTE: required by a bound in `collect`
//~| HELP: consider specifying the generic argument
tags.sort();
@@ -18,7 +18,7 @@ error[E0283]: type annotations needed
LL | let mut tags: Vec<Version> = lines.iter().map(|e| parse(e)).collect()?;
| ^^^^^^^ cannot infer type of the type parameter `B` declared on the method `collect`
|
= note: cannot satisfy `_: FromIterator<std::result::Result<Version, Error>>`
= note: the type must implement `FromIterator<std::result::Result<Version, Error>>`
note: required by a bound in `collect`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
help: consider specifying the generic argument
@@ -4,7 +4,7 @@ error[E0283]: type annotations needed
LL | .into()?;
| ^^^^
|
= note: cannot satisfy `_: From<FilterMap<Map<std::slice::Iter<'_, &str>, {closure@$DIR/into-inference-needs-type.rs:10:14: 10:17}>, fn(Option<&str>) -> Option<Option<&str>> {Option::<Option<&str>>::Some}>>`
= note: the type must implement `From<FilterMap<Map<std::slice::Iter<'_, &str>, {closure@$DIR/into-inference-needs-type.rs:10:14: 10:17}>, fn(Option<&str>) -> Option<Option<&str>> {Option::<Option<&str>>::Some}>>`
= note: required for `FilterMap<Map<std::slice::Iter<'_, &str>, {closure@$DIR/into-inference-needs-type.rs:10:14: 10:17}>, fn(Option<&str>) -> Option<Option<&str>> {Option::<Option<&str>>::Some}>` to implement `Into<_>`
help: try using a fully qualified path to specify the expected types
|
@@ -6,7 +6,7 @@ LL | qux(Bar.into());
| |
| required by a bound introduced by this call
|
= note: cannot satisfy `_: From<Bar>`
= note: the type must implement `From<Bar>`
note: required by a bound in `qux`
--> $DIR/argument-with-unnecessary-method-call.rs:6:16
|
@@ -4,7 +4,7 @@ error[E0283]: type annotations needed
LL | println!("{:?}", iter::<_>());
| ^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `iter`
|
= note: cannot satisfy `_: Iterator`
= note: the type must implement `Iterator`
note: required by a bound in `iter`
--> $DIR/runaway-impl-candidate-selection.rs:8:12
|
@@ -4,7 +4,7 @@ error[E0283]: type annotations needed
LL | hello();
| ^^^^^ cannot infer type of the type parameter `T` declared on the function `hello`
|
= note: cannot satisfy `_: Hello`
= note: the type must implement `Hello`
help: the following types implement trait `Hello`
--> $DIR/overflow-computing-ambiguity.rs:8:1
|
@@ -7,7 +7,7 @@ LL | panic!(std::default::Default::default());
| | cannot infer type
| required by a bound introduced by this call
|
= note: cannot satisfy `_: Any`
= note: the type must implement `Any`
note: required by a bound in `std::rt::begin_panic`
--> $SRC_DIR/std/src/panicking.rs:LL:COL
+1 -1
View File
@@ -6,7 +6,7 @@ LL | lst.sort_by_key(|&(v, _)| v.iter().sum());
| |
| type must be known at this point
|
= note: cannot satisfy `_: Ord`
= note: the type must implement `Ord`
note: required by a bound in `slice::<impl [T]>::sort_by_key`
--> $SRC_DIR/alloc/src/slice.rs:LL:COL
help: consider specifying the generic argument
+1 -1
View File
@@ -6,5 +6,5 @@ fn main() {
foo(42);
//~^ ERROR type annotations needed
//~| NOTE cannot infer type
//~| NOTE cannot satisfy
//~| NOTE the type must implement
}
+1 -1
View File
@@ -4,7 +4,7 @@ error[E0283]: type annotations needed
LL | foo(42);
| ^^^ cannot infer type of the type parameter `T` declared on the function `foo`
|
= note: cannot satisfy `_: Into<String>`
= note: the type must implement `Into<String>`
note: required by a bound in `foo`
--> $DIR/type-annotation-needed.rs:1:11
|