Skip to content

Commit 71ca239

Browse files
committed
don't assume trait ambiguity happens in Self
1 parent c38ddb8 commit 71ca239

File tree

4 files changed

+113
-34
lines changed

4 files changed

+113
-34
lines changed

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

+15-15
Original file line numberDiff line numberDiff line change
@@ -1462,9 +1462,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
14621462
let bound_predicate = predicate.bound_atom();
14631463
let mut err = match bound_predicate.skip_binder() {
14641464
ty::PredicateAtom::Trait(data, _) => {
1465-
let self_ty = data.trait_ref.self_ty();
14661465
let trait_ref = bound_predicate.rebind(data.trait_ref);
1467-
debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind(), trait_ref);
1466+
debug!("trait_ref {:?}", trait_ref);
14681467

14691468
if predicate.references_error() {
14701469
return;
@@ -1479,6 +1478,17 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
14791478
// known, since we don't dispatch based on region
14801479
// relationships.
14811480

1481+
// Pick the first substitution that still contains inference variables as the one
1482+
// we're going to emit an error for. If there are none (see above), fall back to
1483+
// the substitution for `Self`.
1484+
let subst = {
1485+
let substs = data.trait_ref.substs;
1486+
substs
1487+
.iter()
1488+
.find(|s| s.has_infer_types_or_consts())
1489+
.unwrap_or_else(|| substs[0])
1490+
};
1491+
14821492
// This is kind of a hack: it frequently happens that some earlier
14831493
// error prevents types from being fully inferred, and then we get
14841494
// a bunch of uninteresting errors saying something like "<generic
@@ -1495,21 +1505,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
14951505
// check upstream for type errors and don't add the obligations to
14961506
// begin with in those cases.
14971507
if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) {
1498-
self.emit_inference_failure_err(
1499-
body_id,
1500-
span,
1501-
self_ty.into(),
1502-
ErrorCode::E0282,
1503-
)
1504-
.emit();
1508+
self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0282).emit();
15051509
return;
15061510
}
1507-
let mut err = self.emit_inference_failure_err(
1508-
body_id,
1509-
span,
1510-
self_ty.into(),
1511-
ErrorCode::E0283,
1512-
);
1511+
let mut err =
1512+
self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0283);
15131513
err.note(&format!("cannot satisfy `{}`", predicate));
15141514
if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code {
15151515
self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());

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

+14-19
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0283]: type annotations needed
22
--> $DIR/issue-72690.rs:7:5
33
|
44
LL | String::from("x".as_ref());
5-
| ^^^^^^^^^^^^ cannot infer type for struct `String`
5+
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
66
|
77
= note: cannot satisfy `String: From<&_>`
88
= note: required by `from`
@@ -13,19 +13,21 @@ error[E0282]: type annotations needed
1313
LL | |x| String::from("x".as_ref());
1414
| ^ consider giving this closure parameter a type
1515

16-
error[E0283]: type annotations needed
16+
error[E0283]: type annotations needed for `&T`
1717
--> $DIR/issue-72690.rs:15:17
1818
|
1919
LL | let _ = "x".as_ref();
20-
| ^^^^^^ cannot infer type for type `str`
20+
| - ^^^^^^ cannot infer type for type parameter `T` declared on the trait `AsRef`
21+
| |
22+
| consider giving this pattern the explicit type `&T`, where the type parameter `T` is specified
2123
|
2224
= note: cannot satisfy `str: AsRef<_>`
2325

2426
error[E0283]: type annotations needed
2527
--> $DIR/issue-72690.rs:19:5
2628
|
2729
LL | String::from("x".as_ref());
28-
| ^^^^^^^^^^^^ cannot infer type for struct `String`
30+
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
2931
|
3032
= note: cannot satisfy `String: From<&_>`
3133
= note: required by `from`
@@ -34,7 +36,7 @@ error[E0283]: type annotations needed
3436
--> $DIR/issue-72690.rs:25:5
3537
|
3638
LL | String::from("x".as_ref());
37-
| ^^^^^^^^^^^^ cannot infer type for struct `String`
39+
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
3840
|
3941
= note: cannot satisfy `String: From<&_>`
4042
= note: required by `from`
@@ -43,41 +45,34 @@ error[E0283]: type annotations needed
4345
--> $DIR/issue-72690.rs:33:5
4446
|
4547
LL | String::from("x".as_ref());
46-
| ^^^^^^^^^^^^ cannot infer type for struct `String`
48+
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
4749
|
4850
= note: cannot satisfy `String: From<&_>`
4951
= note: required by `from`
5052

