1
Fork 0

Fix #90970, doesn't address #87437

This commit is contained in:
Esteban Kuber 2022-03-26 21:26:02 +00:00
parent 3aac307ca6
commit ac8cbbd200
8 changed files with 115 additions and 6 deletions

View file

@ -2,10 +2,11 @@ pub mod on_unimplemented;
pub mod suggestions; pub mod suggestions;
use super::{ use super::{
EvaluationResult, FulfillmentContext, FulfillmentError, FulfillmentErrorCode, DerivedObligationCause, EvaluationResult, FulfillmentContext, FulfillmentError,
MismatchedProjectionTypes, Obligation, ObligationCause, ObligationCauseCode, FulfillmentErrorCode, ImplDerivedObligationCause, MismatchedProjectionTypes, Obligation,
OnUnimplementedDirective, OnUnimplementedNote, OutputTypeParameterMismatch, Overflow, ObligationCause, ObligationCauseCode, OnUnimplementedDirective, OnUnimplementedNote,
PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe, OutputTypeParameterMismatch, Overflow, PredicateObligation, SelectionContext, SelectionError,
TraitNotObjectSafe,
}; };
use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
@ -654,11 +655,77 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
} else if !suggested { } else if !suggested {
// Can't show anything else useful, try to find similar impls. // Can't show anything else useful, try to find similar impls.
let impl_candidates = self.find_similar_impl_candidates(trait_ref); let impl_candidates = self.find_similar_impl_candidates(trait_ref);
self.report_similar_impl_candidates( if !self.report_similar_impl_candidates(
impl_candidates, impl_candidates,
trait_ref, trait_ref,
&mut err, &mut err,
); ) {
// This is *almost* equivalent to
// `obligation.cause.code().peel_derives()`, but it gives us the
// trait predicate for that corresponding root obligation. This
// lets us get a derived obligation from a type parameter, like
// when calling `string.strip_suffix(p)` where `p` is *not* an
// implementer of `Pattern<'_>`.
let mut code = obligation.cause.code();
let mut trait_pred = trait_predicate;
let mut peeled = false;
loop {
match &*code {
ObligationCauseCode::FunctionArgumentObligation {
parent_code,
..
} => {
code = &parent_code;
}
ObligationCauseCode::ImplDerivedObligation(
box ImplDerivedObligationCause {
derived:
DerivedObligationCause {
parent_code,
parent_trait_pred,
},
..
},
)
| ObligationCauseCode::BuiltinDerivedObligation(
DerivedObligationCause {
parent_code,
parent_trait_pred,
},
)
| ObligationCauseCode::DerivedObligation(
DerivedObligationCause {
parent_code,
parent_trait_pred,
},
) => {
peeled = true;
code = &parent_code;
trait_pred = *parent_trait_pred;
}
_ => break,
};
}
let def_id = trait_pred.def_id();
// Mention *all* the `impl`s for the *top most* obligation, the
// user might have meant to use one of them, if any found. We skip
// auto-traits or fundamental traits that might not be exactly what
// the user might expect to be presented with. Instead this is
// useful for less general traits.
if peeled
&& !self.tcx.trait_is_auto(def_id)
&& !self.tcx.lang_items().items().contains(&Some(def_id))
{
let trait_ref = trait_pred.to_poly_trait_ref();
let impl_candidates =
self.find_similar_impl_candidates(trait_ref);
self.report_similar_impl_candidates(
impl_candidates,
trait_ref,
&mut err,
);
}
}
} }
// Changing mutability doesn't make a difference to whether we have // Changing mutability doesn't make a difference to whether we have

View file

@ -6,6 +6,7 @@ LL | writes_to_specific_path(&cap);
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |
= help: the trait `Delegates<U>` is implemented for `T`
note: required because of the requirements on the impl of `Contains<(), true>` for `&C` note: required because of the requirements on the impl of `Contains<(), true>` for `&C`
--> $DIR/issue-85848.rs:21:12 --> $DIR/issue-85848.rs:21:12
| |

View file

