Ban non-static in const generics in AST.

This commit is contained in:
Camille GILLOT 2021-12-05 00:07:21 +01:00
parent e85edd9a84
commit a87ab48099
3 changed files with 34 additions and 33 deletions

View File

@ -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;
}
_ => {}
}
}

View File

@ -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 \
<https://github.com/rust-lang/rust/issues/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 \
<https://github.com/rust-lang/rust/issues/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 [

View File

@ -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,