Don't point at Self type if we can't find an infer variable in ambiguous trait predicate
This commit is contained in:
parent
ca0105ba4e
commit
12ab6bfafd
15 changed files with 94 additions and 57 deletions
|
@ -914,9 +914,17 @@ impl<'tcx> Term<'tcx> {
|
|||
pub fn ty(&self) -> Option<Ty<'tcx>> {
|
||||
if let Term::Ty(ty) = self { Some(*ty) } else { None }
|
||||
}
|
||||
|
||||
pub fn ct(&self) -> Option<Const<'tcx>> {
|
||||
if let Term::Const(c) = self { Some(*c) } else { None }
|
||||
}
|
||||
|
||||
pub fn into_arg(self) -> GenericArg<'tcx> {
|
||||
match self {
|
||||
Term::Ty(ty) => ty.into(),
|
||||
Term::Const(c) => c.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This kind of predicate has no *direct* correspondent in the
|
||||
|
|
|
@ -1970,13 +1970,31 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
|||
|
||||
// Pick the first substitution that still contains inference variables as the one
|
||||
// we're going to emit an error for. If there are none (see above), fall back to
|
||||
// the substitution for `Self`.
|
||||
let subst = {
|
||||
let substs = data.trait_ref.substs;
|
||||
substs
|
||||
.iter()
|
||||
.find(|s| s.has_infer_types_or_consts())
|
||||
.unwrap_or_else(|| substs[0])
|
||||
// a more general error.
|
||||
let subst = data.trait_ref.substs.iter().find(|s| s.has_infer_types_or_consts());
|
||||
|
||||
let mut err = if let Some(subst) = subst {
|
||||
let impl_candidates = self
|
||||
.find_similar_impl_candidates(trait_ref)
|
||||
.into_iter()
|
||||
.map(|candidate| candidate.trait_ref)
|
||||
.collect();
|
||||
self.emit_inference_failure_err(
|
||||
body_id,
|
||||
span,
|
||||
subst,
|
||||
impl_candidates,
|
||||
ErrorCode::E0283,
|
||||
true,
|
||||
)
|
||||
} else {
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
span,
|
||||
E0283,
|
||||
"type annotations needed: cannot satisfy `{}`",
|
||||
predicate,
|
||||
)
|
||||
};
|
||||
|
||||
// This is kind of a hack: it frequently happens that some earlier
|
||||
|
@ -1999,30 +2017,17 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
|||
self.emit_inference_failure_err(
|
||||
body_id,
|
||||
span,
|
||||
subst,
|
||||
trait_ref.self_ty().skip_binder().into(),
|
||||
vec![],
|
||||
ErrorCode::E0282,
|
||||
false,
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
err.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
let impl_candidates = self
|
||||
.find_similar_impl_candidates(trait_ref)
|
||||
.into_iter()
|
||||
.map(|candidate| candidate.trait_ref)
|
||||
.collect();
|
||||
let mut err = self.emit_inference_failure_err(
|
||||
body_id,
|
||||
span,
|
||||
subst,
|
||||
impl_candidates,
|
||||
ErrorCode::E0283,
|
||||
true,
|
||||
);
|
||||
|
||||
let obligation = Obligation::new(
|
||||
obligation.cause.clone(),
|
||||
obligation.param_env,
|
||||
|
@ -2136,17 +2141,20 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
|||
)
|
||||
}
|
||||
ty::PredicateKind::Projection(data) => {
|
||||
let self_ty = data.projection_ty.self_ty();
|
||||
let term = data.term;
|
||||
if predicate.references_error() || self.is_tainted_by_errors() {
|
||||
return;
|
||||
}
|
||||
if self_ty.needs_infer() && term.needs_infer() {
|
||||
// We do this for the `foo.collect()?` case to produce a suggestion.
|
||||
let subst = data
|
||||
.projection_ty
|
||||
.substs
|
||||
.iter()
|
||||
.chain(Some(data.term.into_arg()))
|
||||
.find(|g| g.has_infer_types_or_consts());
|
||||
if let Some(subst) = subst {
|
||||
let mut err = self.emit_inference_failure_err(
|
||||
body_id,
|
||||
span,
|
||||
self_ty.into(),
|
||||
subst,
|
||||
vec![],
|
||||
ErrorCode::E0284,
|
||||
true,
|
||||
|
@ -2154,6 +2162,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
|||
err.note(&format!("cannot satisfy `{}`", predicate));
|
||||
err
|
||||
} else {
|
||||
// If we can't find a substitution, just print a generic error
|
||||
let mut err = struct_span_err!(
|
||||
self.tcx.sess,
|
||||
span,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error[E0283]: type annotations needed
|
||||
error[E0283]: type annotations needed: cannot satisfy `u32: C`
|
||||
--> $DIR/coherence-overlap-trait-alias.rs:15:6
|
||||
|
|
||||
LL | impl C for u32 {}
|
||||
| ^ cannot infer type for type `u32`
|
||||
| ^
|
||||
|
|
||||
note: multiple `impl`s satisfying `u32: C` found
|
||||
--> $DIR/coherence-overlap-trait-alias.rs:14:1
|
||||
|
|
|
@ -34,19 +34,19 @@ LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
|
|||
= help: const parameters may only be used as standalone arguments, i.e. `J`
|
||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual<I, 8_u32>: True`
|
||||
--> $DIR/issue-72787.rs:21:26
|
||||
|
|
||||
LL | IsLessOrEqual<I, 8>: True,
|
||||
| ^^^^ cannot infer type for struct `IsLessOrEqual<I, 8_u32>`
|
||||
| ^^^^
|
||||
|
|
||||
= note: cannot satisfy `IsLessOrEqual<I, 8_u32>: True`
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual<I, 8_u32>: True`
|
||||
--> $DIR/issue-72787.rs:21:26
|
||||
|
|
||||
LL | IsLessOrEqual<I, 8>: True,
|
||||
| ^^^^ cannot infer type for struct `IsLessOrEqual<I, 8_u32>`
|
||||
| ^^^^
|
||||
|
|
||||
= note: cannot satisfy `IsLessOrEqual<I, 8_u32>: True`
|
||||
|
||||
|
|
|
@ -19,8 +19,8 @@ struct S<const I: u32, const J: u32>;
|
|||
impl<const I: u32, const J: u32> S<I, J>
|
||||
where
|
||||
IsLessOrEqual<I, 8>: True,
|
||||
//[min]~^ Error type annotations needed [E0283]
|
||||
//[min]~| Error type annotations needed [E0283]
|
||||
//[min]~^ Error type annotations needed
|
||||
//[min]~| Error type annotations needed
|
||||
IsLessOrEqual<J, 8>: True,
|
||||
IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
|
||||
//[min]~^ Error generic parameters may not be used in const operations
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
error[E0284]: type annotations needed: cannot satisfy `<_ as StreamHasher>::S == <H as StreamHasher>::S`
|
||||
error[E0284]: type annotations needed
|
||||
--> $DIR/issue-12028.rs:27:14
|
||||
|
|
||||
LL | self.input_stream(&mut stream);
|
||||
| ^^^^^^^^^^^^ cannot satisfy `<_ as StreamHasher>::S == <H as StreamHasher>::S`
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= note: cannot satisfy `<_ as StreamHasher>::S == <H as StreamHasher>::S`
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | <u8 as StreamHash<H>>::input_stream(self, &mut stream);
|
||||
| ++++++++++++++++++++++++++++++++++++ ~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error[E0283]: type annotations needed
|
||||
error[E0283]: type annotations needed: cannot satisfy `&'a T: Foo`
|
||||
--> $DIR/issue-21974.rs:11:19
|
||||
|
|
||||
LL | where &'a T : Foo,
|
||||
| ^^^ cannot infer type for reference `&'a T`
|
||||
| ^^^
|
||||
|
|
||||
= note: cannot satisfy `&'a T: Foo`
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error[E0283]: type annotations needed
|
||||
error[E0283]: type annotations needed: cannot satisfy `T0: Trait0<'l0>`
|
||||
--> $DIR/issue-24424.rs:4:57
|
||||
|
|
||||
LL | impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {}
|
||||
| ^^^^^^^^^^^ cannot infer type for type parameter `T0`
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: cannot satisfy `T0: Trait0<'l0>`
|
||||
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
error[E0284]: type annotations needed: cannot satisfy `<u8 as Element<_>>::Array == [u8; 3]`
|
||||
error[E0284]: type annotations needed
|
||||
--> $DIR/issue-69683.rs:30:10
|
||||
|
|
||||
LL | 0u16.foo(b);
|
||||
| ^^^ cannot satisfy `<u8 as Element<_>>::Array == [u8; 3]`
|
||||
| ^^^
|
||||
|
|
||||
= note: cannot satisfy `<u8 as Element<_>>::Array == [u8; 3]`
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | <u16 as Foo<I>>::foo(0u16, b);
|
||||
| +++++++++++++++++++++ ~
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/issue-69683.rs:30:10
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
error[E0284]: type annotations needed: cannot satisfy `<u64 as Rem<_>>::Output == u64`
|
||||
--> $DIR/issue-71584.rs:4:11
|
||||
error[E0284]: type annotations needed
|
||||
--> $DIR/issue-71584.rs:4:15
|
||||
|
|
||||
LL | d = d % n.into();
|
||||
| ^ cannot satisfy `<u64 as Rem<_>>::Output == u64`
|
||||
| - ^^^^
|
||||
| |
|
||||
| type must be known at this point
|
||||
|
|
||||
= note: cannot satisfy `<u64 as Rem<_>>::Output == u64`
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | d = d % <u32 as Into<T>>::into(n);
|
||||
| +++++++++++++++++++++++ ~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error[E0283]: type annotations needed
|
||||
error[E0283]: type annotations needed: cannot satisfy `&'a (): Foo`
|
||||
--> $DIR/issue-34979.rs:6:13
|
||||
|
|
||||
LL | &'a (): Foo,
|
||||
| ^^^ cannot infer type for reference `&'a ()`
|
||||
| ^^^
|
||||
|
|
||||
= note: cannot satisfy `&'a (): Foo`
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error[E0283]: type annotations needed
|
||||
error[E0283]: type annotations needed: cannot satisfy `(&'static (), &'a ()): A`
|
||||
--> $DIR/region-overlap.rs:5:10
|
||||
|
|
||||
LL | impl<'a> A for (&'static (), &'a ()) {}
|
||||
| ^ cannot infer type for tuple `(&'static (), &'a ())`
|
||||
| ^
|
||||
|
|
||||
note: multiple `impl`s satisfying `(&'static (), &'a ()): A` found
|
||||
--> $DIR/region-overlap.rs:5:1
|
||||
|
@ -12,11 +12,11 @@ LL | impl<'a> A for (&'static (), &'a ()) {}
|
|||
LL | impl<'a> A for (&'a (), &'static ()) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
error[E0283]: type annotations needed: cannot satisfy `(&'a (), &'static ()): A`
|
||||
--> $DIR/region-overlap.rs:6:10
|
||||
|
|
||||
LL | impl<'a> A for (&'a (), &'static ()) {}
|
||||
| ^ cannot infer type for tuple `(&'a (), &'static ())`
|
||||
| ^
|
||||
|
|
||||
note: multiple `impl`s satisfying `(&'a (), &'static ()): A` found
|
||||
--> $DIR/region-overlap.rs:5:1
|
||||
|
|
|
@ -5,7 +5,7 @@ trait Foo {}
|
|||
impl<'a, 'b, T> Foo for T
|
||||
where
|
||||
T: FnMut(&'a ()),
|
||||
//~^ ERROR: type annotations needed [E0283]
|
||||
//~^ ERROR: type annotations needed
|
||||
T: FnMut(&'b ()),
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error[E0283]: type annotations needed
|
||||
error[E0283]: type annotations needed: cannot satisfy `T: FnMut<(&'a (),)>`
|
||||
--> $DIR/issue-85735.rs:7:8
|
||||
|
|
||||
LL | T: FnMut(&'a ()),
|
||||
| ^^^^^^^^^^^^^ cannot infer type for type parameter `T`
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: cannot satisfy `T: FnMut<(&'a (),)>`
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error[E0283]: type annotations needed
|
||||
error[E0283]: type annotations needed: cannot satisfy `&'a T: Foo`
|
||||
--> $DIR/issue-40294.rs:6:19
|
||||
|
|
||||
LL | where &'a T : Foo,
|
||||
| ^^^ cannot infer type for reference `&'a T`
|
||||
| ^^^
|
||||
|
|
||||
= note: cannot satisfy `&'a T: Foo`
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue