mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 11:48:30 +00:00
Rollup merge of #76739 - davidtwco:issue-75323-non-static-lifetime-in-anonconst, r=varkor
resolve: prohibit anon const non-static lifetimes Fixes #75323, fixes #74447 and fixes #73375. This PR prohibits non-static lifetimes in anonymous constants when only the `min_const_generics` feature is enabled. ~~To do so, `to_region_vid`'s `bug!` had to be changed into a delayed bug, which unfortunately required providing it a `TyCtxt`.~~ --- ~~While I am happy with how the implementation of the error turned out in `rustc_passes::check_const`, emitting an error wasn't sufficient to avoid hitting the ICE later. I also tried implementing the error in `rustc_mir::transform::check_consts::validation` and that worked, but it didn't silence the ICE either. To silence the ICE, I changed it to a delayed bug which worked but was more invasive that I would have liked, and required I return an incorrect lifetime. It's possible that this check should be implemented earlier in the compiler to make the invasive changes unnecessary, but I wasn't sure where that would be and wanted to get some feedback first.~~ The approach taken by this PR has been changed to implement the error in name resolution, which ended up being much simpler. cc @rust-lang/wg-const-eval r? @lcnr
This commit is contained in:
commit
c8eb2059da
@ -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::PrimTy;
|
||||
use rustc_session::config::nightly_options;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::hygiene::MacroKind;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1777,6 +1777,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
let result = loop {
|
||||
match *scope {
|
||||
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);
|
||||
scope = s;
|
||||
}
|
||||
|
@ -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() {}
|
@ -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`.
|
Loading…
Reference in New Issue
Block a user