Skip to content

Commit 12ab6bf

Browse files
Don't point at Self type if we can't find an infer variable in ambiguous trait predicate
1 parent ca0105b commit 12ab6bf

File tree

15 files changed

+94
-57
lines changed

15 files changed

+94
-57
lines changed

compiler/rustc_middle/src/ty/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -914,9 +914,17 @@ impl<'tcx> Term<'tcx> {
914914
pub fn ty(&self) -> Option<Ty<'tcx>> {
915915
if let Term::Ty(ty) = self { Some(*ty) } else { None }
916916
}
917+
917918
pub fn ct(&self) -> Option<Const<'tcx>> {
918919
if let Term::Const(c) = self { Some(*c) } else { None }
919920
}
921+
922+
pub fn into_arg(self) -> GenericArg<'tcx> {
923+
match self {
924+
Term::Ty(ty) => ty.into(),
925+
Term::Const(c) => c.into(),
926+
}
927+
}
920928
}
921929

922930
/// This kind of predicate has no *direct* correspondent in the

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+36-27
Original file line numberDiff line numberDiff line change
@@ -1970,13 +1970,31 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
19701970

19711971
// Pick the first substitution that still contains inference variables as the one
19721972
// we're going to emit an error for. If there are none (see above), fall back to
1973-
// the substitution for `Self`.
1974-
let subst = {
1975-
let substs = data.trait_ref.substs;
1976-
substs
1977-
.iter()
1978-
.find(|s| s.has_infer_types_or_consts())
1979-
.unwrap_or_else(|| substs[0])
1973+
// a more general error.
1974+
let subst = data.trait_ref.substs.iter().find(|s| s.has_infer_types_or_consts());
1975+
1976+
let mut err = if let Some(subst) = subst {
1977+
let impl_candidates = self
1978+
.find_similar_impl_candidates(trait_ref)
1979+
.into_iter()
1980+
.map(|candidate| candidate.trait_ref)
1981+
.collect();
1982+
self.emit_inference_failure_err(
1983+
body_id,
1984+
span,
1985+
subst,
1986+
impl_candidates,
1987+
ErrorCode::E0283,
1988+
true,
1989+
)
1990+
} else {
1991+
struct_span_err!(
1992+
self.tcx.sess,
1993+
span,
1994+
E0283,
1995+
"type annotations needed: cannot satisfy `{}`",
1996+
predicate,
1997+
)
19801998
};
19811999

19822000
// 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> {
19992017
self.emit_inference_failure_err(
20002018
body_id,
20012019
span,
2002-
subst,
2020+
trait_ref.self_ty().skip_binder().into(),
20032021
vec![],
20042022
ErrorCode::E0282,
20052023
false,
20062024
)
20072025
.emit();
20082026
}
2027+
err.cancel();
20092028
return;
20102029
}
20112030

