Skip to content

Commit 76d4862

Browse files
committed
Auto merge of #95776 - cjgillot:ast-lifetimes-static, r=petrochenkov
Enforce static lifetimes in consts during late resolution This PR moves the handling of implicitly and explicitly static lifetimes in constants from HIR to the AST.
2 parents 9a98c63 + 7d990a8 commit 76d4862

File tree

8 files changed

+314
-146
lines changed

8 files changed

+314
-146
lines changed

compiler/rustc_resolve/src/late.rs

+39-9
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,16 @@ enum LifetimeRibKind {
199199
/// This rib declares generic parameters.
200200
Generics { parent: NodeId, span: Span, kind: LifetimeBinderKind },
201201

202+
/// FIXME(const_generics): This patches over an ICE caused by non-'static lifetimes in const
203+
/// generics. We are disallowing this until we can decide on how we want to handle non-'static
204+
/// lifetimes in const generics. See issue #74052 for discussion.
205+
ConstGeneric,
206+
207+
/// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
208+
/// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by
209+
/// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
210+
AnonConst,
211+
202212
/// For **Modern** cases, create a new anonymous region parameter
203213
/// and reference that.
204214
///
@@ -527,7 +537,9 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
527537
}
528538
fn visit_anon_const(&mut self, constant: &'ast AnonConst) {
529539
// We deal with repeat expressions explicitly in `resolve_expr`.
530-
self.resolve_anon_const(constant, IsRepeatExpr::No);
540+
self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| {
541+
this.resolve_anon_const(constant, IsRepeatExpr::No);
542+
})
531543
}
532544
fn visit_expr(&mut self, expr: &'ast Expr) {
533545
self.resolve_expr(expr, None);
@@ -1102,14 +1114,18 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
11021114

11031115
this.ribs[TypeNS].push(Rib::new(ConstParamTyRibKind));
11041116
this.ribs[ValueNS].push(Rib::new(ConstParamTyRibKind));
1105-
this.visit_ty(ty);
1117+
this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| {
1118+
this.visit_ty(ty)
1119+
});
11061120
this.ribs[TypeNS].pop().unwrap();
11071121
this.ribs[ValueNS].pop().unwrap();
11081122

11091123
if let Some(ref expr) = default {
11101124
this.ribs[TypeNS].push(forward_ty_ban_rib);
11111125
this.ribs[ValueNS].push(forward_const_ban_rib);
1112-
this.visit_anon_const(expr);
1126+
this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| {
1127+
this.resolve_anon_const(expr, IsRepeatExpr::No)
1128+
});
11131129
forward_const_ban_rib = this.ribs[ValueNS].pop().unwrap();
11141130
forward_ty_ban_rib = this.ribs[TypeNS].pop().unwrap();
11151131
}
@@ -1158,8 +1174,19 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
11581174
return;
11591175
}
11601176

1161-
if let LifetimeRibKind::Item = rib.kind {
1162-
break;
1177+
match rib.kind {
1178+
LifetimeRibKind::Item => break,
1179+
LifetimeRibKind::ConstGeneric => {
1180+
self.emit_non_static_lt_in_const_generic_error(lifetime);
1181+
self.r.lifetimes_res_map.insert(lifetime.id, LifetimeRes::Error);
1182+
return;
1183+
}
1184+
LifetimeRibKind::AnonConst => {
1185+
self.maybe_emit_forbidden_non_static_lifetime_error(lifetime);
1186+
self.r.lifetimes_res_map.insert(lifetime.id, LifetimeRes::Error);
1187+
return;
1188+
}
1189+
_ => {}
11631190
}
11641191
}
11651192

@@ -3065,9 +3092,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
30653092
is_repeat,
30663093
constant.value.is_potential_trivial_const_param(),
30673094
None,
3068-
|this| {
3069-
visit::walk_anon_const(this, constant);
3070-
},
3095+
|this| visit::walk_anon_const(this, constant),
30713096
);
30723097
}
30733098

@@ -3218,7 +3243,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
32183243
}
32193244
ExprKind::Repeat(ref elem, ref ct) => {
32203245
self.visit_expr(elem);
3221-
self.resolve_anon_const(ct, IsRepeatExpr::Yes);
3246+
self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| {
3247+
this.resolve_anon_const(ct, IsRepeatExpr::Yes)
3248+
});
3249+
}
3250+
ExprKind::ConstBlock(ref ct) => {
3251+
self.resolve_anon_const(ct, IsRepeatExpr::No);
32223252
}
32233253
ExprKind::Index(ref elem, ref idx) => {
32243254
self.resolve_expr(elem, Some(expr));

compiler/rustc_resolve/src/late/diagnostics.rs

+31-46
Original file line numberDiff line numberDiff line change
@@ -1886,6 +1886,37 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
18861886

18871887
err.emit();
18881888
}
1889+
1890+
crate fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &ast::Lifetime) {
1891+
struct_span_err!(
1892+
self.r.session,
1893+
lifetime_ref.ident.span,
1894+
E0771,
1895+
"use of non-static lifetime `{}` in const generic",
1896+
lifetime_ref.ident
1897+
)
1898+
.note(
1899+
"for more information, see issue #74052 \
1900+
<https://github.com/rust-lang/rust/issues/74052>",
1901+
)
1902+
.emit();
1903+
}
1904+
1905+
/// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
1906+
/// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by
1907+
/// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
1908+
crate fn maybe_emit_forbidden_non_static_lifetime_error(&self, lifetime_ref: &ast::Lifetime) {
1909+
let feature_active = self.r.session.features_untracked().generic_const_exprs;
1910+
if !feature_active {
1911+
feature_err(
1912+
&self.r.session.parse_sess,
1913+
sym::generic_const_exprs,
1914+
lifetime_ref.ident.span,
1915+
"a non-static lifetime is not allowed in a `const`",
1916+
)
1917+
.emit();
1918+
}
1919+
}
18891920
}
18901921

