don't assume trait ambiguity happens in Self
This commit is contained in:
parent
c38ddb8040
commit
71ca239f80
@ -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());
|
||||
|
@ -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`
|
||||
|
40
src/test/ui/traits/issue-77982.rs
Normal file
40
src/test/ui/traits/issue-77982.rs
Normal 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
|
||||
}
|
44
src/test/ui/traits/issue-77982.stderr
Normal file
44
src/test/ui/traits/issue-77982.stderr
Normal 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`.
|
Loading…
Reference in New Issue
Block a user