2012-
let impl_candidates = self
2013-
.find_similar_impl_candidates(trait_ref)
2014-
.into_iter()
2015-
.map(|candidate| candidate.trait_ref)
2016-
.collect();
2017-
let mut err = self.emit_inference_failure_err(
2018-
body_id,
2019-
span,
2020-
subst,
2021-
impl_candidates,
2022-
ErrorCode::E0283,
2023-
true,
2024-
);
2025-
20262031
let obligation = Obligation::new(
20272032
obligation.cause.clone(),
20282033
obligation.param_env,
@@ -2136,24 +2141,28 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
21362141
)
21372142
}
21382143
ty::PredicateKind::Projection(data) => {
2139-
let self_ty = data.projection_ty.self_ty();
2140-
let term = data.term;
21412144
if predicate.references_error() || self.is_tainted_by_errors() {
21422145
return;
21432146
}
2144-
if self_ty.needs_infer() && term.needs_infer() {
2145-
// We do this for the `foo.collect()?` case to produce a suggestion.
2147+
let subst = data
2148+
.projection_ty
2149+
.substs
2150+
.iter()
2151+
.chain(Some(data.term.into_arg()))
2152+
.find(|g| g.has_infer_types_or_consts());
2153+
if let Some(subst) = subst {
21462154
let mut err = self.emit_inference_failure_err(
21472155
body_id,
21482156
span,
2149-
self_ty.into(),
2157+
subst,
21502158
vec![],
21512159
ErrorCode::E0284,
21522160
true,
21532161
);
21542162
err.note(&format!("cannot satisfy `{}`", predicate));
21552163
err
21562164
} else {
2165+
// If we can't find a substitution, just print a generic error
21572166
let mut err = struct_span_err!(
21582167
self.tcx.sess,
21592168
span,

src/test/ui/coherence/coherence-overlap-trait-alias.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0283]: type annotations needed
1+
error[E0283]: type annotations needed: cannot satisfy `u32: C`
22
--> $DIR/coherence-overlap-trait-alias.rs:15:6
33
|
44
LL | impl C for u32 {}
5-
| ^ cannot infer type for type `u32`
5+
| ^
66
|
77
note: multiple `impl`s satisfying `u32: C` found
88
--> $DIR/coherence-overlap-trait-alias.rs:14:1

src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,19 @@ LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
3434
= help: const parameters may only be used as standalone arguments, i.e. `J`
3535
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
3636

37-
error[E0283]: type annotations needed
37+
error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual<I, 8_u32>: True`
3838
--> $DIR/issue-72787.rs:21:26
3939
|
4040
LL | IsLessOrEqual<I, 8>: True,
41-
| ^^^^ cannot infer type for struct `IsLessOrEqual<I, 8_u32>`
41+
| ^^^^
4242
|
4343
= note: cannot satisfy `IsLessOrEqual<I, 8_u32>: True`
4444

45-
error[E0283]: type annotations needed
45+
error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual<I, 8_u32>: True`
4646
--> $DIR/issue-72787.rs:21:26
4747
|
4848
LL | IsLessOrEqual<I, 8>: True,
49-
| ^^^^ cannot infer type for struct `IsLessOrEqual<I, 8_u32>`
49+
| ^^^^
5050
|
5151
= note: cannot satisfy `IsLessOrEqual<I, 8_u32>: True`
5252

src/test/ui/const-generics/generic_const_exprs/issue-72787.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ struct S<const I: u32, const J: u32>;
1919
impl<const I: u32, const J: u32> S<I, J>
2020
where
2121
IsLessOrEqual<I, 8>: True,
22-
//[min]~^ Error type annotations needed [E0283]
23-
//[min]~| Error type annotations needed [E0283]
22+
//[min]~^ Error type annotations needed
23+
//[min]~| Error type annotations needed
2424
IsLessOrEqual<J, 8>: True,
2525
IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
2626
//[min]~^ Error generic parameters may not be used in const operations

src/test/ui/issues/issue-12028.stderr

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1-
error[E0284]: type annotations needed: cannot satisfy `<_ as StreamHasher>::S == <H as StreamHasher>::S`
1+
error[E0284]: type annotations needed
22
--> $DIR/issue-12028.rs:27:14
33
|
44
LL | self.input_stream(&mut stream);
5-
| ^^^^^^^^^^^^ cannot satisfy `<_ as StreamHasher>::S == <H as StreamHasher>::S`
5+
| ^^^^^^^^^^^^
6+
|
7+
= note: cannot satisfy `<_ as StreamHasher>::S == <H as StreamHasher>::S`
8+
help: try using a fully qualified path to specify the expected types
9+
|
10+
LL | <u8 as StreamHash<H>>::input_stream(self, &mut stream);
11+
| ++++++++++++++++++++++++++++++++++++ ~
612

713
error: aborting due to previous error
814

src/test/ui/issues/issue-21974.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0283]: type annotations needed
1+
error[E0283]: type annotations needed: cannot satisfy `&'a T: Foo`
22
--> $DIR/issue-21974.rs:11:19
33
|
44
LL | where &'a T : Foo,
5-
| ^^^ cannot infer type for reference `&'a T`
5+
| ^^^
66
|
77
= note: cannot satisfy `&'a T: Foo`
88

src/test/ui/issues/issue-24424.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0283]: type annotations needed
1+
error[E0283]: type annotations needed: cannot satisfy `T0: Trait0<'l0>`
22
--> $DIR/issue-24424.rs:4:57
33
|
44
LL | impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {}
5-
| ^^^^^^^^^^^ cannot infer type for type parameter `T0`
5+
| ^^^^^^^^^^^
66
|
77
= note: cannot satisfy `T0: Trait0<'l0>`
88

src/test/ui/issues/issue-69683.stderr

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1-
error[E0284]: type annotations needed: cannot satisfy `<u8 as Element<_>>::Array == [u8; 3]`
1+
error[E0284]: type annotations needed
22
--> $DIR/issue-69683.rs:30:10
33
|
44
LL | 0u16.foo(b);
5-
| ^^^ cannot satisfy `<u8 as Element<_>>::Array == [u8; 3]`
5+
| ^^^
6+
|
7+
= note: cannot satisfy `<u8 as Element<_>>::Array == [u8; 3]`
8+
help: try using a fully qualified path to specify the expected types
9+
|
10+
LL | <u16 as Foo<I>>::foo(0u16, b);
11+
| +++++++++++++++++++++ ~
612

713
error[E0283]: type annotations needed
814
--> $DIR/issue-69683.rs:30:10

src/test/ui/issues/issue-71584.stderr

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
1-
error[E0284]: type annotations needed: cannot satisfy `<u64 as Rem<_>>::Output == u64`
2-
--> $DIR/issue-71584.rs:4:11
1+
error[E0284]: type annotations needed
2+
--> $DIR/issue-71584.rs:4:15
33
|
44
LL | d = d % n.into();
5-
| ^ cannot satisfy `<u64 as Rem<_>>::Output == u64`
5+
| - ^^^^
6+
| |
7+
| type must be known at this point
8+
|
9+
= note: cannot satisfy `<u64 as Rem<_>>::Output == u64`
10+
help: try using a fully qualified path to specify the expected types
11+
|
12+
LL | d = d % <u32 as Into<T>>::into(n);
13+
| +++++++++++++++++++++++ ~
614

715
error: aborting due to previous error
816

src/test/ui/lifetimes/issue-34979.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0283]: type annotations needed
1+
error[E0283]: type annotations needed: cannot satisfy `&'a (): Foo`
22
--> $DIR/issue-34979.rs:6:13
33
|
44
LL | &'a (): Foo,
5-
| ^^^ cannot infer type for reference `&'a ()`
5+
| ^^^
66
|
77
= note: cannot satisfy `&'a (): Foo`
88

