Ban non-static in const generics in AST.
This commit is contained in:
parent
e85edd9a84
commit
a87ab48099
3 changed files with 34 additions and 33 deletions
|
@ -199,6 +199,11 @@ enum LifetimeRibKind {
|
||||||
/// This rib declares generic parameters.
|
/// This rib declares generic parameters.
|
||||||
Generics { parent: NodeId, span: Span, kind: LifetimeBinderKind },
|
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
|
/// For **Modern** cases, create a new anonymous region parameter
|
||||||
/// and reference that.
|
/// 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[TypeNS].push(Rib::new(ConstParamTyRibKind));
|
||||||
this.ribs[ValueNS].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[TypeNS].pop().unwrap();
|
||||||
this.ribs[ValueNS].pop().unwrap();
|
this.ribs[ValueNS].pop().unwrap();
|
||||||
|
|
||||||
if let Some(ref expr) = default {
|
if let Some(ref expr) = default {
|
||||||
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.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_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();
|
||||||
}
|
}
|
||||||
|
@ -1158,8 +1167,14 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let LifetimeRibKind::Item = rib.kind {
|
match rib.kind {
|
||||||
break;
|
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;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1886,6 +1886,21 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
||||||
|
|
||||||
err.emit();
|
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> {
|
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 {
|
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 let def::Res::Def(_, did) = trait_ref.trait_ref.path.res {
|
||||||
if [
|
if [
|
||||||
|
|
|
@ -164,8 +164,6 @@ crate struct LifetimeContext<'a, 'tcx> {
|
||||||
map: &'a mut NamedRegionMap,
|
map: &'a mut NamedRegionMap,
|
||||||
scope: ScopeRef<'a>,
|
scope: ScopeRef<'a>,
|
||||||
|
|
||||||
is_in_const_generic: bool,
|
|
||||||
|
|
||||||
/// Indicates that we only care about the definition of a trait. This should
|
/// 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
|
/// be false if the `Item` we are resolving lifetimes for is not a trait or
|
||||||
/// we eventually need lifetimes resolve for trait items.
|
/// we eventually need lifetimes resolve for trait items.
|
||||||
|
@ -452,7 +450,6 @@ fn do_resolve(
|
||||||
tcx,
|
tcx,
|
||||||
map: &mut named_region_map,
|
map: &mut named_region_map,
|
||||||
scope: ROOT_SCOPE,
|
scope: ROOT_SCOPE,
|
||||||
is_in_const_generic: false,
|
|
||||||
trait_definition_only,
|
trait_definition_only,
|
||||||
labels_in_fn: vec![],
|
labels_in_fn: vec![],
|
||||||
xcrate_object_lifetime_defaults: Default::default(),
|
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);
|
self.insert_lifetime(lifetime_ref, Region::Static);
|
||||||
return;
|
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);
|
self.resolve_lifetime_ref(lifetime_ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1341,14 +1334,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GenericParamKind::Const { ref ty, default } => {
|
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);
|
walk_list!(this, visit_param_bound, param.bounds);
|
||||||
this.visit_ty(&ty);
|
this.visit_ty(&ty);
|
||||||
if let Some(default) = default {
|
if let Some(default) = default {
|
||||||
this.visit_body(this.tcx.hir().body(default.body));
|
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,
|
tcx: *tcx,
|
||||||
map,
|
map,
|
||||||
scope: &wrap_scope,
|
scope: &wrap_scope,
|
||||||
is_in_const_generic: self.is_in_const_generic,
|
|
||||||
trait_definition_only: self.trait_definition_only,
|
trait_definition_only: self.trait_definition_only,
|
||||||
labels_in_fn,
|
labels_in_fn,
|
||||||
xcrate_object_lifetime_defaults,
|
xcrate_object_lifetime_defaults,
|
||||||
|
|
Loading…
Add table
Reference in a new issue