about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <huyuumi.dev@gmail.com>2020-01-14 14:02:23 +0900
committerGitHub <noreply@github.com>2020-01-14 14:02:23 +0900
commitd7e599203c3d3abbc3be486792a76cb89d3fa067 (patch)
tree897b1ec459167b5022011e2ce5cfeaf3bedc7255
parent7da1dcc3e0eee606b61ac7f7039b39b3332dfb6f (diff)
parent82b90bd9938fb56452b8a10bd004ad84a0f81503 (diff)
downloadrust-d7e599203c3d3abbc3be486792a76cb89d3fa067.tar.gz
rust-d7e599203c3d3abbc3be486792a76cb89d3fa067.zip
Rollup merge of #68143 - skinny121:const-param-type-elided-lifetime, r=petrochenkov
Forbid elided lifetimes within const generic parameter types

Disallows `fn foo<const T: &u32>()`, the lifetime must be explicitly given, i.e. `fn foo<const T: &'static u32>()`.

Fixes #67883
-rw-r--r--src/librustc_ast_lowering/lib.rs14
-rw-r--r--src/test/ui/const-generics/const-param-elided-lifetime.rs24
-rw-r--r--src/test/ui/const-generics/const-param-elided-lifetime.stderr40
3 files changed, 72 insertions, 6 deletions
diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs
index d30d0bd8345..76a0889c376 100644
--- a/src/librustc_ast_lowering/lib.rs
+++ b/src/librustc_ast_lowering/lib.rs
@@ -2120,12 +2120,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 00000000000..5679dd35c30
--- /dev/null
+++ b/src/test/ui/const-generics/const-param-elided-lifetime.rs
@@ -0,0 +1,24 @@
+// Elided lifetimes within the type of a const generic parameters is disallowed. This matches the
+// behaviour of trait bounds where `fn foo<T: Ord<&u8>>() {}` 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
+
+struct A<const N: &u8>;
+//~^ ERROR `&` without an explicit lifetime name cannot be used here
+trait B {}
+
+impl<const N: &u8> A<N> { //~ ERROR `&` without an explicit lifetime name cannot be used here
+    fn foo<const M: &u8>(&self) {}
+    //~^ ERROR `&` without an explicit lifetime name cannot be used here
+}
+
+impl<const N: &u8> B for A<N> {}
+//~^ ERROR `&` without an explicit lifetime name cannot be used here
+
+fn bar<const N: &u8>() {}
+//~^ 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 00000000000..93133c507fe
--- /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:9:19
+   |
+LL | struct A<const N: &u8>;
+   |                   ^ 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<const N: &u8> A<N> {
+   |               ^ explicit lifetime name needed here
+
+error[E0637]: `&` without an explicit lifetime name cannot be used here
+  --> $DIR/const-param-elided-lifetime.rs:14:21
+   |
+LL |     fn foo<const M: &u8>(&self) {}
+   |                     ^ explicit lifetime name needed here
+
+error[E0637]: `&` without an explicit lifetime name cannot be used here
+  --> $DIR/const-param-elided-lifetime.rs:18:15
+   |
+LL | impl<const N: &u8> B for A<N> {}
+   |               ^ explicit lifetime name needed here
+
+error[E0637]: `&` without an explicit lifetime name cannot be used here
+  --> $DIR/const-param-elided-lifetime.rs:21:17
+   |
+LL | fn bar<const N: &u8>() {}
+   |                 ^ 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:6:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: aborting due to 5 previous errors
+