18911922
impl<'tcx> LifetimeContext<'_, 'tcx> {
@@ -1982,24 +2013,6 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
19822013
}
19832014
}
19842015

1985-
// FIXME(const_generics): This patches over an ICE caused by non-'static lifetimes in const
1986-
// generics. We are disallowing this until we can decide on how we want to handle non-'static
1987-
// lifetimes in const generics. See issue #74052 for discussion.
1988-
crate fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &hir::Lifetime) {
1989-
let mut err = struct_span_err!(
1990-
self.tcx.sess,
1991-
lifetime_ref.span,
1992-
E0771,
1993-
"use of non-static lifetime `{}` in const generic",
1994-
lifetime_ref
1995-
);
1996-
err.note(
1997-
"for more information, see issue #74052 \
1998-
<https://github.com/rust-lang/rust/issues/74052>",
1999-
);
2000-
err.emit();
2001-
}
2002-
20032016
crate fn is_trait_ref_fn_scope(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) -> bool {
20042017
if let def::Res::Def(_, did) = trait_ref.trait_ref.path.res {
20052018
if [
@@ -2401,32 +2414,4 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
24012414
_ => unreachable!(),
24022415
}
24032416
}
2404-
2405-
/// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
2406-
/// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by
2407-
/// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
2408-
crate fn maybe_emit_forbidden_non_static_lifetime_error(
2409-
&self,
2410-
body_id: hir::BodyId,
2411-
lifetime_ref: &'tcx hir::Lifetime,
2412-
) {
2413-
let is_anon_const = matches!(
2414-
self.tcx.def_kind(self.tcx.hir().body_owner_def_id(body_id)),
2415-
hir::def::DefKind::AnonConst
2416-
);
2417-
let is_allowed_lifetime = matches!(
2418-
lifetime_ref.name,
2419-
hir::LifetimeName::Implicit | hir::LifetimeName::Static | hir::LifetimeName::Underscore
2420-
);
2421-
2422-
if !self.tcx.lazy_normalization() && is_anon_const && !is_allowed_lifetime {
2423-
feature_err(
2424-
&self.tcx.sess.parse_sess,
2425-
sym::generic_const_exprs,
2426-
lifetime_ref.span,
2427-
"a non-static lifetime is not allowed in a `const`",
2428-
)
2429-
.emit();
2430-
}
2431-
}
24322417
}

compiler/rustc_resolve/src/late/lifetimes.rs

-15
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,6 @@ crate struct LifetimeContext<'a, 'tcx> {
164164
map: &'a mut NamedRegionMap,
165165
scope: ScopeRef<'a>,
166166

167-
is_in_const_generic: bool,
168-
169167
/// Indicates that we only care about the definition of a trait. This should
170168
/// be false if the `Item` we are resolving lifetimes for is not a trait or
171169
/// we eventually need lifetimes resolve for trait items.
@@ -452,7 +450,6 @@ fn do_resolve(
452450
tcx,
453451
map: &mut named_region_map,
454452
scope: ROOT_SCOPE,
455-
is_in_const_generic: false,
456453
trait_definition_only,
457454
labels_in_fn: vec![],
458455
xcrate_object_lifetime_defaults: Default::default(),
@@ -1266,10 +1263,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
12661263
self.insert_lifetime(lifetime_ref, Region::Static);
12671264
return;
12681265
}
1269-
if self.is_in_const_generic && lifetime_ref.name != LifetimeName::Error {
1270-
self.emit_non_static_lt_in_const_generic_error(lifetime_ref);
1271-
return;
1272-
}
12731266
self.resolve_lifetime_ref(lifetime_ref);
12741267
}
12751268

@@ -1341,14 +1334,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
13411334
}
13421335
}
13431336
GenericParamKind::Const { ref ty, default } => {
1344-
let was_in_const_generic = this.is_in_const_generic;
1345-
this.is_in_const_generic = true;
13461337
walk_list!(this, visit_param_bound, param.bounds);
13471338
this.visit_ty(&ty);
13481339
if let Some(default) = default {
13491340
this.visit_body(this.tcx.hir().body(default.body));
13501341
}
1351-
this.is_in_const_generic = was_in_const_generic;
13521342
}
13531343
}
13541344
}
@@ -1798,7 +1788,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
17981788
tcx: *tcx,
17991789
map,
18001790
scope: &wrap_scope,
1801-
is_in_const_generic: self.is_in_const_generic,
18021791
trait_definition_only: self.trait_definition_only,
18031792
labels_in_fn,
18041793
xcrate_object_lifetime_defaults,
@@ -2254,10 +2243,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
22542243
let result = loop {
22552244
match *scope {
22562245
Scope::Body { id, s } => {
2257-
// Non-static lifetimes are prohibited in anonymous constants without
2258-
// `generic_const_exprs`.
2259-
self.maybe_emit_forbidden_non_static_lifetime_error(id, lifetime_ref);
2260-
22612246
outermost_body = Some(id);
22622247
scope = s;
22632248
}

0 commit comments

Comments
 (0)