1
Fork 0

Don't point at Self type if we can't find an infer variable in ambiguous trait predicate

This commit is contained in:
Michael Goulet 2022-06-25 10:42:23 -07:00
parent ca0105ba4e
commit 12ab6bfafd
15 changed files with 94 additions and 57 deletions

View file

@ -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

View file

@ -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,

View file

@ -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

View file

@ -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`

View file

@ -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

View file

@ -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

View file

@ -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`

View file

@ -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>`

View file

@ -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

View file

@ -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

View file

@ -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`

View file

@ -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

View file

@ -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 ()),
{
}

View file

@ -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 (),)>`

View file

@ -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`