51-
error[E0283]: type annotations needed for `String`
53+
error[E0283]: type annotations needed
5254
--> $DIR/issue-72690.rs:41:5
5355
|
5456
LL | String::from("x".as_ref());
55-
| ^^^^^^^^^^^^ cannot infer type for struct `String`
56-
LL | let _ = String::from("x");
57-
| - consider giving this pattern a type
57+
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
5858
|
5959
= note: cannot satisfy `String: From<&_>`
6060
= note: required by `from`
6161

62-
error[E0283]: type annotations needed for `String`
62+
error[E0283]: type annotations needed
6363
--> $DIR/issue-72690.rs:47:5
6464
|
65-
LL | let _ = String::from("x");
66-
| - consider giving this pattern a type
6765
LL | String::from("x".as_ref());
68-
| ^^^^^^^^^^^^ cannot infer type for struct `String`
66+
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
6967
|
7068
= note: cannot satisfy `String: From<&_>`
7169
= note: required by `from`
7270

73-
error[E0283]: type annotations needed for `String`
71+
error[E0283]: type annotations needed
7472
--> $DIR/issue-72690.rs:55:5
7573
|
76-
LL | let _ = String::from("x");
77-
| - consider giving this pattern a type
78-
...
7974
LL | String::from("x".as_ref());
80-
| ^^^^^^^^^^^^ cannot infer type for struct `String`
75+
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
8176
|
8277
= note: cannot satisfy `String: From<&_>`
8378
= note: required by `from`

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

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
use std::collections::HashMap;
2+
3+
fn what() {
4+
let descr = String::new();
5+
let mut opts = HashMap::<String, ()>::new();
6+
let opt = String::new();
7+
8+
opts.get(opt.as_ref()); //~ ERROR type annotations needed
9+
}
10+
11+
fn main() {
12+
let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect();
13+
//~^ ERROR type annotations needed
14+
}
15+
16+
trait Foo<'a, T: ?Sized> {
17+
fn foo(&self) -> Box<T> {
18+
todo!()
19+
}
20+
}
21+
22+
trait Bar<'a, T: ?Sized> {
23+
fn bar(&self) -> Box<T> {
24+
todo!()
25+
}
26+
}
27+
28+
impl Foo<'static, u32> for () {}
29+
impl<'a> Foo<'a, i16> for () {}
30+
31+
impl<'a> Bar<'static, u32> for &'a () {}
32+
impl<'a> Bar<'a, i16> for &'a () {}
33+
34+
fn foo() {
35+
let _ = ().foo(); //~ ERROR type annotations needed
36+
}
37+
38+
fn bar() {
39+
let _ = (&()).bar(); //~ ERROR type annotations needed
40+
}

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

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
error[E0283]: type annotations needed
2+
--> $DIR/issue-77982.rs:8:10
3+
|
4+
LL | opts.get(opt.as_ref());
5+
| ^^^ ------------ this method call resolves to `&T`
6+
| |
7+
| cannot infer type for type parameter `Q` declared on the associated function `get`
8+
|
9+
= note: cannot satisfy `String: Borrow<_>`
10+
11+
error[E0283]: type annotations needed
12+
--> $DIR/issue-77982.rs:12:44
13+
|
14+
LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect();
15+
| ^^^^^^^^^ ----------- this method call resolves to `T`
16+
| |
17+
| cannot infer type for type parameter `T` declared on the trait `From`
18+
|
19+
= note: cannot satisfy `u32: From<_>`
20+
= note: required by `from`
21+
22+
error[E0283]: type annotations needed for `Box<T>`
23+
--> $DIR/issue-77982.rs:35:16
24+
|
25+
LL | let _ = ().foo();
26+
| - ^^^ cannot infer type for type parameter `T` declared on the trait `Foo`
27+
| |
28+
| consider giving this pattern the explicit type `Box<T>`, where the type parameter `T` is specified
29+
|
30+
= note: cannot satisfy `(): Foo<'_, _>`
31+
32+
error[E0283]: type annotations needed for `Box<T>`
33+
--> $DIR/issue-77982.rs:39:19
34+
|
35+
LL | let _ = (&()).bar();
36+
| - ^^^ cannot infer type for type parameter `T` declared on the trait `Bar`
37+
| |
38+
| consider giving this pattern the explicit type `Box<T>`, where the type parameter `T` is specified
39+
|
40+
= note: cannot satisfy `&(): Bar<'_, _>`
41+
42+
error: aborting due to 4 previous errors
43+
44+
For more information about this error, try `rustc --explain E0283`.

0 commit comments

Comments
 (0)