Skip to content

Commit

Permalink
Rollup merge of #76739 - davidtwco:issue-75323-non-static-lifetime-in…
Browse files Browse the repository at this point in the history
…-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
  • Loading branch information
jonas-schievink authored Oct 2, 2020
2 parents 17c9b71 + eacfb2b commit c8eb205
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 0 deletions.
29 changes: 29 additions & 0 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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();
}
}
}
4 changes: 4 additions & 0 deletions compiler/rustc_resolve/src/late/lifetimes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit c8eb205

Please sign in to comment.