Skip to content

Commit 7528cc3

Browse files
committed
Point at impl and type defs introducing requirements on E0277
1 parent fd66899 commit 7528cc3

File tree

55 files changed

+621
-110
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+621
-110
lines changed

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1575,7 +1575,7 @@ impl<'tcx> TyCtxt<'tcx> {
15751575
.filter(|item| item.kind == AssocKind::Fn && item.defaultness.has_value())
15761576
}
15771577

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

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

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2067,7 +2067,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
20672067

20682068
// Don't print the tuple of capture types
20692069
if !is_upvar_tys_infer_tuple {
2070-
err.note(&format!("required because it appears within the type `{}`", ty));
2070+
let msg = format!("required because it appears within the type `{}`", ty);
2071+
match ty.kind() {
2072+
ty::Adt(def, _) => match self.tcx.item_name_from_hir(def.did) {
2073+
Some(ident) => err.span_note(ident.span, &msg),
2074+
None => err.note(&msg),
2075+
},
2076+
_ => err.note(&msg),
2077+
};
20712078
}
20722079

20732080
obligated_types.push(ty);
@@ -2089,11 +2096,36 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
20892096
ObligationCauseCode::ImplDerivedObligation(ref data) => {
20902097
let mut parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_ref);
20912098
let parent_def_id = parent_trait_ref.def_id();
2092-
err.note(&format!(
2099+
let msg = format!(
20932100
"required because of the requirements on the impl of `{}` for `{}`",
20942101
parent_trait_ref.print_only_trait_path(),
20952102
parent_trait_ref.skip_binder().self_ty()
2096-
));
2103+
);
2104+
let mut candidates = vec![];
2105+
self.tcx.for_each_relevant_impl(
2106+
parent_def_id,
2107+
parent_trait_ref.self_ty().skip_binder(),
2108+
|impl_def_id| {
2109+
candidates.push(impl_def_id);
2110+
},
2111+
);
2112+
match &candidates[..] {
2113+
[def_id] => match self.tcx.hir().get_if_local(*def_id) {
2114+
Some(Node::Item(hir::Item {
2115+
kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
2116+
..
2117+
})) => {
2118+
let mut spans = Vec::with_capacity(2);
2119+
if let Some(trait_ref) = of_trait {
2120+
spans.push(trait_ref.path.span);
2121+
}
2122+
spans.push(self_ty.span);
2123+
err.span_note(spans, &msg)
2124+
}
2125+
_ => err.note(&msg),
2126+
},
2127+
_ => err.note(&msg),
2128+
};
20972129

20982130
let mut parent_predicate = parent_trait_ref.without_const().to_predicate(tcx);
20992131
let mut data = data;

src/test/ui/associated-types/impl-wf-cycle-1.stderr

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ LL | |
1010
LL | | }
1111
| |_^
1212
|
13-
= note: required because of the requirements on the impl of `Grault` for `(T,)`
13+
note: required because of the requirements on the impl of `Grault` for `(T,)`
14+
--> $DIR/impl-wf-cycle-1.rs:15:17
15+
|
16+
LL | impl<T: Grault> Grault for (T,)
17+
| ^^^^^^ ^^^^
1418
= note: 1 redundant requirements hidden
1519
= note: required because of the requirements on the impl of `Grault` for `(T,)`
1620

@@ -20,7 +24,11 @@ error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
2024
LL | type A = ();
2125
| ^^^^^^^^^^^^
2226
|
23-
= note: required because of the requirements on the impl of `Grault` for `(T,)`
27+
note: required because of the requirements on the impl of `Grault` for `(T,)`
28+
--> $DIR/impl-wf-cycle-1.rs:15:17
29+
|
30+
LL | impl<T: Grault> Grault for (T,)
31+
| ^^^^^^ ^^^^
2432
= note: 1 redundant requirements hidden
2533
= note: required because of the requirements on the impl of `Grault` for `(T,)`
2634

