Skip to content

Commit cb0e8eb

Browse files
committed
Resolve generic consts
1 parent 7422b86 commit cb0e8eb

File tree

1 file changed

+128
-59
lines changed

1 file changed

+128
-59
lines changed

compiler/rustc_resolve/src/late.rs

Lines changed: 128 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2401,32 +2401,70 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
24012401
});
24022402
}
24032403

2404-
ItemKind::Static(box ast::StaticItem { ref ty, ref expr, .. })
2405-
| ItemKind::Const(box ast::ConstItem { ref ty, ref expr, .. }) => {
2404+
ItemKind::Static(box ast::StaticItem { ref ty, ref expr, .. }) => {
24062405
self.with_static_rib(|this| {
24072406
this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| {
24082407
this.visit_ty(ty);
24092408
});
24102409
this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
24112410
if let Some(expr) = expr {
2412-
let constant_item_kind = match item.kind {
2413-
ItemKind::Const(..) => ConstantItemKind::Const,
2414-
ItemKind::Static(..) => ConstantItemKind::Static,
2415-
_ => unreachable!(),
2416-
};
24172411
// We already forbid generic params because of the above item rib,
24182412
// so it doesn't matter whether this is a trivial constant.
24192413
this.with_constant_rib(
24202414
IsRepeatExpr::No,
24212415
ConstantHasGenerics::Yes,
2422-
Some((item.ident, constant_item_kind)),
2416+
Some((item.ident, ConstantItemKind::Static)),
24232417
|this| this.visit_expr(expr),
24242418
);
24252419
}
24262420
});
24272421
});
24282422
}
24292423

