diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index e469ca80c590a..3537fb388d013 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -1044,6 +1044,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { lifetime_ref ); err.span_label(lifetime_ref.span, "undeclared lifetime"); + let mut suggests_in_band = false; for missing in &self.missing_named_lifetime_spots { match missing { MissingLifetimeSpot::Generics(generics) => { @@ -1057,6 +1058,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { }) { (param.span.shrink_to_lo(), format!("{}, ", lifetime_ref)) } else { + suggests_in_band = true; (generics.span, format!("<{}>", lifetime_ref)) }; err.span_suggestion( @@ -1084,6 +1086,15 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { } } } + if nightly_options::is_nightly_build() + && !self.tcx.features().in_band_lifetimes + && suggests_in_band + { + err.help( + "if you want to experiment with in-band lifetime bindings, \ + add `#![feature(in_band_lifetimes)]` to the crate attributes", + ); + } err.emit(); } diff --git a/src/test/ui/error-codes/E0261.stderr b/src/test/ui/error-codes/E0261.stderr index 0eab2dc0ee05f..33d74feead513 100644 --- a/src/test/ui/error-codes/E0261.stderr +++ b/src/test/ui/error-codes/E0261.stderr @@ -5,6 +5,8 @@ LL | fn foo(x: &'a str) { } | - ^^ undeclared lifetime | | | help: consider introducing lifetime `'a` here: `<'a>` + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error[E0261]: use of undeclared lifetime name `'a` --> $DIR/E0261.rs:5:9 @@ -13,6 +15,8 @@ LL | struct Foo { | - help: consider introducing lifetime `'a` here: `<'a>` LL | x: &'a str, | ^^ undeclared lifetime + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error: aborting due to 2 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-in_band_lifetimes.stderr b/src/test/ui/feature-gates/feature-gate-in_band_lifetimes.stderr index bbf3ea8a89f23..0f0406b8e17d8 100644 --- a/src/test/ui/feature-gates/feature-gate-in_band_lifetimes.stderr +++ b/src/test/ui/feature-gates/feature-gate-in_band_lifetimes.stderr @@ -5,6 +5,8 @@ LL | fn foo(x: &'x u8) -> &'x u8 { x } | - ^^ undeclared lifetime | | | help: consider introducing lifetime `'x` here: `<'x>` + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error[E0261]: use of undeclared lifetime name `'x` --> $DIR/feature-gate-in_band_lifetimes.rs:3:23 @@ -13,6 +15,8 @@ LL | fn foo(x: &'x u8) -> &'x u8 { x } | - ^^ undeclared lifetime | | | help: consider introducing lifetime `'x` here: `<'x>` + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:15:12 @@ -28,6 +32,7 @@ error[E0261]: use of undeclared lifetime name `'b` LL | fn inner_2(&self) -> &'b u8 { | ^^ undeclared lifetime | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes help: consider introducing lifetime `'b` here | LL | impl<'b, 'a> X<'b> { @@ -44,6 +49,8 @@ LL | impl X<'b> { | - ^^ undeclared lifetime | | | help: consider introducing lifetime `'b` here: `<'b>` + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error[E0261]: use of undeclared lifetime name `'b` --> $DIR/feature-gate-in_band_lifetimes.rs:25:27 @@ -51,6 +58,7 @@ error[E0261]: use of undeclared lifetime name `'b` LL | fn inner_3(&self) -> &'b u8 { | ^^ undeclared lifetime | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes help: consider introducing lifetime `'b` here | LL | impl<'b> X<'b> { @@ -67,6 +75,8 @@ LL | impl Y<&'a u8> { | - ^^ undeclared lifetime | | | help: consider introducing lifetime `'a` here: `<'a>` + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error[E0261]: use of undeclared lifetime name `'a` --> $DIR/feature-gate-in_band_lifetimes.rs:35:25 @@ -74,6 +84,7 @@ error[E0261]: use of undeclared lifetime name `'a` LL | fn inner(&self) -> &'a u8 { | ^^ undeclared lifetime | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes help: consider introducing lifetime `'a` here | LL | impl<'a> Y<&'a u8> { @@ -89,6 +100,7 @@ error[E0261]: use of undeclared lifetime name `'b` LL | fn any_lifetime() -> &'b u8; | ^^ undeclared lifetime | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes help: consider introducing lifetime `'b` here | LL | trait MyTrait<'b, 'a> { @@ -104,6 +116,7 @@ error[E0261]: use of undeclared lifetime name `'b` LL | fn borrowed_lifetime(&'b self) -> &'b u8; | ^^ undeclared lifetime | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes help: consider introducing lifetime `'b` here | LL | trait MyTrait<'b, 'a> { @@ -119,6 +132,7 @@ error[E0261]: use of undeclared lifetime name `'b` LL | fn borrowed_lifetime(&'b self) -> &'b u8; | ^^ undeclared lifetime | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes help: consider introducing lifetime `'b` here | LL | trait MyTrait<'b, 'a> { @@ -135,6 +149,8 @@ LL | impl MyTrait<'a> for Y<&'a u8> { | - ^^ undeclared lifetime | | | help: consider introducing lifetime `'a` here: `<'a>` + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error[E0261]: use of undeclared lifetime name `'a` --> $DIR/feature-gate-in_band_lifetimes.rs:50:25 @@ -143,6 +159,8 @@ LL | impl MyTrait<'a> for Y<&'a u8> { | - ^^ undeclared lifetime | | | help: consider introducing lifetime `'a` here: `<'a>` + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error[E0261]: use of undeclared lifetime name `'a` --> $DIR/feature-gate-in_band_lifetimes.rs:53:31 @@ -150,6 +168,7 @@ error[E0261]: use of undeclared lifetime name `'a` LL | fn my_lifetime(&self) -> &'a u8 { self.0 } | ^^ undeclared lifetime | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes help: consider introducing lifetime `'a` here | LL | impl<'a> MyTrait<'a> for Y<&'a u8> { @@ -165,6 +184,7 @@ error[E0261]: use of undeclared lifetime name `'b` LL | fn any_lifetime() -> &'b u8 { &0 } | ^^ undeclared lifetime | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes help: consider introducing lifetime `'b` here | LL | impl<'b> MyTrait<'a> for Y<&'a u8> { @@ -180,6 +200,7 @@ error[E0261]: use of undeclared lifetime name `'b` LL | fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 } | ^^ undeclared lifetime | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes help: consider introducing lifetime `'b` here | LL | impl<'b> MyTrait<'a> for Y<&'a u8> { @@ -195,6 +216,7 @@ error[E0261]: use of undeclared lifetime name `'b` LL | fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 } | ^^ undeclared lifetime | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes help: consider introducing lifetime `'b` here | LL | impl<'b> MyTrait<'a> for Y<&'a u8> { diff --git a/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr b/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr index fc2ce1cb866bb..f164c0d07a3c4 100644 --- a/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr +++ b/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr @@ -4,6 +4,7 @@ error[E0261]: use of undeclared lifetime name `'b` LL | + Deref>; | ^^ undeclared lifetime | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes help: consider introducing lifetime `'b` here | LL | trait Iterable<'b> { @@ -19,6 +20,7 @@ error[E0261]: use of undeclared lifetime name `'undeclared` LL | fn iter<'a>(&'a self) -> Self::Iter<'undeclared>; | ^^^^^^^^^^^ undeclared lifetime | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes help: consider introducing lifetime `'undeclared` here | LL | trait Iterable<'undeclared> { diff --git a/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr b/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr index c9f235c4f7df7..93c0384fcc266 100644 --- a/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr +++ b/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr @@ -5,6 +5,8 @@ LL | fn main() { | - help: consider introducing lifetime `'a` here: `<'a>` LL | 0.clone::<'a>(); | ^^ undeclared lifetime + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error: aborting due to previous error diff --git a/src/test/ui/regions/regions-in-enums.stderr b/src/test/ui/regions/regions-in-enums.stderr index 66537653291c7..d56c1fbd119c8 100644 --- a/src/test/ui/regions/regions-in-enums.stderr +++ b/src/test/ui/regions/regions-in-enums.stderr @@ -5,6 +5,8 @@ LL | enum No0 { | - help: consider introducing lifetime `'foo` here: `<'foo>` LL | X5(&'foo usize) | ^^^^ undeclared lifetime + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-in-enums.rs:17:9 @@ -13,6 +15,8 @@ LL | enum No1 { | - help: consider introducing lifetime `'a` here: `<'a>` LL | X6(&'a usize) | ^^ undeclared lifetime + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error: aborting due to 2 previous errors diff --git a/src/test/ui/regions/regions-in-structs.stderr b/src/test/ui/regions/regions-in-structs.stderr index 5dfdc2ee93b43..2750149d09735 100644 --- a/src/test/ui/regions/regions-in-structs.stderr +++ b/src/test/ui/regions/regions-in-structs.stderr @@ -5,6 +5,8 @@ LL | struct StructDecl { | - help: consider introducing lifetime `'a` here: `<'a>` LL | a: &'a isize, | ^^ undeclared lifetime + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-in-structs.rs:11:9 @@ -14,6 +16,8 @@ LL | struct StructDecl { LL | a: &'a isize, LL | b: &'a isize, | ^^ undeclared lifetime + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error: aborting due to 2 previous errors diff --git a/src/test/ui/regions/regions-name-undeclared.stderr b/src/test/ui/regions/regions-name-undeclared.stderr index eb19a30c52b97..57d39d59c8b04 100644 --- a/src/test/ui/regions/regions-name-undeclared.stderr +++ b/src/test/ui/regions/regions-name-undeclared.stderr @@ -4,6 +4,7 @@ error[E0261]: use of undeclared lifetime name `'b` LL | fn m4(&self, arg: &'b isize) { } | ^^ undeclared lifetime | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes help: consider introducing lifetime `'b` here | LL | impl<'b, 'a> Foo<'a> { @@ -19,6 +20,7 @@ error[E0261]: use of undeclared lifetime name `'b` LL | fn m5(&'b self) { } | ^^ undeclared lifetime | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes help: consider introducing lifetime `'b` here | LL | impl<'b, 'a> Foo<'a> { @@ -34,6 +36,7 @@ error[E0261]: use of undeclared lifetime name `'b` LL | fn m6(&self, arg: Foo<'b>) { } | ^^ undeclared lifetime | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes help: consider introducing lifetime `'b` here | LL | impl<'b, 'a> Foo<'a> { @@ -50,6 +53,8 @@ LL | type X = Option<&'a isize>; | - ^^ undeclared lifetime | | | help: consider introducing lifetime `'a` here: `<'a>` + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-name-undeclared.rs:27:13 @@ -58,6 +63,8 @@ LL | enum E { | - help: consider introducing lifetime `'a` here: `<'a>` LL | E1(&'a isize) | ^^ undeclared lifetime + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-name-undeclared.rs:30:13 @@ -66,6 +73,8 @@ LL | struct S { | - help: consider introducing lifetime `'a` here: `<'a>` LL | f: &'a isize | ^^ undeclared lifetime + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-name-undeclared.rs:32:14 @@ -74,6 +83,8 @@ LL | fn f(a: &'a isize) { } | - ^^ undeclared lifetime | | | help: consider introducing lifetime `'a` here: `<'a>` + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-name-undeclared.rs:40:17 @@ -82,6 +93,8 @@ LL | fn fn_types(a: &'a isize, | - ^^ undeclared lifetime | | | help: consider introducing lifetime `'a` here: `<'a>` + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error[E0261]: use of undeclared lifetime name `'b` --> $DIR/regions-name-undeclared.rs:42:36 @@ -90,6 +103,7 @@ LL | ... &'b isize, | ^^ undeclared lifetime | = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes help: consider introducing lifetime `'b` here | LL | fn fn_types<'b>(a: &'a isize, @@ -106,6 +120,7 @@ LL | ... &'b isize)>, | ^^ undeclared lifetime | = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes help: consider introducing lifetime `'b` here | LL | fn fn_types<'b>(a: &'a isize, @@ -123,6 +138,8 @@ LL | fn fn_types(a: &'a isize, ... LL | c: &'a isize) | ^^ undeclared lifetime + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error: aborting due to 11 previous errors diff --git a/src/test/ui/regions/regions-undeclared.stderr b/src/test/ui/regions/regions-undeclared.stderr index 6bfde5524ac49..f3cae184ccde8 100644 --- a/src/test/ui/regions/regions-undeclared.stderr +++ b/src/test/ui/regions/regions-undeclared.stderr @@ -11,6 +11,8 @@ LL | enum EnumDecl { | - help: consider introducing lifetime `'a` here: `<'a>` LL | Foo(&'a isize), | ^^ undeclared lifetime + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-undeclared.rs:5:10 @@ -20,6 +22,8 @@ LL | enum EnumDecl { LL | Foo(&'a isize), LL | Bar(&'a isize), | ^^ undeclared lifetime + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-undeclared.rs:8:15 @@ -28,6 +32,8 @@ LL | fn fnDecl(x: &'a isize, | - ^^ undeclared lifetime | | | help: consider introducing lifetime `'a` here: `<'a>` + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error[E0261]: use of undeclared lifetime name `'a` --> $DIR/regions-undeclared.rs:9:15 @@ -36,6 +42,8 @@ LL | fn fnDecl(x: &'a isize, | - help: consider introducing lifetime `'a` here: `<'a>` LL | y: &'a isize) | ^^ undeclared lifetime + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error: aborting due to 5 previous errors diff --git a/src/test/ui/where-clauses/where-lifetime-resolution.stderr b/src/test/ui/where-clauses/where-lifetime-resolution.stderr index 6c52664154bbf..a704fea282899 100644 --- a/src/test/ui/where-clauses/where-lifetime-resolution.stderr +++ b/src/test/ui/where-clauses/where-lifetime-resolution.stderr @@ -6,6 +6,8 @@ LL | fn f() where LL | for<'a> dyn Trait1<'a>: Trait1<'a>, // OK LL | (dyn for<'a> Trait1<'a>): Trait1<'a>, | ^^ undeclared lifetime + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error[E0261]: use of undeclared lifetime name `'b` --> $DIR/where-lifetime-resolution.rs:8:52 @@ -15,6 +17,8 @@ LL | fn f() where ... LL | for<'a> dyn for<'b> Trait2<'a, 'b>: Trait2<'a, 'b>, | ^^ undeclared lifetime + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes error: aborting due to 2 previous errors