diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index f5e8eca8fcb..9622553319d 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -204,6 +204,11 @@ enum LifetimeRibKind { /// lifetimes in const generics. See issue #74052 for discussion. ConstGeneric, + /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`. + /// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by + /// `body_id` is an anonymous constant and `lifetime_ref` is non-static. + AnonConst, + /// For **Modern** cases, create a new anonymous region parameter /// and reference that. /// @@ -532,7 +537,9 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { } fn visit_anon_const(&mut self, constant: &'ast AnonConst) { // We deal with repeat expressions explicitly in `resolve_expr`. - self.resolve_anon_const(constant, IsRepeatExpr::No); + self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| { + this.resolve_anon_const(constant, IsRepeatExpr::No); + }) } fn visit_expr(&mut self, expr: &'ast Expr) { self.resolve_expr(expr, None); @@ -1117,7 +1124,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { this.ribs[TypeNS].push(forward_ty_ban_rib); this.ribs[ValueNS].push(forward_const_ban_rib); this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| { - this.visit_anon_const(expr) + this.resolve_anon_const(expr, IsRepeatExpr::No) }); forward_const_ban_rib = this.ribs[ValueNS].pop().unwrap(); forward_ty_ban_rib = this.ribs[TypeNS].pop().unwrap(); @@ -1174,6 +1181,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { self.r.lifetimes_res_map.insert(lifetime.id, LifetimeRes::Error); return; } + LifetimeRibKind::AnonConst => { + self.maybe_emit_forbidden_non_static_lifetime_error(lifetime); + self.r.lifetimes_res_map.insert(lifetime.id, LifetimeRes::Error); + return; + } _ => {} } } @@ -3076,9 +3088,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { is_repeat, constant.value.is_potential_trivial_const_param(), None, - |this| { - visit::walk_anon_const(this, constant); - }, + |this| visit::walk_anon_const(this, constant), ); } @@ -3229,7 +3239,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { } ExprKind::Repeat(ref elem, ref ct) => { self.visit_expr(elem); - self.resolve_anon_const(ct, IsRepeatExpr::Yes); + self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| { + this.resolve_anon_const(ct, IsRepeatExpr::Yes) + }); + } + ExprKind::ConstBlock(ref ct) => { + self.resolve_anon_const(ct, IsRepeatExpr::No); } ExprKind::Index(ref elem, ref idx) => { self.resolve_expr(elem, Some(expr)); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index b153c9f9526..894ff0f17f8 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1901,6 +1901,22 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { ) .emit(); } + + /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`. + /// This function will emit an error if `generic_const_exprs` is not 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, lifetime_ref: &ast::Lifetime) { + let feature_active = self.r.session.features_untracked().generic_const_exprs; + if !feature_active { + feature_err( + &self.r.session.parse_sess, + sym::generic_const_exprs, + lifetime_ref.ident.span, + "a non-static lifetime is not allowed in a `const`", + ) + .emit(); + } + } } impl<'tcx> LifetimeContext<'_, 'tcx> { @@ -2398,32 +2414,4 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { _ => unreachable!(), } } - - /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`. - /// This function will emit an error if `generic_const_exprs` is not 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.lazy_normalization() && is_anon_const && !is_allowed_lifetime { - feature_err( - &self.tcx.sess.parse_sess, - sym::generic_const_exprs, - lifetime_ref.span, - "a non-static lifetime is not allowed in a `const`", - ) - .emit(); - } - } } diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 6bb0c3b5e6b..35a40a0a321 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -2243,10 +2243,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let result = loop { match *scope { Scope::Body { id, s } => { - // Non-static lifetimes are prohibited in anonymous constants without - // `generic_const_exprs`. - self.maybe_emit_forbidden_non_static_lifetime_error(id, lifetime_ref); - outermost_body = Some(id); scope = s; }