2424+
ItemKind::Const(box ast::ConstItem { ref generics, ref ty, ref expr, .. }) => {
2425+
// FIXME(generic_consts): Is the ordering of ribs correct? Right now, it's
2426+
// STATIC <- LIFETIME_ANON_REPORT <- GENERICS <- LIFETIME_ELIDED_STATIC {,<- CONSTANT}
2427+
self.with_static_rib(|this| {
2428+
this.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
2429+
this.with_generic_param_rib(
2430+
&generics.params,
2431+
RibKind::Item(HasGenericParams::Yes(generics.span)),
2432+
LifetimeRibKind::Generics {
2433+
binder: item.id,
2434+
kind: LifetimeBinderKind::Item,
2435+
span: generics.span,
2436+
},
2437+
|this| {
2438+
this.with_lifetime_rib(
2439+
LifetimeRibKind::Elided(LifetimeRes::Static),
2440+
|this| {
2441+
this.visit_generics(generics);
2442+
this.visit_ty(ty);
2443+
},
2444+
);
2445+
2446+
this.with_lifetime_rib(
2447+
LifetimeRibKind::Elided(LifetimeRes::Infer),
2448+
|this| {
2449+
let Some(expr) = expr else { return; };
2450+
2451+
// FIXME(generic_consts): Is this still true?
2452+
// > We already forbid generic params because of the above item rib,
2453+
// > so it doesn't matter whether this is a trivial constant.
2454+
this.with_constant_rib(
2455+
IsRepeatExpr::No,
2456+
ConstantHasGenerics::Yes,
2457+
Some((item.ident, ConstantItemKind::Const)),
2458+
|this| this.visit_expr(expr),
2459+
)
2460+
},
2461+
);
2462+
},
2463+
);
2464+
})
2465+
})
2466+
}
2467+
24302468
ItemKind::Use(ref use_tree) => {
24312469
self.future_proof_import(use_tree);
24322470
}
@@ -2688,28 +2726,42 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
26882726
for item in trait_items {
26892727
self.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id));
26902728
match &item.kind {
2691-
AssocItemKind::Const(box ast::ConstItem { ty, expr, .. }) => {
2692-
self.visit_ty(ty);
2693-
// Only impose the restrictions of `ConstRibKind` for an
2694-
// actual constant expression in a provided default.
2695-
if let Some(expr) = expr {
2696-
// We allow arbitrary const expressions inside of associated consts,
2697-
// even if they are potentially not const evaluatable.
2698-
//
2699-
// Type parameters can already be used and as associated consts are
2700-
// not used as part of the type system, this is far less surprising.
2701-
self.with_lifetime_rib(
2702-
LifetimeRibKind::Elided(LifetimeRes::Infer),
2703-
|this| {
2704-
this.with_constant_rib(
2705-
IsRepeatExpr::No,
2706-
ConstantHasGenerics::Yes,
2707-
None,
2708-
|this| this.visit_expr(expr),
2709-
)
2710-
},
2711-
);
2712-
}
2729+
// FIXME(generic_consts): Reuse `walk_assoc_item` here somehow?
2730+
AssocItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
2731+
self.with_generic_param_rib(
2732+
&generics.params,
2733+
RibKind::AssocItem,
2734+
LifetimeRibKind::Generics {
2735+
binder: item.id,
2736+
span: generics.span,
2737+
kind: LifetimeBinderKind::Item,
2738+
},
2739+
|this| {
2740+
this.visit_generics(generics);
2741+
this.visit_ty(ty);
2742+
2743+
// Only impose the restrictions of `ConstRibKind` for an
2744+
// actual constant expression in a provided default.
2745+
if let Some(expr) = expr {
2746+
// We allow arbitrary const expressions inside of associated consts,
2747+
// even if they are potentially not const evaluatable.
2748+
//
2749+
// Type parameters can already be used and as associated consts are
2750+
// not used as part of the type system, this is far less surprising.
2751+
this.with_lifetime_rib(
2752+
LifetimeRibKind::Elided(LifetimeRes::Infer),
2753+
|this| {
2754+
this.with_constant_rib(
2755+
IsRepeatExpr::No,
2756+
ConstantHasGenerics::Yes,
2757+
None,
2758+
|this| this.visit_expr(expr),
2759+
)
2760+
},
2761+
);
2762+
}
2763+
},
2764+
);
27132765
}
27142766
AssocItemKind::Fn(box Fn { generics, .. }) => {
27152767
walk_assoc_item(self, generics, LifetimeBinderKind::Function, item);
@@ -2864,36 +2916,53 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
28642916
use crate::ResolutionError::*;
28652917
self.resolve_doc_links(&item.attrs, MaybeExported::ImplItem(trait_id.ok_or(&item.vis)));
28662918
match &item.kind {
2867-
AssocItemKind::Const(box ast::ConstItem { ty, expr, .. }) => {
2919+
// FIXME(generic_consts): Reuse `walk_assoc_item` here somehow?
2920+
AssocItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
28682921
debug!("resolve_implementation AssocItemKind::Const");
2869-
// If this is a trait impl, ensure the const
2870-
// exists in trait
2871-
self.check_trait_item(
2872-
item.id,
2873-
item.ident,
2874-
&item.kind,
2875-
ValueNS,
2876-
item.span,
2877-
seen_trait_items,
2878-
|i, s, c| ConstNotMemberOfTrait(i, s, c),
2879-
);
28802922

2881-
self.visit_ty(ty);
2882-
if let Some(expr) = expr {
2883-
// We allow arbitrary const expressions inside of associated consts,
2884-
// even if they are potentially not const evaluatable.
2885-
//
2886-
// Type parameters can already be used and as associated consts are
2887-
// not used as part of the type system, this is far less surprising.
2888-
self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
2889-
this.with_constant_rib(
2890-
IsRepeatExpr::No,
2891-
ConstantHasGenerics::Yes,
2892-
None,
2893-
|this| this.visit_expr(expr),
2894-
)
2895-
});
2896-
}
2923+
self.with_generic_param_rib(
2924+
&generics.params,
2925+
RibKind::AssocItem,
2926+
LifetimeRibKind::Generics {
2927+
binder: item.id,
2928+
span: generics.span,
2929+
kind: LifetimeBinderKind::Item,
2930+
},
2931+
|this| {
2932+
// If this is a trait impl, ensure the const
2933+
// exists in trait
2934+
this.check_trait_item(
2935+
item.id,
2936+
item.ident,
2937+
&item.kind,
2938+
ValueNS,
2939+
item.span,
2940+
seen_trait_items,
2941+
|i, s, c| ConstNotMemberOfTrait(i, s, c),
2942+
);
2943+
2944+
this.visit_generics(generics);
2945+
this.visit_ty(ty);
2946+
if let Some(expr) = expr {
2947+
// We allow arbitrary const expressions inside of associated consts,
2948+
// even if they are potentially not const evaluatable.
2949+
//
2950+
// Type parameters can already be used and as associated consts are
2951+
// not used as part of the type system, this is far less surprising.
2952+
this.with_lifetime_rib(
2953+
LifetimeRibKind::Elided(LifetimeRes::Infer),
2954+
|this| {
2955+
this.with_constant_rib(
2956+
IsRepeatExpr::No,
2957+
ConstantHasGenerics::Yes,
2958+
None,
2959+
|this| this.visit_expr(expr),
2960+
)
2961+
},
2962+
);
2963+
}
2964+
},
2965+
);
28972966
}
28982967
AssocItemKind::Fn(box Fn { generics, .. }) => {
28992968
debug!("resolve_implementation AssocItemKind::Fn");
@@ -4430,6 +4499,7 @@ impl<'ast> Visitor<'ast> for LifetimeCountVisitor<'_, '_, '_> {
44304499
fn visit_item(&mut self, item: &'ast Item) {
44314500
match &item.kind {
44324501
ItemKind::TyAlias(box TyAlias { ref generics, .. })
4502+
| ItemKind::Const(box ConstItem { ref generics, .. })
44334503
| ItemKind::Fn(box Fn { ref generics, .. })
44344504
| ItemKind::Enum(_, ref generics)
44354505
| ItemKind::Struct(_, ref generics)
@@ -4449,7 +4519,6 @@ impl<'ast> Visitor<'ast> for LifetimeCountVisitor<'_, '_, '_> {
44494519
ItemKind::Mod(..)
44504520
| ItemKind::ForeignMod(..)
44514521
| ItemKind::Static(..)
4452-
| ItemKind::Const(..)
44534522
| ItemKind::Use(..)
44544523
| ItemKind::ExternCrate(..)
44554524
| ItemKind::MacroDef(..)

0 commit comments

Comments
 (0)