@@ -30,7 +38,11 @@ error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
3038
LL | type B = bool;
3139
| ^^^^^^^^^^^^^^
3240
|
33-
= note: required because of the requirements on the impl of `Grault` for `(T,)`
41+
note: required because of the requirements on the impl of `Grault` for `(T,)`
42+
--> $DIR/impl-wf-cycle-1.rs:15:17
43+
|
44+
LL | impl<T: Grault> Grault for (T,)
45+
| ^^^^^^ ^^^^
3446
= note: 1 redundant requirements hidden
3547
= note: required because of the requirements on the impl of `Grault` for `(T,)`
3648

src/test/ui/associated-types/impl-wf-cycle-2.stderr

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,23 @@ LL | |
1010
LL | | }
1111
| |_^
1212
|
13-
= note: required because of the requirements on the impl of `Grault` for `(T,)`
13+
note: required because of the requirements on the impl of `Grault` for `(T,)`
14+
--> $DIR/impl-wf-cycle-2.rs:7:17
15+
|
16+
LL | impl<T: Grault> Grault for (T,)
17+
| ^^^^^^ ^^^^
1418

1519
error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
1620
--> $DIR/impl-wf-cycle-2.rs:11:5
1721
|
1822
LL | type A = ();
1923
| ^^^^^^^^^^^^
2024
|
21-
= note: required because of the requirements on the impl of `Grault` for `(T,)`
25+
note: required because of the requirements on the impl of `Grault` for `(T,)`
26+
--> $DIR/impl-wf-cycle-2.rs:7:17
27+
|
28+
LL | impl<T: Grault> Grault for (T,)
29+
| ^^^^^^ ^^^^
2230

2331
error: aborting due to 2 previous errors
2432

src/test/ui/associated-types/issue-44153.stderr

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ LL | fn visit() {}
77
LL | <() as Visit>::visit();
88
| ^^^^^^^^^^^^^^^^^^^^ expected `()`, found `&()`
99
|
10-
= note: required because of the requirements on the impl of `Visit` for `()`
10+
note: required because of the requirements on the impl of `Visit` for `()`
11+
--> $DIR/issue-44153.rs:13:10
12+
|
13+
LL | impl<'a> Visit for () where
14+
| ^^^^^ ^^
1115

1216
error: aborting due to previous error
1317

src/test/ui/associated-types/issue-65774-1.stderr

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ error[E0277]: the trait bound `T: MyDisplay` is not satisfied
1313
LL | let closure = |config: &mut <S as MPU>::MpuConfig| writer.my_write(&config);
1414
| ^^^^^^^ the trait `MyDisplay` is not implemented for `T`
1515
|
16-
= note: required because of the requirements on the impl of `MyDisplay` for `&mut T`
16+
note: required because of the requirements on the impl of `MyDisplay` for `&mut T`
17+
--> $DIR/issue-65774-1.rs:5:24
18+
|
19+
LL | impl<'a, T: MyDisplay> MyDisplay for &'a mut T { }
20+
| ^^^^^^^^^ ^^^^^^^^^
1721
= note: required for the cast to the object type `dyn MyDisplay`
1822

1923
error: aborting due to 2 previous errors

