From a87ab480999e21de80b12ad6de6a777c70bebaab Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 5 Dec 2021 00:07:21 +0100 Subject: [PATCH] Ban non-static in const generics in AST. --- compiler/rustc_resolve/src/late.rs | 23 ++++++++++--- .../rustc_resolve/src/late/diagnostics.rs | 33 +++++++++---------- compiler/rustc_resolve/src/late/lifetimes.rs | 11 ------- 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 9ea66c0b59d..f5e8eca8fcb 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -199,6 +199,11 @@ enum LifetimeRibKind { /// This rib declares generic parameters. Generics { parent: NodeId, span: Span, kind: LifetimeBinderKind }, + /// FIXME(const_generics): This patches over an ICE caused by non-'static lifetimes in const + /// generics. We are disallowing this until we can decide on how we want to handle non-'static + /// lifetimes in const generics. See issue #74052 for discussion. + ConstGeneric, + /// For **Modern** cases, create a new anonymous region parameter /// and reference that. /// @@ -1102,14 +1107,18 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { this.ribs[TypeNS].push(Rib::new(ConstParamTyRibKind)); this.ribs[ValueNS].push(Rib::new(ConstParamTyRibKind)); - this.visit_ty(ty); + this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| { + this.visit_ty(ty) + }); this.ribs[TypeNS].pop().unwrap(); this.ribs[ValueNS].pop().unwrap(); if let Some(ref expr) = default { this.ribs[TypeNS].push(forward_ty_ban_rib); this.ribs[ValueNS].push(forward_const_ban_rib); - this.visit_anon_const(expr); + this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| { + this.visit_anon_const(expr) + }); forward_const_ban_rib = this.ribs[ValueNS].pop().unwrap(); forward_ty_ban_rib = this.ribs[TypeNS].pop().unwrap(); } @@ -1158,8 +1167,14 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { return; } - if let LifetimeRibKind::Item = rib.kind { - break; + match rib.kind { + LifetimeRibKind::Item => break, + LifetimeRibKind::ConstGeneric => { + self.emit_non_static_lt_in_const_generic_error(lifetime); + self.r.lifetimes_res_map.insert(lifetime.id, LifetimeRes::Error); + return; + } + _ => {} } } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a9edb713b0d..b153c9f9526 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1886,6 +1886,21 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.emit(); } + + crate fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &ast::Lifetime) { + struct_span_err!( + self.r.session, + lifetime_ref.ident.span, + E0771, + "use of non-static lifetime `{}` in const generic", + lifetime_ref.ident + ) + .note( + "for more information, see issue #74052 \ + ", + ) + .emit(); + } } impl<'tcx> LifetimeContext<'_, 'tcx> { @@ -1982,24 +1997,6 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { } } - // FIXME(const_generics): This patches over an ICE caused by non-'static lifetimes in const - // generics. We are disallowing this until we can decide on how we want to handle non-'static - // lifetimes in const generics. See issue #74052 for discussion. - crate fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &hir::Lifetime) { - let mut err = struct_span_err!( - self.tcx.sess, - lifetime_ref.span, - E0771, - "use of non-static lifetime `{}` in const generic", - lifetime_ref - ); - err.note( - "for more information, see issue #74052 \ - ", - ); - err.emit(); - } - crate fn is_trait_ref_fn_scope(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) -> bool { if let def::Res::Def(_, did) = trait_ref.trait_ref.path.res { if [ diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index ce3069265d0..6bb0c3b5e6b 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -164,8 +164,6 @@ crate struct LifetimeContext<'a, 'tcx> { map: &'a mut NamedRegionMap, scope: ScopeRef<'a>, - is_in_const_generic: bool, - /// Indicates that we only care about the definition of a trait. This should /// be false if the `Item` we are resolving lifetimes for is not a trait or /// we eventually need lifetimes resolve for trait items. @@ -452,7 +450,6 @@ fn do_resolve( tcx, map: &mut named_region_map, scope: ROOT_SCOPE, - is_in_const_generic: false, trait_definition_only, labels_in_fn: vec![], xcrate_object_lifetime_defaults: Default::default(), @@ -1266,10 +1263,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.insert_lifetime(lifetime_ref, Region::Static); return; } - if self.is_in_const_generic && lifetime_ref.name != LifetimeName::Error { - self.emit_non_static_lt_in_const_generic_error(lifetime_ref); - return; - } self.resolve_lifetime_ref(lifetime_ref); } @@ -1341,14 +1334,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } } GenericParamKind::Const { ref ty, default } => { - let was_in_const_generic = this.is_in_const_generic; - this.is_in_const_generic = true; walk_list!(this, visit_param_bound, param.bounds); this.visit_ty(&ty); if let Some(default) = default { this.visit_body(this.tcx.hir().body(default.body)); } - this.is_in_const_generic = was_in_const_generic; } } } @@ -1798,7 +1788,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { tcx: *tcx, map, scope: &wrap_scope, - is_in_const_generic: self.is_in_const_generic, trait_definition_only: self.trait_definition_only, labels_in_fn, xcrate_object_lifetime_defaults,