Skip to content

Commit

Permalink
Point at impl and type defs introducing requirements on E0277
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Apr 7, 2021
1 parent d326c21 commit 8bc5581
Show file tree
Hide file tree
Showing 55 changed files with 621 additions and 110 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/mod.rs
Expand Up @@ -1598,7 +1598,7 @@ impl<'tcx> TyCtxt<'tcx> {
.filter(|item| item.kind == AssocKind::Fn && item.defaultness.has_value())
}

fn item_name_from_hir(self, def_id: DefId) -> Option<Ident> {
pub fn item_name_from_hir(self, def_id: DefId) -> Option<Ident> {
self.hir().get_if_local(def_id).and_then(|node| node.ident())
}

Expand Down
Expand Up @@ -2070,7 +2070,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {

// Don't print the tuple of capture types
if !is_upvar_tys_infer_tuple {
err.note(&format!("required because it appears within the type `{}`", ty));
let msg = format!("required because it appears within the type `{}`", ty);
match ty.kind() {
ty::Adt(def, _) => match self.tcx.item_name_from_hir(def.did) {
Some(ident) => err.span_note(ident.span, &msg),
None => err.note(&msg),
},
_ => err.note(&msg),
};
}

obligated_types.push(ty);
Expand All @@ -2092,11 +2099,36 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
ObligationCauseCode::ImplDerivedObligation(ref data) => {
let mut parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_ref);
let parent_def_id = parent_trait_ref.def_id();
err.note(&format!(
let msg = format!(
"required because of the requirements on the impl of `{}` for `{}`",
parent_trait_ref.print_only_trait_path(),
parent_trait_ref.skip_binder().self_ty()
));
);
let mut candidates = vec![];
self.tcx.for_each_relevant_impl(
parent_def_id,
parent_trait_ref.self_ty().skip_binder(),
|impl_def_id| {
candidates.push(impl_def_id);
},
);
match &candidates[..] {
[def_id] => match self.tcx.hir().get_if_local(*def_id) {
Some(Node::Item(hir::Item {
kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
..
})) => {
let mut spans = Vec::with_capacity(2);
if let Some(trait_ref) = of_trait {
spans.push(trait_ref.path.span);
}
spans.push(self_ty.span);
err.span_note(spans, &msg)
}
_ => err.note(&msg),
},
_ => err.note(&msg),
};

let mut parent_predicate = parent_trait_ref.without_const().to_predicate(tcx);
let mut data = data;
Expand Down
18 changes: 15 additions & 3 deletions src/test/ui/associated-types/impl-wf-cycle-1.stderr
Expand Up @@ -10,7 +10,11 @@ LL | |
LL | | }
| |_^
|
= note: required because of the requirements on the impl of `Grault` for `(T,)`
note: required because of the requirements on the impl of `Grault` for `(T,)`
--> $DIR/impl-wf-cycle-1.rs:15:17
|
LL | impl<T: Grault> Grault for (T,)
| ^^^^^^ ^^^^
= note: 1 redundant requirements hidden
= note: required because of the requirements on the impl of `Grault` for `(T,)`

Expand All @@ -20,7 +24,11 @@ error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
LL | type A = ();
| ^^^^^^^^^^^^
|
= note: required because of the requirements on the impl of `Grault` for `(T,)`
note: required because of the requirements on the impl of `Grault` for `(T,)`
--> $DIR/impl-wf-cycle-1.rs:15:17
|
LL | impl<T: Grault> Grault for (T,)
| ^^^^^^ ^^^^
= note: 1 redundant requirements hidden
= note: required because of the requirements on the impl of `Grault` for `(T,)`

Expand All @@ -30,7 +38,11 @@ error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
LL | type B = bool;
| ^^^^^^^^^^^^^^
|
= note: required because of the requirements on the impl of `Grault` for `(T,)`
note: required because of the requirements on the impl of `Grault` for `(T,)`
--> $DIR/impl-wf-cycle-1.rs:15:17
|
LL | impl<T: Grault> Grault for (T,)
| ^^^^^^ ^^^^
= note: 1 redundant requirements hidden
= note: required because of the requirements on the impl of `Grault` for `(T,)`

Expand Down
12 changes: 10 additions & 2 deletions src/test/ui/associated-types/impl-wf-cycle-2.stderr
Expand Up @@ -10,15 +10,23 @@ LL | |
LL | | }
| |_^
|
= note: required because of the requirements on the impl of `Grault` for `(T,)`
note: required because of the requirements on the impl of `Grault` for `(T,)`
--> $DIR/impl-wf-cycle-2.rs:7:17
|
LL | impl<T: Grault> Grault for (T,)
| ^^^^^^ ^^^^

error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
--> $DIR/impl-wf-cycle-2.rs:11:5
|
LL | type A = ();
| ^^^^^^^^^^^^
|
= note: required because of the requirements on the impl of `Grault` for `(T,)`
note: required because of the requirements on the impl of `Grault` for `(T,)`
--> $DIR/impl-wf-cycle-2.rs:7:17
|
LL | impl<T: Grault> Grault for (T,)
| ^^^^^^ ^^^^

error: aborting due to 2 previous errors

Expand Down
6 changes: 5 additions & 1 deletion src/test/ui/associated-types/issue-44153.stderr
Expand Up @@ -7,7 +7,11 @@ LL | fn visit() {}
LL | <() as Visit>::visit();
| ^^^^^^^^^^^^^^^^^^^^ expected `&()`, found `()`
|
= note: required because of the requirements on the impl of `Visit` for `()`
note: required because of the requirements on the impl of `Visit` for `()`
--> $DIR/issue-44153.rs:13:10
|
LL | impl<'a> Visit for () where
| ^^^^^ ^^

error: aborting due to previous error

Expand Down
6 changes: 5 additions & 1 deletion src/test/ui/associated-types/issue-65774-1.stderr
Expand Up @@ -13,7 +13,11 @@ error[E0277]: the trait bound `T: MyDisplay` is not satisfied
LL | let closure = |config: &mut <S as MPU>::MpuConfig| writer.my_write(&config);
| ^^^^^^^ the trait `MyDisplay` is not implemented for `T`
|
= note: required because of the requirements on the impl of `MyDisplay` for `&mut T`
note: required because of the requirements on the impl of `MyDisplay` for `&mut T`
--> $DIR/issue-65774-1.rs:5:24
|
LL | impl<'a, T: MyDisplay> MyDisplay for &'a mut T { }
| ^^^^^^^^^ ^^^^^^^^^
= note: required for the cast to the object type `dyn MyDisplay`

error: aborting due to 2 previous errors
Expand Down
6 changes: 5 additions & 1 deletion src/test/ui/async-await/issue-72590-type-error-sized.stderr
Expand Up @@ -17,7 +17,11 @@ LL | async fn frob(self) {}
| ^^^^ doesn't have a size known at compile-time
|
= help: within `Foo`, the trait `Sized` is not implemented for `str`
= note: required because it appears within the type `Foo`
note: required because it appears within the type `Foo`
--> $DIR/issue-72590-type-error-sized.rs:5:8
|
LL | struct Foo {
| ^^^
= help: unsized fn params are gated as an unstable feature
help: function arguments must have a statically known size, borrowed types always have a known size
|
Expand Down
48 changes: 48 additions & 0 deletions src/test/ui/async-await/pin-needed-to-poll-2.rs
@@ -0,0 +1,48 @@
use std::{
future::Future,
pin::Pin,
marker::Unpin,
task::{Context, Poll},
};

struct Sleep(std::marker::PhantomPinned);

impl Future for Sleep {
type Output = ();

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Poll::Ready(())
}
}

impl Drop for Sleep {
fn drop(&mut self) {}
}

fn sleep() -> Sleep {
Sleep(std::marker::PhantomPinned)
}


struct MyFuture {
sleep: Sleep,
}

impl MyFuture {
fn new() -> Self {
Self {
sleep: sleep(),
}
}
}

impl Future for MyFuture {
type Output = ();

fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Pin::new(&mut self.sleep).poll(cx)
//~^ ERROR `PhantomPinned` cannot be unpinned
}
}

