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>> {
|
pub fn ty(&self) -> Option<Ty<'tcx>> {
|
||||||
if let Term::Ty(ty) = self { Some(*ty) } else { None }
|
if let Term::Ty(ty) = self { Some(*ty) } else { None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ct(&self) -> Option<Const<'tcx>> {
|
pub fn ct(&self) -> Option<Const<'tcx>> {
|
||||||
if let Term::Const(c) = self { Some(*c) } else { None }
|
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
|
/// 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
|
// 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
|
// we're going to emit an error for. If there are none (see above), fall back to
|
||||||
// the substitution for `Self`.
|
// a more general error.
|
||||||
let subst = {
|
let subst = data.trait_ref.substs.iter().find(|s| s.has_infer_types_or_consts());
|
||||||
let substs = data.trait_ref.substs;
|
|
||||||
substs
|
let mut err = if let Some(subst) = subst {
|
||||||
.iter()
|
let impl_candidates = self
|
||||||
.find(|s| s.has_infer_types_or_consts())
|
.find_similar_impl_candidates(trait_ref)
|
||||||
.unwrap_or_else(|| substs[0])
|
.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
|
// 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(
|
self.emit_inference_failure_err(
|
||||||
body_id,
|
body_id,
|
||||||
span,
|
span,
|
||||||
subst,
|
trait_ref.self_ty().skip_binder().into(),
|
||||||
vec![],
|
vec![],
|
||||||
ErrorCode::E0282,
|
ErrorCode::E0282,
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
|
err.cancel();
|
||||||
return;
|
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(
|
let obligation = Obligation::new(
|
||||||
obligation.cause.clone(),
|
obligation.cause.clone(),
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
|
@ -2136,17 +2141,20 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Projection(data) => {
|
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() {
|
if predicate.references_error() || self.is_tainted_by_errors() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if self_ty.needs_infer() && term.needs_infer() {
|
let subst = data
|
||||||
// We do this for the `foo.collect()?` case to produce a suggestion.
|
.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(
|
let mut err = self.emit_inference_failure_err(
|
||||||
body_id,
|
body_id,
|
||||||
span,
|
span,
|
||||||
self_ty.into(),
|
subst,
|
||||||
vec![],
|
vec![],
|
||||||
ErrorCode::E0284,
|
ErrorCode::E0284,
|
||||||
true,
|
true,
|
||||||
|
@ -2154,6 +2162,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
err.note(&format!("cannot satisfy `{}`", predicate));
|
err.note(&format!("cannot satisfy `{}`", predicate));
|
||||||
err
|
err
|
||||||
} else {
|
} else {
|
||||||
|
// If we can't find a substitution, just print a generic error
|
||||||
let mut err = struct_span_err!(
|
let mut err = struct_span_err!(
|
||||||
self.tcx.sess,
|
self.tcx.sess,
|
||||||
span,
|
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
|
--> $DIR/coherence-overlap-trait-alias.rs:15:6
|
||||||
|
|
|
|
||||||
LL | impl C for u32 {}
|
LL | impl C for u32 {}
|
||||||
| ^ cannot infer type for type `u32`
|
| ^
|
||||||
|
|
|
|
||||||
note: multiple `impl`s satisfying `u32: C` found
|
note: multiple `impl`s satisfying `u32: C` found
|
||||||
--> $DIR/coherence-overlap-trait-alias.rs:14:1
|
--> $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: const parameters may only be used as standalone arguments, i.e. `J`
|
||||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
= 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
|
--> $DIR/issue-72787.rs:21:26
|
||||||
|
|
|
|
||||||
LL | IsLessOrEqual<I, 8>: True,
|
LL | IsLessOrEqual<I, 8>: True,
|
||||||
| ^^^^ cannot infer type for struct `IsLessOrEqual<I, 8_u32>`
|
| ^^^^
|
||||||
|
|
|
|
||||||
= note: cannot satisfy `IsLessOrEqual<I, 8_u32>: True`
|
= 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
|
--> $DIR/issue-72787.rs:21:26
|
||||||
|
|
|
|
||||||
LL | IsLessOrEqual<I, 8>: True,
|
LL | IsLessOrEqual<I, 8>: True,
|
||||||
| ^^^^ cannot infer type for struct `IsLessOrEqual<I, 8_u32>`
|
| ^^^^
|
||||||
|
|
|
|
||||||
= note: cannot satisfy `IsLessOrEqual<I, 8_u32>: True`
|
= 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>
|
impl<const I: u32, const J: u32> S<I, J>
|
||||||
where
|
where
|
||||||
IsLessOrEqual<I, 8>: True,
|
IsLessOrEqual<I, 8>: True,
|
||||||
//[min]~^ Error type annotations needed [E0283]
|
//[min]~^ Error type annotations needed
|
||||||
//[min]~| Error type annotations needed [E0283]
|
//[min]~| Error type annotations needed
|
||||||
IsLessOrEqual<J, 8>: True,
|
IsLessOrEqual<J, 8>: True,
|
||||||
IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
|
IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
|
||||||
//[min]~^ Error generic parameters may not be used in const operations
|
//[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
|
--> $DIR/issue-12028.rs:27:14
|
||||||
|
|
|
|
||||||
LL | self.input_stream(&mut stream);
|
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
|
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
|
--> $DIR/issue-21974.rs:11:19
|
||||||
|
|
|
|
||||||
LL | where &'a T : Foo,
|
LL | where &'a T : Foo,
|
||||||
| ^^^ cannot infer type for reference `&'a T`
|
| ^^^
|
||||||
|
|
|
|
||||||
= note: cannot satisfy `&'a T: Foo`
|
= 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
|
--> $DIR/issue-24424.rs:4:57
|
||||||
|
|
|
|
||||||
LL | impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {}
|
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>`
|
= 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
|
--> $DIR/issue-69683.rs:30:10
|
||||||
|
|
|
|
||||||
LL | 0u16.foo(b);
|
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
|
error[E0283]: type annotations needed
|
||||||
--> $DIR/issue-69683.rs:30:10
|
--> $DIR/issue-69683.rs:30:10
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
error[E0284]: type annotations needed: cannot satisfy `<u64 as Rem<_>>::Output == u64`
|
error[E0284]: type annotations needed
|
||||||
--> $DIR/issue-71584.rs:4:11
|
--> $DIR/issue-71584.rs:4:15
|
||||||
|
|
|
|
||||||
LL | d = d % n.into();
|
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
|
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
|
--> $DIR/issue-34979.rs:6:13
|
||||||
|
|
|
|
||||||
LL | &'a (): Foo,
|
LL | &'a (): Foo,
|
||||||
| ^^^ cannot infer type for reference `&'a ()`
|
| ^^^
|
||||||
|
|
|
|
||||||
= note: cannot satisfy `&'a (): Foo`
|
= 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
|
--> $DIR/region-overlap.rs:5:10
|
||||||
|
|
|
|
||||||
LL | impl<'a> A for (&'static (), &'a ()) {}
|
LL | impl<'a> A for (&'static (), &'a ()) {}
|
||||||
| ^ cannot infer type for tuple `(&'static (), &'a ())`
|
| ^
|
||||||
|
|
|
|
||||||
note: multiple `impl`s satisfying `(&'static (), &'a ()): A` found
|
note: multiple `impl`s satisfying `(&'static (), &'a ()): A` found
|
||||||
--> $DIR/region-overlap.rs:5:1
|
--> $DIR/region-overlap.rs:5:1
|
||||||
|
@ -12,11 +12,11 @@ LL | impl<'a> A for (&'static (), &'a ()) {}
|
||||||
LL | impl<'a> A for (&'a (), &'static ()) {}
|
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
|
--> $DIR/region-overlap.rs:6:10
|
||||||
|
|
|
|
||||||
LL | impl<'a> A for (&'a (), &'static ()) {}
|
LL | impl<'a> A for (&'a (), &'static ()) {}
|
||||||
| ^ cannot infer type for tuple `(&'a (), &'static ())`
|
| ^
|
||||||
|
|
|
|
||||||
note: multiple `impl`s satisfying `(&'a (), &'static ()): A` found
|
note: multiple `impl`s satisfying `(&'a (), &'static ()): A` found
|
||||||
--> $DIR/region-overlap.rs:5:1
|
--> $DIR/region-overlap.rs:5:1
|
||||||
|
|
|
@ -5,7 +5,7 @@ trait Foo {}
|
||||||
impl<'a, 'b, T> Foo for T
|
impl<'a, 'b, T> Foo for T
|
||||||
where
|
where
|
||||||
T: FnMut(&'a ()),
|
T: FnMut(&'a ()),
|
||||||
//~^ ERROR: type annotations needed [E0283]
|
//~^ ERROR: type annotations needed
|
||||||
T: FnMut(&'b ()),
|
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
|
--> $DIR/issue-85735.rs:7:8
|
||||||
|
|
|
|
||||||
LL | T: FnMut(&'a ()),
|
LL | T: FnMut(&'a ()),
|
||||||
| ^^^^^^^^^^^^^ cannot infer type for type parameter `T`
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: cannot satisfy `T: FnMut<(&'a (),)>`
|
= 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
|
--> $DIR/issue-40294.rs:6:19
|
||||||
|
|
|
|
||||||
LL | where &'a T : Foo,
|
LL | where &'a T : Foo,
|
||||||
| ^^^ cannot infer type for reference `&'a T`
|
| ^^^
|
||||||
|
|
|
|
||||||
= note: cannot satisfy `&'a T: Foo`
|
= note: cannot satisfy `&'a T: Foo`
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue