Skip to content

Commit fcf1367

Browse files
Better comment for implicit captures
1 parent 62415e2 commit fcf1367

10 files changed

+90
-29
lines changed

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+50-13
Original file line numberDiff line numberDiff line change
@@ -726,25 +726,62 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
726726
// Ensure that the parent of the def is an item, not HRTB
727727
let parent_id = self.tcx.parent_hir_id(hir_id);
728728
if !parent_id.is_owner() {
729-
struct_span_code_err!(
730-
self.tcx.dcx(),
731-
lifetime.ident.span,
732-
E0657,
733-
"`impl Trait` can only capture lifetimes bound at the fn or impl level"
734-
)
735-
.emit();
729+
// If the lifetime span is the same as the lifetime's declaration,
730+
// then it's likely we've implicitly captured the lifetime. Give
731+
// a better span and also note that it's implicitly captured.
732+
let diag = if lifetime.ident.span == self.tcx.def_span(def_id) {
733+
self.tcx
734+
.dcx()
735+
.struct_span_err(
736+
self.tcx.def_span(item_id.owner_id),
737+
"`impl Trait` can only capture lifetimes bound \
738+
at the fn or impl level",
739+
)
740+
.with_span_label(
741+
self.tcx.def_span(item_id.owner_id),
742+
"`impl Trait` implicitly captures all lifetimes in scope",
743+
)
744+
} else {
745+
struct_span_code_err!(
746+
self.tcx.dcx(),
747+
lifetime.ident.span,
748+
E0657,
749+
"`impl Trait` can only capture lifetimes bound at the fn or impl level"
750+
)
751+
};
752+
diag.with_code(E0657)
753+
.with_span_note(self.tcx.def_span(def_id), "lifetime declared here")
754+
.emit();
736755
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
737756
}
738757
if let hir::Node::Item(hir::Item {
739758
kind: hir::ItemKind::OpaqueTy { .. }, ..
740759
}) = self.tcx.hir_node(parent_id)
741760
{
742-
self.tcx.dcx().struct_span_err(
743-
lifetime.ident.span,
744-
"higher kinded lifetime bounds on nested opaque types are not supported yet",
745-
)
746-
.with_span_note(self.tcx.def_span(def_id), "lifetime declared here")
747-
.emit();
761+
let diag = if lifetime.ident.span == self.tcx.def_span(def_id) {
762+
// If the lifetime span is the same as the lifetime's declaration,
763+
// then it's likely we've implicitly captured the lifetime. Give
764+
// a better span and also note that it's implicitly captured.
765+
self.tcx
766+
.dcx()
767+
.struct_span_err(
768+
self.tcx.def_span(item_id.owner_id),
769+
"`impl Trait` captures higher-ranked lifetime, \
770+
which is not supported yet",
771+
)
772+
.with_span_label(
773+
self.tcx.def_span(item_id.owner_id),
774+
"`impl Trait` implicitly captures all lifetimes in scope",
775+
)
776+
} else {
777+
self.tcx.dcx().struct_span_err(
778+
lifetime.ident.span,
779+
"higher kinded lifetime bounds on nested opaque types are not supported yet",
780+
)
781+
};
782+
diag.with_code(E0657)
783+
.with_span_note(self.tcx.def_span(def_id), "lifetime declared here")
784+
.emit();
748785
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
749786
}
750787
}

tests/ui/error-codes/E0657.stderr

+12
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,24 @@ error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl le
33
|
44
LL | -> Box<for<'a> Id<impl Lt<'a>>>
55
| ^^
6+
|
7+
note: lifetime declared here
8+
--> $DIR/E0657.rs:10:16
9+
|
10+
LL | -> Box<for<'a> Id<impl Lt<'a>>>
11+
| ^^
612

713
error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
814
--> $DIR/E0657.rs:19:35
915
|
1016
LL | -> Box<for<'a> Id<impl Lt<'a>>>
1117
| ^^
18+
|
19+
note: lifetime declared here
20+
--> $DIR/E0657.rs:19:20
21+
|
22+
LL | -> Box<for<'a> Id<impl Lt<'a>>>
23+
| ^^
1224

1325
error: aborting due to 2 previous errors
1426

tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr

