don't assume trait ambiguity happens in Self

This commit is contained in:
SNCPlay42 2020-10-19 17:42:57 +01:00
parent c38ddb8040
commit 71ca239f80
4 changed files with 113 additions and 34 deletions

View File

@ -1462,9 +1462,8 @@ fn maybe_report_ambiguity(
let bound_predicate = predicate.bound_atom();
let mut err = match bound_predicate.skip_binder() {
ty::PredicateAtom::Trait(data, _) => {
let self_ty = data.trait_ref.self_ty();
let trait_ref = bound_predicate.rebind(data.trait_ref);
debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind(), trait_ref);
debug!("trait_ref {:?}", trait_ref);
if predicate.references_error() {
return;
@ -1479,6 +1478,17 @@ fn maybe_report_ambiguity(
// known, since we don't dispatch based on region
// relationships.
// 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])
};
// This is kind of a hack: it frequently happens that some earlier
// error prevents types from being fully inferred, and then we get
// a bunch of uninteresting errors saying something like "<generic
@ -1495,21 +1505,11 @@ fn maybe_report_ambiguity(
// check upstream for type errors and don't add the obligations to
// begin with in those cases.
if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) {
self.emit_inference_failure_err(
body_id,
span,
self_ty.into(),
ErrorCode::E0282,
)
.emit();
self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0282).emit();
return;
}
let mut err = self.emit_inference_failure_err(
body_id,
span,
self_ty.into(),
ErrorCode::E0283,
);
let mut err =
self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0283);
err.note(&format!("cannot satisfy `{}`", predicate));
if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code {
self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());

View File

@ -2,7 +2,7 @@ error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:7:5
|
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for struct `String`
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
= note: required by `from`
@ -13,11 +13,13 @@ error[E0282]: type annotations needed
LL | |x| String::from("x".as_ref());
| ^ consider giving this closure parameter a type
error[E0283]: type annotations needed
error[E0283]: type annotations needed for `&T`
--> $DIR/issue-72690.rs:15:17
|
LL | let _ = "x".as_ref();
| ^^^^^^ cannot infer type for type `str`
| - ^^^^^^ cannot infer type for type parameter `T` declared on the trait `AsRef`
| |
| consider giving this pattern the explicit type `&T`, where the type parameter `T` is specified
|
= note: cannot satisfy `str: AsRef<_>`
@ -25,7 +27,7 @@ error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:19:5
|
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for struct `String`
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
= note: required by `from`
@ -34,7 +36,7 @@ error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:25:5
|
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for struct `String`
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
= note: required by `from`
@ -43,41 +45,34 @@ error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:33:5
|
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for struct `String`
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
= note: required by `from`
error[E0283]: type annotations needed for `String`
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:41:5
|
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for struct `String`
LL | let _ = String::from("x");
| - consider giving this pattern a type
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
= note: required by `from`
error[E0283]: type annotations needed for `String`
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:47:5
|
LL | let _ = String::from("x");
| - consider giving this pattern a type
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for struct `String`
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
= note: required by `from`
error[E0283]: type annotations needed for `String`
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:55:5
|
LL | let _ = String::from("x");
| - consider giving this pattern a type
...
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for struct `String`
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
= note: required by `from`

View File

@ -0,0 +1,40 @@
use std::collections::HashMap;
fn what() {
let descr = String::new();
let mut opts = HashMap::<String, ()>::new();
let opt = String::new();
opts.get(opt.as_ref()); //~ ERROR type annotations needed
}
fn main() {
let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect();
//~^ ERROR type annotations needed
}
trait Foo<'a, T: ?Sized> {
fn foo(&self) -> Box<T> {
todo!()
}
}
trait Bar<'a, T: ?Sized> {
fn bar(&self) -> Box<T> {
todo!()
}
}
impl Foo<'static, u32> for () {}
impl<'a> Foo<'a, i16> for () {}
impl<'a> Bar<'static, u32> for &'a () {}
impl<'a> Bar<'a, i16> for &'a () {}
fn foo() {
let _ = ().foo(); //~ ERROR type annotations needed
}
fn bar() {
let _ = (&()).bar(); //~ ERROR type annotations needed
}

View File

@ -0,0 +1,44 @@
error[E0283]: type annotations needed
--> $DIR/issue-77982.rs:8:10
|
LL | opts.get(opt.as_ref());
| ^^^ ------------ this method call resolves to `&T`
| |
| cannot infer type for type parameter `Q` declared on the associated function `get`
|
= note: cannot satisfy `String: Borrow<_>`
error[E0283]: type annotations needed
--> $DIR/issue-77982.rs:12:44
|
LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect();
| ^^^^^^^^^ ----------- this method call resolves to `T`
| |
| cannot infer type for type parameter `T` declared on the trait `From`
|
= note: cannot satisfy `u32: From<_>`
= note: required by `from`
error[E0283]: type annotations needed for `Box<T>`
--> $DIR/issue-77982.rs:35:16
|
LL | let _ = ().foo();
| - ^^^ cannot infer type for type parameter `T` declared on the trait `Foo`
| |
| consider giving this pattern the explicit type `Box<T>`, where the type parameter `T` is specified
|
= note: cannot satisfy `(): Foo<'_, _>`
error[E0283]: type annotations needed for `Box<T>`
--> $DIR/issue-77982.rs:39:19
|
LL | let _ = (&()).bar();
| - ^^^ cannot infer type for type parameter `T` declared on the trait `Bar`
| |
| consider giving this pattern the explicit type `Box<T>`, where the type parameter `T` is specified
|
= note: cannot satisfy `&(): Bar<'_, _>`
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0283`.