src/test/ui/async-await/issue-72590-type-error-sized.stderr

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ LL | async fn frob(self) {}
1717
| ^^^^ doesn't have a size known at compile-time
1818
|
1919
= help: within `Foo`, the trait `Sized` is not implemented for `str`
20-
= note: required because it appears within the type `Foo`
20+
note: required because it appears within the type `Foo`
21+
--> $DIR/issue-72590-type-error-sized.rs:5:8
22+
|
23+
LL | struct Foo {
24+
| ^^^
2125
= help: unsized fn params are gated as an unstable feature
2226
help: function arguments must have a statically known size, borrowed types always have a known size
2327
|
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use std::{
2+
future::Future,
3+
pin::Pin,
4+
marker::Unpin,
5+
task::{Context, Poll},
6+
};
7+
8+
struct Sleep(std::marker::PhantomPinned);
9+
10+
impl Future for Sleep {
11+
type Output = ();
12+
13+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
14+
Poll::Ready(())
15+
}
16+
}
17+
18+
impl Drop for Sleep {
19+
fn drop(&mut self) {}
20+
}
21+
22+
fn sleep() -> Sleep {
23+
Sleep(std::marker::PhantomPinned)
24+
}
25+
26+
27+
struct MyFuture {
28+
sleep: Sleep,
29+
}
30+
31+
impl MyFuture {
32+
fn new() -> Self {
33+
Self {
34+
sleep: sleep(),
35+
}
36+
}
37+
}
38+
39+
impl Future for MyFuture {
40+
type Output = ();
41+
42+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
43+
Pin::new(&mut self.sleep).poll(cx)
44+
//~^ ERROR `PhantomPinned` cannot be unpinned
45+
}
46+
}
47+
48+
fn main() {}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0277]: `PhantomPinned` cannot be unpinned
2+
--> $DIR/pin-needed-to-poll-2.rs:43:9
3+
|
4+
LL | Pin::new(&mut self.sleep).poll(cx)
5+
| ^^^^^^^^ within `Sleep`, the trait `Unpin` is not implemented for `PhantomPinned`
6+
|
7+
note: required because it appears within the type `Sleep`
8+
--> $DIR/pin-needed-to-poll-2.rs:8:8
9+
|
10+
LL | struct Sleep(std::marker::PhantomPinned);
11+
| ^^^^^
12+
= note: required by `Pin::<P>::new`
13+
14+
error: aborting due to previous error
15+
16+
For more information about this error, try `rustc --explain E0277`.

