mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
Ban non-static lifetimes from AnonConst on AST.
The extra diagnostics come from the compiler no longer aborting before typeck.
This commit is contained in:
parent
b711723d41
commit
865d0fef2f
@ -204,6 +204,11 @@ enum LifetimeRibKind {
|
|||||||
/// lifetimes in const generics. See issue #74052 for discussion.
|
/// lifetimes in const generics. See issue #74052 for discussion.
|
||||||
ConstGeneric,
|
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
|
/// For **Modern** cases, create a new anonymous region parameter
|
||||||
/// and reference that.
|
/// 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) {
|
fn visit_anon_const(&mut self, constant: &'ast AnonConst) {
|
||||||
// We deal with repeat expressions explicitly in `resolve_expr`.
|
// 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) {
|
fn visit_expr(&mut self, expr: &'ast Expr) {
|
||||||
self.resolve_expr(expr, None);
|
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[TypeNS].push(forward_ty_ban_rib);
|
||||||
this.ribs[ValueNS].push(forward_const_ban_rib);
|
this.ribs[ValueNS].push(forward_const_ban_rib);
|
||||||
this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| {
|
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_const_ban_rib = this.ribs[ValueNS].pop().unwrap();
|
||||||
forward_ty_ban_rib = this.ribs[TypeNS].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);
|
self.r.lifetimes_res_map.insert(lifetime.id, LifetimeRes::Error);
|
||||||
return;
|
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,
|
is_repeat,
|
||||||
constant.value.is_potential_trivial_const_param(),
|
constant.value.is_potential_trivial_const_param(),
|
||||||
None,
|
None,
|
||||||
|this| {
|
|this| visit::walk_anon_const(this, constant),
|
||||||
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) => {
|
ExprKind::Repeat(ref elem, ref ct) => {
|
||||||
self.visit_expr(elem);
|
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) => {
|
ExprKind::Index(ref elem, ref idx) => {
|
||||||
self.resolve_expr(elem, Some(expr));
|
self.resolve_expr(elem, Some(expr));
|
||||||
|
@ -1901,6 +1901,22 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
|||||||
)
|
)
|
||||||
.emit();
|
.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> {
|
impl<'tcx> LifetimeContext<'_, 'tcx> {
|
||||||
@ -2398,32 +2414,4 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
|
|||||||
_ => unreachable!(),
|
_ => 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2243,10 +2243,6 @@ 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 without
|
|
||||||
// `generic_const_exprs`.
|
|
||||||
self.maybe_emit_forbidden_non_static_lifetime_error(id, lifetime_ref);
|
|
||||||
|
|
||||||
outermost_body = Some(id);
|
outermost_body = Some(id);
|
||||||
scope = s;
|
scope = s;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user