fn main() {}
16 changes: 16 additions & 0 deletions src/test/ui/async-await/pin-needed-to-poll-2.stderr
@@ -0,0 +1,16 @@
error[E0277]: `PhantomPinned` cannot be unpinned
--> $DIR/pin-needed-to-poll-2.rs:43:9
|
LL | Pin::new(&mut self.sleep).poll(cx)
| ^^^^^^^^ within `Sleep`, the trait `Unpin` is not implemented for `PhantomPinned`
|
note: required because it appears within the type `Sleep`
--> $DIR/pin-needed-to-poll-2.rs:8:8
|
LL | struct Sleep(std::marker::PhantomPinned);
| ^^^^^
= note: required by `Pin::<P>::new`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
6 changes: 5 additions & 1 deletion src/test/ui/block-result/issue-22645.stderr
Expand Up @@ -6,7 +6,11 @@ LL | b + 3
|
= help: the following implementations were found:
<f64 as Scalar>
= note: required because of the requirements on the impl of `Add<{integer}>` for `Bob`
note: required because of the requirements on the impl of `Add<{integer}>` for `Bob`
--> $DIR/issue-22645.rs:8:19
|
LL | impl<RHS: Scalar> Add <RHS> for Bob {
| ^^^^^^^^^ ^^^

error[E0308]: mismatched types
--> $DIR/issue-22645.rs:15:3
Expand Down
Expand Up @@ -9,7 +9,11 @@ LL | impl <T:Sync+'static> RequiresRequiresShareAndSend for X<T> { }
LL | pub trait RequiresRequiresShareAndSend : RequiresShare + Send { }
| ---- required by this bound in `RequiresRequiresShareAndSend`
|
= note: required because it appears within the type `X<T>`
note: required because it appears within the type `X<T>`
--> $DIR/builtin-superkinds-in-metadata.rs:9:8
|
LL | struct X<T>(T);
| ^
help: consider further restricting this bound
|
LL | impl <T:Sync+'static + std::marker::Send> RequiresRequiresShareAndSend for X<T> { }
Expand Down
60 changes: 50 additions & 10 deletions src/test/ui/did_you_mean/recursion_limit.stderr
Expand Up @@ -8,16 +8,56 @@ LL | is_send::<A>();
| ^^^^^^^^^^^^
|
= help: consider adding a `#![recursion_limit="20"]` attribute to your crate (`recursion_limit`)
= note: required because it appears within the type `J`
= note: required because it appears within the type `I`
= note: required because it appears within the type `H`
= note: required because it appears within the type `G`
= note: required because it appears within the type `F`
= note: required because it appears within the type `E`
= note: required because it appears within the type `D`
= note: required because it appears within the type `C`
= note: required because it appears within the type `B`
= note: required because it appears within the type `A`
note: required because it appears within the type `J`
--> $DIR/recursion_limit.rs:24:9
|
LL | link! { J, K }
| ^
note: required because it appears within the type `I`
--> $DIR/recursion_limit.rs:23:9
|
LL | link! { I, J }
| ^
note: required because it appears within the type `H`
--> $DIR/recursion_limit.rs:22:9
|
LL | link! { H, I }
| ^
note: required because it appears within the type `G`
--> $DIR/recursion_limit.rs:21:9
|
LL | link! { G, H }
| ^
note: required because it appears within the type `F`
--> $DIR/recursion_limit.rs:20:9
|
LL | link! { F, G }
| ^
note: required because it appears within the type `E`
--> $DIR/recursion_limit.rs:19:9
|
LL | link! { E, F }
| ^
note: required because it appears within the type `D`
--> $DIR/recursion_limit.rs:18:9
|
LL | link! { D, E }
| ^
note: required because it appears within the type `C`
--> $DIR/recursion_limit.rs:17:9
|
LL | link! { C, D }
| ^
note: required because it appears within the type `B`
--> $DIR/recursion_limit.rs:16:9
|
LL | link! { B, C }
| ^
note: required because it appears within the type `A`
--> $DIR/recursion_limit.rs:15:9
|
LL | link! { A, B }
| ^

error: aborting due to previous error

Expand Down
12 changes: 10 additions & 2 deletions src/test/ui/dst/dst-bad-deep.stderr
Expand Up @@ -5,8 +5,16 @@ LL | let h: &Fat<Fat<[isize]>> = &Fat { ptr: *g };
| ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `Fat<Fat<[isize]>>`, the trait `Sized` is not implemented for `[isize]`
= note: required because it appears within the type `Fat<[isize]>`
= note: required because it appears within the type `Fat<Fat<[isize]>>`
note: required because it appears within the type `Fat<[isize]>`
--> $DIR/dst-bad-deep.rs:6:8
|
LL | struct Fat<T: ?Sized> {
| ^^^
note: required because it appears within the type `Fat<Fat<[isize]>>`
--> $DIR/dst-bad-deep.rs:6:8
|
LL | struct Fat<T: ?Sized> {
| ^^^
= note: structs must have a statically known size to be initialized

error: aborting due to previous error
Expand Down
6 changes: 5 additions & 1 deletion src/test/ui/error-codes/E0275.stderr
Expand Up @@ -8,7 +8,11 @@ LL | impl<T> Foo for T where Bar<T>: Foo {}
| ^^^
|
= help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`E0275`)
= note: required because of the requirements on the impl of `Foo` for `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
note: required because of the requirements on the impl of `Foo` for `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
--> $DIR/E0275.rs:5:9
|
LL | impl<T> Foo for T where Bar<T>: Foo {}
| ^^^ ^
= note: 127 redundant requirements hidden
= note: required because of the requirements on the impl of `Foo` for `Bar<T>`

Expand Down
18 changes: 15 additions & 3 deletions src/test/ui/error-codes/E0277-2.stderr
Expand Up @@ -8,9 +8,21 @@ LL | is_send::<Foo>();
| ^^^^^^^^^^^^^^ `*const u8` cannot be sent between threads safely
|
= help: within `Foo`, the trait `Send` is not implemented for `*const u8`
= note: required because it appears within the type `Baz`
= note: required because it appears within the type `Bar`
= note: required because it appears within the type `Foo`
note: required because it appears within the type `Baz`
--> $DIR/E0277-2.rs:9:8
|
LL | struct Baz {
| ^^^
note: required because it appears within the type `Bar`
--> $DIR/E0277-2.rs:5:8
|
LL | struct Bar {
| ^^^
note: required because it appears within the type `Foo`
--> $DIR/E0277-2.rs:1:8
|
LL | struct Foo {
| ^^^

error: aborting due to previous error

Expand Down

0 comments on commit 8bc5581

Please sign in to comment.