From b4fddf0f0806662430b42cb5b226ac1e3d381026 Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Sun, 12 Jan 2020 15:55:12 +1300 Subject: [PATCH 1/3] Forbid elided lifetimes within const generic parameter types. --- src/librustc_ast_lowering/lib.rs | 14 ++++--- .../const-param-elided-lifetime.rs | 19 +++++++++ .../const-param-elided-lifetime.stderr | 40 +++++++++++++++++++ 3 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/const-generics/const-param-elided-lifetime.rs create mode 100644 src/test/ui/const-generics/const-param-elided-lifetime.stderr diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 58b8e8a089ad3..9775871a11bfe 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -2121,12 +2121,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { (hir::ParamName::Plain(param.ident), kind) } - GenericParamKind::Const { ref ty } => ( - hir::ParamName::Plain(param.ident), - hir::GenericParamKind::Const { - ty: self.lower_ty(&ty, ImplTraitContext::disallowed()), - }, - ), + GenericParamKind::Const { ref ty } => { + let ty = self + .with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| { + this.lower_ty(&ty, ImplTraitContext::disallowed()) + }); + + (hir::ParamName::Plain(param.ident), hir::GenericParamKind::Const { ty }) + } }; hir::GenericParam { diff --git a/src/test/ui/const-generics/const-param-elided-lifetime.rs b/src/test/ui/const-generics/const-param-elided-lifetime.rs new file mode 100644 index 0000000000000..ff98368bca280 --- /dev/null +++ b/src/test/ui/const-generics/const-param-elided-lifetime.rs @@ -0,0 +1,19 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +struct A; +//~^ ERROR `&` without an explicit lifetime name cannot be used here +trait B {} + +impl A { //~ ERROR `&` without an explicit lifetime name cannot be used here + fn foo(&self) {} + //~^ ERROR `&` without an explicit lifetime name cannot be used here +} + +impl B for A {} +//~^ ERROR `&` without an explicit lifetime name cannot be used here + +fn bar() {} +//~^ ERROR `&` without an explicit lifetime name cannot be used here + +fn main() {} diff --git a/src/test/ui/const-generics/const-param-elided-lifetime.stderr b/src/test/ui/const-generics/const-param-elided-lifetime.stderr new file mode 100644 index 0000000000000..9f29dbf980a47 --- /dev/null +++ b/src/test/ui/const-generics/const-param-elided-lifetime.stderr @@ -0,0 +1,40 @@ +error[E0637]: `&` without an explicit lifetime name cannot be used here + --> $DIR/const-param-elided-lifetime.rs:4:19 + | +LL | struct A; + | ^ explicit lifetime name needed here + +error[E0637]: `&` without an explicit lifetime name cannot be used here + --> $DIR/const-param-elided-lifetime.rs:8:15 + | +LL | impl A { + | ^ explicit lifetime name needed here + +error[E0637]: `&` without an explicit lifetime name cannot be used here + --> $DIR/const-param-elided-lifetime.rs:9:21 + | +LL | fn foo(&self) {} + | ^ explicit lifetime name needed here + +error[E0637]: `&` without an explicit lifetime name cannot be used here + --> $DIR/const-param-elided-lifetime.rs:13:15 + | +LL | impl B for A {} + | ^ explicit lifetime name needed here + +error[E0637]: `&` without an explicit lifetime name cannot be used here + --> $DIR/const-param-elided-lifetime.rs:16:17 + | +LL | fn bar() {} + | ^ explicit lifetime name needed here + +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/const-param-elided-lifetime.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + +error: aborting due to 5 previous errors + From 9e46ddc7a2c1bcef52bfa9e4ae547b296814e2b9 Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Sun, 12 Jan 2020 17:32:50 +1300 Subject: [PATCH 2/3] Added comment about behaviour. --- src/test/ui/const-generics/const-param-elided-lifetime.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/ui/const-generics/const-param-elided-lifetime.rs b/src/test/ui/const-generics/const-param-elided-lifetime.rs index ff98368bca280..5679dd35c307a 100644 --- a/src/test/ui/const-generics/const-param-elided-lifetime.rs +++ b/src/test/ui/const-generics/const-param-elided-lifetime.rs @@ -1,3 +1,8 @@ +// Elided lifetimes within the type of a const generic parameters is disallowed. This matches the +// behaviour of trait bounds where `fn foo>() {}` is illegal. Though we could change +// elided lifetimes within the type of a const generic parameters to be 'static, like elided +// lifetimes within const/static items. + #![feature(const_generics)] //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash From 82b90bd9938fb56452b8a10bd004ad84a0f81503 Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Sun, 12 Jan 2020 20:41:03 +1300 Subject: [PATCH 3/3] Update test benchmark file --- .../const-param-elided-lifetime.stderr | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/ui/const-generics/const-param-elided-lifetime.stderr b/src/test/ui/const-generics/const-param-elided-lifetime.stderr index 9f29dbf980a47..93133c507fe40 100644 --- a/src/test/ui/const-generics/const-param-elided-lifetime.stderr +++ b/src/test/ui/const-generics/const-param-elided-lifetime.stderr @@ -1,35 +1,35 @@ error[E0637]: `&` without an explicit lifetime name cannot be used here - --> $DIR/const-param-elided-lifetime.rs:4:19 + --> $DIR/const-param-elided-lifetime.rs:9:19 | LL | struct A; | ^ explicit lifetime name needed here error[E0637]: `&` without an explicit lifetime name cannot be used here - --> $DIR/const-param-elided-lifetime.rs:8:15 + --> $DIR/const-param-elided-lifetime.rs:13:15 | LL | impl A { | ^ explicit lifetime name needed here error[E0637]: `&` without an explicit lifetime name cannot be used here - --> $DIR/const-param-elided-lifetime.rs:9:21 + --> $DIR/const-param-elided-lifetime.rs:14:21 | LL | fn foo(&self) {} | ^ explicit lifetime name needed here error[E0637]: `&` without an explicit lifetime name cannot be used here - --> $DIR/const-param-elided-lifetime.rs:13:15 + --> $DIR/const-param-elided-lifetime.rs:18:15 | LL | impl B for A {} | ^ explicit lifetime name needed here error[E0637]: `&` without an explicit lifetime name cannot be used here - --> $DIR/const-param-elided-lifetime.rs:16:17 + --> $DIR/const-param-elided-lifetime.rs:21:17 | LL | fn bar() {} | ^ explicit lifetime name needed here warning: the feature `const_generics` is incomplete and may cause the compiler to crash - --> $DIR/const-param-elided-lifetime.rs:1:12 + --> $DIR/const-param-elided-lifetime.rs:6:12 | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^