@ -7,6 +7,7 @@ LL | Err("whoops")?;
| ^ the trait `From<&str>` is not implemented for `impl Debug` | ^ the trait `From<&str>` is not implemented for `impl Debug`
| |
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= help: the trait `FromResidual<Result<Infallible, E>>` is implemented for `Result<T, F>`
= note: required because of the requirements on the impl of `FromResidual<Result<Infallible, &str>>` for `Result<(), impl Debug>` = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, &str>>` for `Result<(), impl Debug>`
error[E0277]: the trait bound `impl Debug: From<&str>` is not satisfied error[E0277]: the trait bound `impl Debug: From<&str>` is not satisfied

View file

@ -52,6 +52,7 @@ error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfie
LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x } LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug` | ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
| |
= help: the trait `Into<U>` is implemented for `T`
= note: required because of the requirements on the impl of `Into<impl Debug>` for `impl Into<u32>` = note: required because of the requirements on the impl of `Into<impl Debug>` for `impl Into<u32>`
error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
@ -60,6 +61,7 @@ error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfie
LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x } LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug` | ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
| |
= help: the trait `Into<U>` is implemented for `T`
= note: required because of the requirements on the impl of `Into<impl Debug>` for `impl Into<u32>` = note: required because of the requirements on the impl of `Into<impl Debug>` for `impl Into<u32>`
error: aborting due to 8 previous errors error: aborting due to 8 previous errors

View file

@ -7,6 +7,7 @@ LL | Err(5)?;
| ^ the trait `From<{integer}>` is not implemented for `()` | ^ the trait `From<{integer}>` is not implemented for `()`
| |
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= help: the trait `FromResidual<Result<Infallible, E>>` is implemented for `Result<T, F>`
= note: required because of the requirements on the impl of `FromResidual<Result<Infallible, {integer}>>` for `Result<i32, ()>` = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, {integer}>>` for `Result<i32, ()>`
error: aborting due to previous error error: aborting due to previous error

View file

@ -80,6 +80,7 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
LL | let a = t as Box<dyn Gettable<String>>; LL | let a = t as Box<dyn Gettable<String>>;
| ^ the trait `Copy` is not implemented for `String` | ^ the trait `Copy` is not implemented for `String`
| |
= help: the trait `Gettable<T>` is implemented for `S<T>`
note: required because of the requirements on the impl of `Gettable<String>` for `S<String>` note: required because of the requirements on the impl of `Gettable<String>` for `S<String>`
--> $DIR/kindck-impl-type-params.rs:14:32 --> $DIR/kindck-impl-type-params.rs:14:32
| |
@ -93,6 +94,7 @@ error[E0277]: the trait bound `Foo: Copy` is not satisfied
LL | let a: Box<dyn Gettable<Foo>> = t; LL | let a: Box<dyn Gettable<Foo>> = t;
| ^ the trait `Copy` is not implemented for `Foo` | ^ the trait `Copy` is not implemented for `Foo`
| |
= help: the trait `Gettable<T>` is implemented for `S<T>`
note: required because of the requirements on the impl of `Gettable<Foo>` for `S<Foo>` note: required because of the requirements on the impl of `Gettable<Foo>` for `S<Foo>`
--> $DIR/kindck-impl-type-params.rs:14:32 --> $DIR/kindck-impl-type-params.rs:14:32
| |

View file

@ -0,0 +1,12 @@
fn strip_lf(s: &str) -> &str {
s.strip_suffix(b'\n').unwrap_or(s)
//~^ ERROR expected a `FnMut<(char,)>` closure, found `u8`
//~| NOTE expected an `FnMut<(char,)>` closure, found `u8`
//~| NOTE required by a bound introduced by this call
//~| HELP the trait `FnMut<(char,)>` is not implemented for `u8`
//~| HELP the following other types implement trait `Pattern<'_>`:
//~| NOTE required because of the requirements on the impl of `Pattern<'_>` for `u8`
}
fn main() {}

View file

@ -0,0 +1,23 @@
error[E0277]: expected a `FnMut<(char,)>` closure, found `u8`
--> $DIR/assoc-fn-bound-root-obligation.rs:2:20
|
LL | s.strip_suffix(b'\n').unwrap_or(s)
| ------------ ^^^^^ expected an `FnMut<(char,)>` closure, found `u8`
| |
| required by a bound introduced by this call
|
= help: the trait `FnMut<(char,)>` is not implemented for `u8`
= help: the following other types implement trait `Pattern<'_>`:
&'b String
&'b [char; N]
&'b [char]
&'b str
&'c &'b str
[char; N]
char
pattern::MultiCharEqPattern<C>
= note: required because of the requirements on the impl of `Pattern<'_>` for `u8`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.