Skip to content

Commit

Permalink
don't assume trait ambiguity happens in Self
Browse files Browse the repository at this point in the history
  • Loading branch information
SNCPlay42 committed Oct 19, 2020
1 parent c38ddb8 commit 71ca239
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 34 deletions.
30 changes: 15 additions & 15 deletions compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Expand Up @@ -1462,9 +1462,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
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;
Expand All @@ -1479,6 +1478,17 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
// 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
Expand All @@ -1495,21 +1505,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
// 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());
Expand Down
33 changes: 14 additions & 19 deletions src/test/ui/issues/issue-72690.stderr
Expand Up @@ -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`
Expand All @@ -13,19 +13,21 @@ 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<_>`

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`
Expand All @@ -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`
Expand All @@ -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`
Expand Down
40 changes: 40 additions & 0 deletions src/test/ui/traits/issue-77982.rs
@@ -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 changes: 44 additions & 0 deletions src/test/ui/traits/issue-77982.stderr
@@ -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`.

0 comments on commit 71ca239

Please sign in to comment.