src/test/ui/marker_trait_attr/region-overlap.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0283]: type annotations needed
1+
error[E0283]: type annotations needed: cannot satisfy `(&'static (), &'a ()): A`
22
--> $DIR/region-overlap.rs:5:10
33
|
44
LL | impl<'a> A for (&'static (), &'a ()) {}
5-
| ^ cannot infer type for tuple `(&'static (), &'a ())`
5+
| ^
66
|
77
note: multiple `impl`s satisfying `(&'static (), &'a ()): A` found
88
--> $DIR/region-overlap.rs:5:1
@@ -12,11 +12,11 @@ LL | impl<'a> A for (&'static (), &'a ()) {}
1212
LL | impl<'a> A for (&'a (), &'static ()) {}
1313
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1414

15-
error[E0283]: type annotations needed
15+
error[E0283]: type annotations needed: cannot satisfy `(&'a (), &'static ()): A`
1616
--> $DIR/region-overlap.rs:6:10
1717
|
1818
LL | impl<'a> A for (&'a (), &'static ()) {}
19-
| ^ cannot infer type for tuple `(&'a (), &'static ())`
19+
| ^
2020
|
2121
note: multiple `impl`s satisfying `(&'a (), &'static ()): A` found
2222
--> $DIR/region-overlap.rs:5:1

src/test/ui/traits/issue-85735.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ trait Foo {}
55
impl<'a, 'b, T> Foo for T
66
where
77
T: FnMut(&'a ()),
8-
//~^ ERROR: type annotations needed [E0283]
8+
//~^ ERROR: type annotations needed
99
T: FnMut(&'b ()),
1010
{
1111
}

src/test/ui/traits/issue-85735.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0283]: type annotations needed
1+
error[E0283]: type annotations needed: cannot satisfy `T: FnMut<(&'a (),)>`
22
--> $DIR/issue-85735.rs:7:8
33
|
44
LL | T: FnMut(&'a ()),
5-
| ^^^^^^^^^^^^^ cannot infer type for type parameter `T`
5+
| ^^^^^^^^^^^^^
66
|
77
= note: cannot satisfy `T: FnMut<(&'a (),)>`
88

src/test/ui/type/type-check/issue-40294.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0283]: type annotations needed
1+
error[E0283]: type annotations needed: cannot satisfy `&'a T: Foo`
22
--> $DIR/issue-40294.rs:6:19
33
|
44
LL | where &'a T : Foo,
5-
| ^^^ cannot infer type for reference `&'a T`
5+
| ^^^
66
|
77
= note: cannot satisfy `&'a T: Foo`
88

0 commit comments

Comments
 (0)