+5-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ help: consider using the `'static` lifetime, but this is uncommon unless you're
1010
LL | fn d() -> impl Fn() -> (impl Debug + 'static) {
1111
| ~~~~~~~
1212

13-
error: higher kinded lifetime bounds on nested opaque types are not supported yet
13+
error[E0657]: higher kinded lifetime bounds on nested opaque types are not supported yet
1414
--> $DIR/impl-fn-hrtb-bounds.rs:4:41
1515
|
1616
LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
@@ -22,7 +22,7 @@ note: lifetime declared here
2222
LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
2323
| ^
2424

25-
error: higher kinded lifetime bounds on nested opaque types are not supported yet
25+
error[E0657]: higher kinded lifetime bounds on nested opaque types are not supported yet
2626
--> $DIR/impl-fn-hrtb-bounds.rs:10:52
2727
|
2828
LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
@@ -34,7 +34,7 @@ note: lifetime declared here
3434
LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
3535
| ^^
3636

37-
error: higher kinded lifetime bounds on nested opaque types are not supported yet
37+
error[E0657]: higher kinded lifetime bounds on nested opaque types are not supported yet
3838
--> $DIR/impl-fn-hrtb-bounds.rs:16:52
3939
|
4040
LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
@@ -75,4 +75,5 @@ LL | |x| x
7575

7676
error: aborting due to 7 previous errors
7777

78-
For more information about this error, try `rustc --explain E0106`.
78+
Some errors have detailed explanations: E0106, E0657.
79+
For more information about an error, try `rustc --explain E0106`.

tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ error: ambiguous `+` in a type
1010
LL | fn b() -> impl Fn() -> impl Debug + Send {
1111
| ^^^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + Send)`
1212

13-
error: higher kinded lifetime bounds on nested opaque types are not supported yet
13+
error[E0657]: higher kinded lifetime bounds on nested opaque types are not supported yet
1414
--> $DIR/impl-fn-parsing-ambiguities.rs:4:40
1515
|
1616
LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ {
@@ -33,3 +33,4 @@ LL | |x| x
3333

3434
error: aborting due to 4 previous errors
3535

36+
For more information about this error, try `rustc --explain E0657`.

tests/ui/impl-trait/implicit-capture-late.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
2+
--> $DIR/implicit-capture-late.rs:10:55
3+
|
4+
LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {
5+
| ^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope
6+
|
7+
note: lifetime declared here
28
--> $DIR/implicit-capture-late.rs:10:36
39
|
410
LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {

tests/ui/impl-trait/issues/issue-54895.stderr

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: higher kinded lifetime bounds on nested opaque types are not supported yet
1+
error[E0657]: higher kinded lifetime bounds on nested opaque types are not supported yet
22
--> $DIR/issue-54895.rs:15:53
33
|
44
LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> {
@@ -12,3 +12,4 @@ LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> {
1212

1313
error: aborting due to 1 previous error
1414

15+
For more information about this error, try `rustc --explain E0657`.

tests/ui/impl-trait/issues/issue-67830.stderr

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: higher kinded lifetime bounds on nested opaque types are not supported yet
1+
error[E0657]: higher kinded lifetime bounds on nested opaque types are not supported yet
22
--> $DIR/issue-67830.rs:21:62
33
|
44
LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> {
@@ -31,3 +31,4 @@ LL | Wrap(|a| Some(a).into_iter())
3131

3232
error: aborting due to 3 previous errors
3333

34+
For more information about this error, try `rustc --explain E0657`.

tests/ui/impl-trait/issues/issue-88236-2.stderr

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: higher kinded lifetime bounds on nested opaque types are not supported yet
1+
error[E0657]: higher kinded lifetime bounds on nested opaque types are not supported yet
22
--> $DIR/issue-88236-2.rs:15:61
33
|
44
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
@@ -10,7 +10,7 @@ note: lifetime declared here
1010
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
1111
| ^^
1212

13-
error: higher kinded lifetime bounds on nested opaque types are not supported yet
13+
error[E0657]: higher kinded lifetime bounds on nested opaque types are not supported yet
1414
--> $DIR/issue-88236-2.rs:18:80
1515
|
1616
LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
@@ -22,7 +22,7 @@ note: lifetime declared here
2222
LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
2323
| ^^
2424

25-
error: higher kinded lifetime bounds on nested opaque types are not supported yet
25+
error[E0657]: higher kinded lifetime bounds on nested opaque types are not supported yet
2626
--> $DIR/issue-88236-2.rs:25:78
2727
|
2828
LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
@@ -90,3 +90,4 @@ LL | x
9090

9191
error: aborting due to 8 previous errors
9292

93+
For more information about this error, try `rustc --explain E0657`.

tests/ui/impl-trait/issues/issue-88236.stderr

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: higher kinded lifetime bounds on nested opaque types are not supported yet
1+
error[E0657]: higher kinded lifetime bounds on nested opaque types are not supported yet
22
--> $DIR/issue-88236.rs:15:61
33
|
44
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
@@ -12,3 +12,4 @@ LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
1212

1313
error: aborting due to 1 previous error
1414

15+
For more information about this error, try `rustc --explain E0657`.

tests/ui/impl-trait/nested-rpit-hrtb.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ help: consider introducing lifetime `'b` here
2929
LL | fn two_htrb_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {}
3030
| ++++
3131

32-
error: higher kinded lifetime bounds on nested opaque types are not supported yet
32+
error[E0657]: higher kinded lifetime bounds on nested opaque types are not supported yet
3333
--> $DIR/nested-rpit-hrtb.rs:25:69
3434
|
3535
LL | fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {}
@@ -41,7 +41,7 @@ note: lifetime declared here
4141
LL | fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {}
4242
| ^^
4343

44-
error: higher kinded lifetime bounds on nested opaque types are not supported yet
44+
error[E0657]: higher kinded lifetime bounds on nested opaque types are not supported yet
4545
--> $DIR/nested-rpit-hrtb.rs:29:68
4646
|
4747
LL | fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {}
@@ -53,7 +53,7 @@ note: lifetime declared here
5353
LL | fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {}
5454
| ^^
5555

56-
error: higher kinded lifetime bounds on nested opaque types are not supported yet
56+
error[E0657]: higher kinded lifetime bounds on nested opaque types are not supported yet
5757
--> $DIR/nested-rpit-hrtb.rs:32:74
5858
|
5959
LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
@@ -65,7 +65,7 @@ note: lifetime declared here
6565
LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
6666
| ^^
6767

68-
error: higher kinded lifetime bounds on nested opaque types are not supported yet
68+
error[E0657]: higher kinded lifetime bounds on nested opaque types are not supported yet
6969
--> $DIR/nested-rpit-hrtb.rs:36:73
7070
|
7171
LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
@@ -133,5 +133,5 @@ LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Si
133133

134134
error: aborting due to 12 previous errors
135135

136-
Some errors have detailed explanations: E0261, E0277.
136+
Some errors have detailed explanations: E0261, E0277, E0657.
137137
For more information about an error, try `rustc --explain E0261`.

0 commit comments

Comments
 (0)