1
Fork 0

resolve: prohibit anon const non-static lifetimes

This commit modifies name resolution to emit an error when non-static
lifetimes are used in anonymous constants when the `min_const_generics`
feature is enabled.

Signed-off-by: David Wood <david@davidtw.co>
This commit is contained in:
David Wood 2020-09-15 14:38:41 +01:00
parent 154f1f544d
commit eacfb2b265
No known key found for this signature in database
GPG key ID: 2592E76C87381FD9
4 changed files with 81 additions and 0 deletions

View file

@ -16,6 +16,7 @@ use rustc_hir::def::{self, CtorKind, DefKind};
use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::PrimTy; use rustc_hir::PrimTy;
use rustc_session::config::nightly_options; use rustc_session::config::nightly_options;
use rustc_session::parse::feature_err;
use rustc_span::hygiene::MacroKind; use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{BytePos, Span, DUMMY_SP}; use rustc_span::{BytePos, Span, DUMMY_SP};
@ -1599,4 +1600,32 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
_ => {} _ => {}
} }
} }
/// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics` so
/// this function will emit an error if `min_const_generics` is enabled, the body identified by
/// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
crate fn maybe_emit_forbidden_non_static_lifetime_error(
&self,
body_id: hir::BodyId,
lifetime_ref: &'tcx hir::Lifetime,
) {
let is_anon_const = matches!(
self.tcx.def_kind(self.tcx.hir().body_owner_def_id(body_id)),
hir::def::DefKind::AnonConst
);
let is_allowed_lifetime = matches!(
lifetime_ref.name,
hir::LifetimeName::Implicit | hir::LifetimeName::Static | hir::LifetimeName::Underscore
);
if self.tcx.features().min_const_generics && is_anon_const && !is_allowed_lifetime {
feature_err(
&self.tcx.sess.parse_sess,
sym::const_generics,
lifetime_ref.span,
"a non-static lifetime is not allowed in a `const`",
)
.emit();
}
}
} }

View file

@ -1777,6 +1777,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
let result = loop { let result = loop {
match *scope { match *scope {
Scope::Body { id, s } => { Scope::Body { id, s } => {
// Non-static lifetimes are prohibited in anonymous constants under
// `min_const_generics`.
self.maybe_emit_forbidden_non_static_lifetime_error(id, lifetime_ref);
outermost_body = Some(id); outermost_body = Some(id);
scope = s; scope = s;
} }

View file

@ -0,0 +1,27 @@
#![feature(min_const_generics)]
// This test checks that non-static lifetimes are prohibited under `min_const_generics`. It
// currently emits an error with `min_const_generics`. This will ICE under `const_generics`.
fn test<const N: usize>() {}
fn issue_75323_and_74447_1<'a>() -> &'a () {
test::<{ let _: &'a (); 3 },>();
//~^ ERROR a non-static lifetime is not allowed in a `const`
&()
}
fn issue_75323_and_74447_2() {
test::<{ let _: &(); 3 },>();
}
fn issue_75323_and_74447_3() {
test::<{ let _: &'static (); 3 },>();
}
fn issue_73375<'a>() {
[(); (|_: &'a u8| (), 0).1];
//~^ ERROR a non-static lifetime is not allowed in a `const`
}
fn main() {}

View file

@ -0,0 +1,21 @@
error[E0658]: a non-static lifetime is not allowed in a `const`
--> $DIR/forbid-non-static-lifetimes.rs:9:22
|
LL | test::<{ let _: &'a (); 3 },>();
| ^^
|
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error[E0658]: a non-static lifetime is not allowed in a `const`
--> $DIR/forbid-non-static-lifetimes.rs:23:16
|
LL | [(); (|_: &'a u8| (), 0).1];
| ^^
|
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.