parent
3aac307ca6
commit
ac8cbbd200
8 changed files with 115 additions and 6 deletions
|
@ -2,10 +2,11 @@ pub mod on_unimplemented;
|
|||
pub mod suggestions;
|
||||
|
||||
use super::{
|
||||
EvaluationResult, FulfillmentContext, FulfillmentError, FulfillmentErrorCode,
|
||||
MismatchedProjectionTypes, Obligation, ObligationCause, ObligationCauseCode,
|
||||
OnUnimplementedDirective, OnUnimplementedNote, OutputTypeParameterMismatch, Overflow,
|
||||
PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe,
|
||||
DerivedObligationCause, EvaluationResult, FulfillmentContext, FulfillmentError,
|
||||
FulfillmentErrorCode, ImplDerivedObligationCause, MismatchedProjectionTypes, Obligation,
|
||||
ObligationCause, ObligationCauseCode, OnUnimplementedDirective, OnUnimplementedNote,
|
||||
OutputTypeParameterMismatch, Overflow, PredicateObligation, SelectionContext, SelectionError,
|
||||
TraitNotObjectSafe,
|
||||
};
|
||||
|
||||
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 {
|
||||
// Can't show anything else useful, try to find similar impls.
|
||||
let impl_candidates = self.find_similar_impl_candidates(trait_ref);
|
||||
self.report_similar_impl_candidates(
|
||||
if !self.report_similar_impl_candidates(
|
||||
impl_candidates,
|
||||
trait_ref,
|
||||
&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
|
||||
|
|
|
@ -6,6 +6,7 @@ LL | writes_to_specific_path(&cap);
|
|||
| |
|
||||
| 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`
|
||||
--> $DIR/issue-85848.rs:21:12
|
||||
|
|
||||
|
|
|
@ -7,6 +7,7 @@ LL | Err("whoops")?;
|
|||
| ^ 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
|
||||
= 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>`
|
||||
|
||||
error[E0277]: the trait bound `impl Debug: From<&str>` is not satisfied
|
||||
|
|
|
@ -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 }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ 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>`
|
||||
|
||||
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 }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ 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>`
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
|
|
@ -7,6 +7,7 @@ LL | Err(5)?;
|
|||
| ^ 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
|
||||
= 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, ()>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
|
@ -80,6 +80,7 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
|
|||
LL | let a = t as Box<dyn Gettable<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>`
|
||||
--> $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;
|
||||
| ^ 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>`
|
||||
--> $DIR/kindck-impl-type-params.rs:14:32
|
||||
|
|
||||
|
|
12
src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs
Normal file
12
src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs
Normal 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() {}
|
|
@ -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`.
|
Loading…
Add table
Add a link
Reference in a new issue