src/test/ui/block-result/issue-22645.stderr

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ LL | b + 3
66
|
77
= help: the following implementations were found:
88
<f64 as Scalar>
9-
= note: required because of the requirements on the impl of `Add<{integer}>` for `Bob`
9+
note: required because of the requirements on the impl of `Add<{integer}>` for `Bob`
10+
--> $DIR/issue-22645.rs:8:19
11+
|
12+
LL | impl<RHS: Scalar> Add <RHS> for Bob {
13+
| ^^^^^^^^^ ^^^
1014

1115
error[E0308]: mismatched types
1216
--> $DIR/issue-22645.rs:15:3

src/test/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ LL | impl <T:Sync+'static> RequiresRequiresShareAndSend for X<T> { }
99
LL | pub trait RequiresRequiresShareAndSend : RequiresShare + Send { }
1010
| ---- required by this bound in `RequiresRequiresShareAndSend`
1111
|
12-
= note: required because it appears within the type `X<T>`
12+
note: required because it appears within the type `X<T>`
13+
--> $DIR/builtin-superkinds-in-metadata.rs:9:8
14+
|
15+
LL | struct X<T>(T);
16+
| ^
1317
help: consider further restricting this bound
1418
|
1519
LL | impl <T:Sync+'static + Send> RequiresRequiresShareAndSend for X<T> { }

src/test/ui/did_you_mean/recursion_limit.stderr

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,56 @@ LL | is_send::<A>();
88
| ^^^^^^^^^^^^
99
|
1010
= help: consider adding a `#![recursion_limit="20"]` attribute to your crate (`recursion_limit`)
11-
= note: required because it appears within the type `J`
12-
= note: required because it appears within the type `I`
13-
= note: required because it appears within the type `H`
14-
= note: required because it appears within the type `G`
15-
= note: required because it appears within the type `F`
16-
= note: required because it appears within the type `E`
17-
= note: required because it appears within the type `D`
18-
= note: required because it appears within the type `C`
19-
= note: required because it appears within the type `B`
20-
= note: required because it appears within the type `A`
11+
note: required because it appears within the type `J`
12+
--> $DIR/recursion_limit.rs:24:9
13+
|
14+
LL | link! { J, K }
15+
| ^
16+
note: required because it appears within the type `I`
17+
--> $DIR/recursion_limit.rs:23:9
18+
|
19+
LL | link! { I, J }
20+
| ^
21+
note: required because it appears within the type `H`
22+
--> $DIR/recursion_limit.rs:22:9
23+
|
24+
LL | link! { H, I }
25+
| ^
26+
note: required because it appears within the type `G`
27+
--> $DIR/recursion_limit.rs:21:9
28+
|
29+
LL | link! { G, H }
30+
| ^
31+
note: required because it appears within the type `F`
32+
--> $DIR/recursion_limit.rs:20:9
33+
|
34+
LL | link! { F, G }
35+
| ^
36+
note: required because it appears within the type `E`
37+
--> $DIR/recursion_limit.rs:19:9
38+
|
39+
LL | link! { E, F }
40+
| ^
41+
note: required because it appears within the type `D`
42+
--> $DIR/recursion_limit.rs:18:9
43+
|
44+
LL | link! { D, E }
45+
| ^
46+
note: required because it appears within the type `C`
47+
--> $DIR/recursion_limit.rs:17:9
48+
|
49+
LL | link! { C, D }
50+
| ^
51+
note: required because it appears within the type `B`
52+
--> $DIR/recursion_limit.rs:16:9
53+
|
54+
LL | link! { B, C }
55+
| ^
56+
note: required because it appears within the type `A`
57+
--> $DIR/recursion_limit.rs:15:9
58+
|
59+
LL | link! { A, B }
60+
| ^
2161

2262
error: aborting due to previous error
2363

src/test/ui/dst/dst-bad-deep.stderr

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,16 @@ LL | let h: &Fat<Fat<[isize]>> = &Fat { ptr: *g };
55
| ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
66
|
77
= help: within `Fat<Fat<[isize]>>`, the trait `Sized` is not implemented for `[isize]`
8-
= note: required because it appears within the type `Fat<[isize]>`
9-
= note: required because it appears within the type `Fat<Fat<[isize]>>`
8+
note: required because it appears within the type `Fat<[isize]>`
9+
--> $DIR/dst-bad-deep.rs:6:8
10+
|
11+
LL | struct Fat<T: ?Sized> {
12+
| ^^^
13+
note: required because it appears within the type `Fat<Fat<[isize]>>`
14+
--> $DIR/dst-bad-deep.rs:6:8
15+
|
16+
LL | struct Fat<T: ?Sized> {
17+
| ^^^
1018
= note: structs must have a statically known size to be initialized
1119

1220
error: aborting due to previous error

src/test/ui/error-codes/E0275.stderr

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ LL | impl<T> Foo for T where Bar<T>: Foo {}
88
| ^^^
99
|
1010
= help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`E0275`)
11-
= 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>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
11+
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>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
12+
--> $DIR/E0275.rs:5:9
13+
|
14+
LL | impl<T> Foo for T where Bar<T>: Foo {}
15+
| ^^^ ^
1216
= note: 127 redundant requirements hidden
1317
= note: required because of the requirements on the impl of `Foo` for `Bar<T>`
1418

src/test/ui/error-codes/E0277-2.stderr

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,21 @@ LL | is_send::<Foo>();
88
| ^^^^^^^^^^^^^^ `*const u8` cannot be sent between threads safely
99
|
1010
= help: within `Foo`, the trait `Send` is not implemented for `*const u8`
11-
= note: required because it appears within the type `Baz`
12-
= note: required because it appears within the type `Bar`
13-
= note: required because it appears within the type `Foo`
11+
note: required because it appears within the type `Baz`
12+
--> $DIR/E0277-2.rs:9:8
13+
|
14+
LL | struct Baz {
15+
| ^^^
16+
note: required because it appears within the type `Bar`
17+
--> $DIR/E0277-2.rs:5:8
18+
|
19+
LL | struct Bar {
20+
| ^^^
21+
note: required because it appears within the type `Foo`
22+
--> $DIR/E0277-2.rs:1:8
23+
|
24+
LL | struct Foo {
25+
| ^^^
1426

1527
error: aborting due to previous error
1628

0 commit comments

Comments
 (0)