Skip to content

Commit

Permalink
Better comment for implicit captures
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Mar 6, 2024
1 parent 62415e2 commit fcf1367
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 29 deletions.
63 changes: 50 additions & 13 deletions compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -726,25 +726,62 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
// Ensure that the parent of the def is an item, not HRTB
let parent_id = self.tcx.parent_hir_id(hir_id);
if !parent_id.is_owner() {
struct_span_code_err!(
self.tcx.dcx(),
lifetime.ident.span,
E0657,
"`impl Trait` can only capture lifetimes bound at the fn or impl level"
)
.emit();
// If the lifetime span is the same as the lifetime's declaration,
// then it's likely we've implicitly captured the lifetime. Give
// a better span and also note that it's implicitly captured.
let diag = if lifetime.ident.span == self.tcx.def_span(def_id) {
self.tcx
.dcx()
.struct_span_err(
self.tcx.def_span(item_id.owner_id),
"`impl Trait` can only capture lifetimes bound \
at the fn or impl level",
)
.with_span_label(
self.tcx.def_span(item_id.owner_id),
"`impl Trait` implicitly captures all lifetimes in scope",
)
} else {
struct_span_code_err!(
self.tcx.dcx(),
lifetime.ident.span,
E0657,
"`impl Trait` can only capture lifetimes bound at the fn or impl level"
)
};
diag.with_code(E0657)
.with_span_note(self.tcx.def_span(def_id), "lifetime declared here")
.emit();
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
}
if let hir::Node::Item(hir::Item {
kind: hir::ItemKind::OpaqueTy { .. }, ..
}) = self.tcx.hir_node(parent_id)
{
self.tcx.dcx().struct_span_err(
lifetime.ident.span,
"higher kinded lifetime bounds on nested opaque types are not supported yet",
)
.with_span_note(self.tcx.def_span(def_id), "lifetime declared here")
.emit();
let diag = if lifetime.ident.span == self.tcx.def_span(def_id) {
// If the lifetime span is the same as the lifetime's declaration,
// then it's likely we've implicitly captured the lifetime. Give
// a better span and also note that it's implicitly captured.
self.tcx
.dcx()
.struct_span_err(
self.tcx.def_span(item_id.owner_id),
"`impl Trait` captures higher-ranked lifetime, \
which is not supported yet",
)
.with_span_label(
self.tcx.def_span(item_id.owner_id),
"`impl Trait` implicitly captures all lifetimes in scope",
)
} else {
self.tcx.dcx().struct_span_err(
lifetime.ident.span,
"higher kinded lifetime bounds on nested opaque types are not supported yet",
)
};
diag.with_code(E0657)
.with_span_note(self.tcx.def_span(def_id), "lifetime declared here")
.emit();
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
}
}
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/error-codes/E0657.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,24 @@ error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl le
|
LL | -> Box<for<'a> Id<impl Lt<'a>>>
| ^^
|
note: lifetime declared here
--> $DIR/E0657.rs:10:16
|
LL | -> Box<for<'a> Id<impl Lt<'a>>>
| ^^

error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
--> $DIR/E0657.rs:19:35
|
LL | -> Box<for<'a> Id<impl Lt<'a>>>
| ^^
|
note: lifetime declared here
--> $DIR/E0657.rs:19:20
|
LL | -> Box<for<'a> Id<impl Lt<'a>>>
| ^^

error: aborting due to 2 previous errors

Expand Down
9 changes: 5 additions & 4 deletions tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ help: consider using the `'static` lifetime, but this is uncommon unless you're
LL | fn d() -> impl Fn() -> (impl Debug + 'static) {
| ~~~~~~~

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

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

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

error: aborting due to 7 previous errors

For more information about this error, try `rustc --explain E0106`.
Some errors have detailed explanations: E0106, E0657.
For more information about an error, try `rustc --explain E0106`.
3 changes: 2 additions & 1 deletion tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ error: ambiguous `+` in a type
LL | fn b() -> impl Fn() -> impl Debug + Send {
| ^^^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + Send)`

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

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0657`.
6 changes: 6 additions & 0 deletions tests/ui/impl-trait/implicit-capture-late.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
--> $DIR/implicit-capture-late.rs:10:55
|
LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {
| ^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope
|
note: lifetime declared here
--> $DIR/implicit-capture-late.rs:10:36
|
LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {
Expand Down
3 changes: 2 additions & 1 deletion tests/ui/impl-trait/issues/issue-54895.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: higher kinded lifetime bounds on nested opaque types are not supported yet
error[E0657]: higher kinded lifetime bounds on nested opaque types are not supported yet
--> $DIR/issue-54895.rs:15:53
|
LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> {
Expand All @@ -12,3 +12,4 @@ LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> {

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0657`.
3 changes: 2 additions & 1 deletion tests/ui/impl-trait/issues/issue-67830.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: higher kinded lifetime bounds on nested opaque types are not supported yet
error[E0657]: higher kinded lifetime bounds on nested opaque types are not supported yet
--> $DIR/issue-67830.rs:21:62
|
LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> {
Expand Down Expand Up @@ -31,3 +31,4 @@ LL | Wrap(|a| Some(a).into_iter())

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0657`.
7 changes: 4 additions & 3 deletions tests/ui/impl-trait/issues/issue-88236-2.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: higher kinded lifetime bounds on nested opaque types are not supported yet
error[E0657]: higher kinded lifetime bounds on nested opaque types are not supported yet
--> $DIR/issue-88236-2.rs:15:61
|
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
Expand All @@ -10,7 +10,7 @@ note: lifetime declared here
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
| ^^

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

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

error: aborting due to 8 previous errors

For more information about this error, try `rustc --explain E0657`.
3 changes: 2 additions & 1 deletion tests/ui/impl-trait/issues/issue-88236.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: higher kinded lifetime bounds on nested opaque types are not supported yet
error[E0657]: higher kinded lifetime bounds on nested opaque types are not supported yet
--> $DIR/issue-88236.rs:15:61
|
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
Expand All @@ -12,3 +12,4 @@ LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0657`.
10 changes: 5 additions & 5 deletions tests/ui/impl-trait/nested-rpit-hrtb.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ help: consider introducing lifetime `'b` here
LL | fn two_htrb_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {}
| ++++

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

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

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

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

error: aborting due to 12 previous errors

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

0 comments on commit fcf1367

Please sign in to comment.