Skip to content

Commit 4f6c9ab

Browse files
committed
wip on using ConstArg for const item bodies
1 parent 7a08ebe commit 4f6c9ab

File tree

12 files changed

+160
-92
lines changed

12 files changed

+160
-92
lines changed

compiler/rustc_ast_lowering/src/item.rs

+34-24
Original file line numberDiff line numberDiff line change
@@ -205,18 +205,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
205205
..
206206
}) => {
207207
let ident = self.lower_ident(*ident);
208-
let (generics, (ty, body_id)) = self.lower_generics(
208+
let (generics, (ty, body)) = self.lower_generics(
209209
generics,
210210
id,
211211
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
212212
|this| {
213213
let ty = this
214214
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
215-
(ty, this.lower_const_item(span, body_id.zip(expr.as_deref())))
215+
let body =
216+
this.lower_const_item(span, body_id.unwrap(), expr.as_deref().unwrap());
217+
(ty, body)
216218
},
217219
);
218220
self.lower_define_opaque(hir_id, &define_opaque);
219-
hir::ItemKind::Const(ident, ty, generics, body_id)
221+
hir::ItemKind::Const(ident, ty, generics, body)
220222
}
221223
ItemKind::Fn(box Fn {
222224
sig: FnSig { decl, header, span: fn_sig_span },
@@ -496,21 +498,27 @@ impl<'hir> LoweringContext<'_, 'hir> {
496498
}
497499
}
498500

499-
fn lower_const_item(&mut self, span: Span, body: Option<(NodeId, &Expr)>) -> hir::BodyId {
500-
self.lower_const_body(span, body.map(|b| b.1))
501-
// TODO: code to add next
502-
// let mgca = self.tcx.features().min_generic_const_args();
503-
// let ct_arg = if mgca && let Some((_, expr)) = body {
504-
// self.try_lower_as_const_path(expr)
505-
// } else {
506-
// None
507-
// };
508-
// let body_id = if mgca && ct_arg.is_none() {
509-
// self.lower_const_body_with_const_block(span, body)
510-
// } else {
511-
// self.lower_const_body(span, body.map(|(_, e)| e))
512-
// };
513-
// (body_id, ct_arg)
501+
fn lower_const_item(
502+
&mut self,
503+
span: Span,
504+
body_id: NodeId,
505+
body_expr: &Expr,
506+
) -> &'hir hir::ConstArg<'hir> {
507+
let mgca = self.tcx.features().min_generic_const_args();
508+
if mgca && let Some(ct_arg) = self.try_lower_as_const_path(body_expr) {
509+
return ct_arg;
510+
}
511+
let anon = self.arena.alloc(self.with_new_scopes(span, |this| {
512+
let body = this.lower_const_body(span, Some(body_expr));
513+
hir::AnonConst {
514+
hir_id: this.lower_node_id(body_id),
515+
def_id: this.local_def_id(body_id),
516+
body,
517+
span,
518+
}
519+
}));
520+
self.arena
521+
.alloc(hir::ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(anon) })
514522
}
515523

516524
#[instrument(level = "debug", skip(self))]
@@ -820,9 +828,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
820828
|this| {
821829
let ty = this
822830
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
823-
let body = expr
824-
.as_deref()
825-
.map(|e| this.lower_const_item(i.span, Some((body_id.unwrap(), e))));
831+
let body = body_id
832+
.zip(expr.as_deref())
833+
.map(|(b_id, b_ex)| this.lower_const_item(i.span, b_id, b_ex));
826834
hir::TraitItemKind::Const(ty, body)
827835
},
828836
);
@@ -1016,7 +1024,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
10161024
let ty = this
10171025
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
10181026
this.lower_define_opaque(hir_id, &define_opaque);
1019-
let body = this.lower_const_item(i.span, body_id.zip(expr.as_deref()));
1027+
let body = this.lower_const_item(
1028+
i.span,
1029+
body_id.unwrap(),
1030+
expr.as_deref().unwrap(),
1031+
);
10201032
hir::ImplItemKind::Const(ty, body)
10211033
},
10221034
),
@@ -1293,8 +1305,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
12931305
self.lower_fn_body(decl, contract, |this| this.lower_block_expr(body))
12941306
}
12951307

1296-
// TODO: add lower_const_body_with_const_block
1297-
12981308
pub(super) fn lower_const_body(&mut self, span: Span, expr: Option<&Expr>) -> hir::BodyId {
12991309
self.lower_body(|this| {
13001310
(

compiler/rustc_ast_lowering/src/lib.rs

+16
Original file line numberDiff line numberDiff line change
@@ -2076,6 +2076,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20762076
}
20772077
}
20782078

2079+
/// Assumes mgca feature is enabled.
2080+
fn try_lower_as_const_path(&mut self, expr: &Expr) -> Option<&'hir hir::ConstArg<'hir>> {
2081+
let ExprKind::Path(qself, path) = &expr.kind else { return None };
2082+
let qpath = self.lower_qpath(
2083+
expr.id,
2084+
qself,
2085+
path,
2086+
ParamMode::Optional,
2087+
AllowReturnTypeNotation::No,
2088+
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2089+
None,
2090+
);
2091+
let ct_kind = hir::ConstArgKind::Path(qpath);
2092+
Some(self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind }))
2093+
}
2094+
20792095
/// Used when lowering a type argument that turned out to actually be a const argument.
20802096
///
20812097
/// Only use for that purpose since otherwise it will create a duplicate def.

compiler/rustc_hir/src/hir.rs

+39-15
Original file line numberDiff line numberDiff line change
@@ -3077,7 +3077,7 @@ impl<'hir> TraitItem<'hir> {
30773077
}
30783078

30793079
expect_methods_self_kind! {
3080-
expect_const, (&'hir Ty<'hir>, Option<BodyId>),
3080+
expect_const, (&'hir Ty<'hir>, Option<&'hir ConstArg<'hir>>),
30813081
TraitItemKind::Const(ty, body), (ty, *body);
30823082

30833083
expect_fn, (&FnSig<'hir>, &TraitFn<'hir>),
@@ -3102,7 +3102,7 @@ pub enum TraitFn<'hir> {
31023102
#[derive(Debug, Clone, Copy, HashStable_Generic)]
31033103
pub enum TraitItemKind<'hir> {
31043104
/// An associated constant with an optional value (otherwise `impl`s must contain a value).
3105-
Const(&'hir Ty<'hir>, Option<BodyId>),
3105+
Const(&'hir Ty<'hir>, Option<&'hir ConstArg<'hir>>),
31063106
/// An associated function with an optional body.
31073107
Fn(FnSig<'hir>, TraitFn<'hir>),
31083108
/// An associated type with (possibly empty) bounds and optional concrete
@@ -3152,9 +3152,9 @@ impl<'hir> ImplItem<'hir> {
31523152
}
31533153

31543154
expect_methods_self_kind! {
3155-
expect_const, (&'hir Ty<'hir>, BodyId), ImplItemKind::Const(ty, body), (ty, *body);
3156-
expect_fn, (&FnSig<'hir>, BodyId), ImplItemKind::Fn(ty, body), (ty, *body);
3157-
expect_type, &'hir Ty<'hir>, ImplItemKind::Type(ty), ty;
3155+
expect_const, (&'hir Ty<'hir>, &'hir ConstArg<'hir>), ImplItemKind::Const(ty, body), (ty, body);
3156+
expect_fn, (&FnSig<'hir>, BodyId), ImplItemKind::Fn(ty, body), (ty, *body);
3157+
expect_type, &'hir Ty<'hir>, ImplItemKind::Type(ty), ty;
31583158
}
31593159
}
31603160

@@ -3163,7 +3163,7 @@ impl<'hir> ImplItem<'hir> {
31633163
pub enum ImplItemKind<'hir> {
31643164
/// An associated constant of the given type, set to the constant result
31653165
/// of the expression.
3166-
Const(&'hir Ty<'hir>, BodyId),
3166+
Const(&'hir Ty<'hir>, &'hir ConstArg<'hir>),
31673167
/// An associated function implementation with the given signature and body.
31683168
Fn(FnSig<'hir>, BodyId),
31693169
/// An associated type.
@@ -4090,8 +4090,8 @@ impl<'hir> Item<'hir> {
40904090
expect_static, (Ident, &'hir Ty<'hir>, Mutability, BodyId),
40914091
ItemKind::Static(ident, ty, mutbl, body), (*ident, ty, *mutbl, *body);
40924092

4093-
expect_const, (Ident, &'hir Ty<'hir>, &'hir Generics<'hir>, BodyId),
4094-
ItemKind::Const(ident, ty, generics, body), (*ident, ty, generics, *body);
4093+
expect_const, (Ident, &'hir Ty<'hir>, &'hir Generics<'hir>, &'hir ConstArg<'hir>),
4094+
ItemKind::Const(ident, ty, generics, ct_arg), (*ident, ty, generics, ct_arg);
40954095

40964096
expect_fn, (Ident, &FnSig<'hir>, &'hir Generics<'hir>, BodyId),
40974097
ItemKind::Fn { ident, sig, generics, body, .. }, (*ident, sig, generics, *body);
@@ -4261,7 +4261,7 @@ pub enum ItemKind<'hir> {
42614261
/// A `static` item.
42624262
Static(Ident, &'hir Ty<'hir>, Mutability, BodyId),
42634263
/// A `const` item.
4264-
Const(Ident, &'hir Ty<'hir>, &'hir Generics<'hir>, BodyId),
4264+
Const(Ident, &'hir Ty<'hir>, &'hir Generics<'hir>, &'hir ConstArg<'hir>),
42654265
/// A function declaration.
42664266
Fn {
42674267
ident: Ident,
@@ -4559,17 +4559,29 @@ impl<'hir> OwnerNode<'hir> {
45594559
OwnerNode::Item(Item {
45604560
kind:
45614561
ItemKind::Static(_, _, _, body)
4562-
| ItemKind::Const(_, _, _, body)
4562+
| ItemKind::Const(
4563+
..,
4564+
ConstArg { kind: ConstArgKind::Anon(AnonConst { body, .. }), .. },
4565+
)
45634566
| ItemKind::Fn { body, .. },
45644567
..
45654568
})
45664569
| OwnerNode::TraitItem(TraitItem {
45674570
kind:
4568-
TraitItemKind::Fn(_, TraitFn::Provided(body)) | TraitItemKind::Const(_, Some(body)),
4571+
TraitItemKind::Fn(_, TraitFn::Provided(body))
4572+
| TraitItemKind::Const(
4573+
_,
4574+
Some(ConstArg { kind: ConstArgKind::Anon(AnonConst { body, .. }), .. }),
4575+
),
45694576
..
45704577
})
45714578
| OwnerNode::ImplItem(ImplItem {
4572-
kind: ImplItemKind::Fn(_, body) | ImplItemKind::Const(_, body),
4579+
kind:
4580+
ImplItemKind::Fn(_, body)
4581+
| ImplItemKind::Const(
4582+
_,
4583+
ConstArg { kind: ConstArgKind::Anon(AnonConst { body, .. }), .. },
4584+
),
45734585
..
45744586
}) => Some(*body),
45754587
_ => None,
@@ -4816,20 +4828,32 @@ impl<'hir> Node<'hir> {
48164828
Node::Item(Item {
48174829
owner_id,
48184830
kind:
4819-
ItemKind::Const(_, _, _, body)
4831+
ItemKind::Const(
4832+
..,
4833+
ConstArg { kind: ConstArgKind::Anon(AnonConst { body, .. }), .. },
4834+
)
48204835
| ItemKind::Static(.., body)
48214836
| ItemKind::Fn { body, .. },
48224837
..
48234838
})
48244839
| Node::TraitItem(TraitItem {
48254840
owner_id,
48264841
kind:
4827-
TraitItemKind::Const(_, Some(body)) | TraitItemKind::Fn(_, TraitFn::Provided(body)),
4842+
TraitItemKind::Const(
4843+
_,
4844+
Some(ConstArg { kind: ConstArgKind::Anon(AnonConst { body, .. }), .. }),
4845+
)
4846+
| TraitItemKind::Fn(_, TraitFn::Provided(body)),
48284847
..
48294848
})
48304849
| Node::ImplItem(ImplItem {
48314850
owner_id,
4832-
kind: ImplItemKind::Const(_, body) | ImplItemKind::Fn(_, body),
4851+
kind:
4852+
ImplItemKind::Const(
4853+
_,
4854+
ConstArg { kind: ConstArgKind::Anon(AnonConst { body, .. }), .. },
4855+
)
4856+
| ImplItemKind::Fn(_, body),
48334857
..
48344858
}) => Some((owner_id.def_id, *body)),
48354859

compiler/rustc_hir/src/intravisit.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
554554
try_visit!(visitor.visit_ident(ident));
555555
try_visit!(visitor.visit_ty_unambig(typ));
556556
try_visit!(visitor.visit_generics(generics));
557-
try_visit!(visitor.visit_nested_body(body));
557+
try_visit!(visitor.visit_const_arg_unambig(body));
558558
}
559559
ItemKind::Fn { ident, sig, generics, body: body_id, .. } => {
560560
try_visit!(visitor.visit_ident(ident));
@@ -1167,7 +1167,7 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(
11671167
match *kind {
11681168
TraitItemKind::Const(ref ty, default) => {
11691169
try_visit!(visitor.visit_ty_unambig(ty));
1170-
visit_opt!(visitor, visit_nested_body, default);
1170+
visit_opt!(visitor, visit_const_arg_unambig, default);
11711171
}
11721172
TraitItemKind::Fn(ref sig, TraitFn::Required(param_idents)) => {
11731173
try_visit!(visitor.visit_fn_decl(sig.decl));
@@ -1225,7 +1225,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(
12251225
match *kind {
12261226
ImplItemKind::Const(ref ty, body) => {
12271227
try_visit!(visitor.visit_ty_unambig(ty));
1228-
visitor.visit_nested_body(body)
1228+
visitor.visit_const_arg_unambig(body)
12291229
}
12301230
ImplItemKind::Fn(ref sig, body_id) => visitor.visit_fn(
12311231
FnKind::Method(impl_item.ident, sig),

compiler/rustc_hir_analysis/src/collect/type_of.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,13 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
155155
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
156156
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
157157
}
158-
TraitItemKind::Const(ty, body_id) => body_id
159-
.and_then(|body_id| {
158+
TraitItemKind::Const(ty, body) => body
159+
.and_then(|ct_arg| {
160160
ty.is_suggestable_infer_ty().then(|| {
161161
infer_placeholder_type(
162162
icx.lowerer(),
163163
def_id,
164-
body_id,
164+
ct_arg.hir_id,
165165
ty.span,
166166
item.ident,
167167
"associated constant",
@@ -180,12 +180,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
180180
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
181181
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
182182
}
183-
ImplItemKind::Const(ty, body_id) => {
183+
ImplItemKind::Const(ty, ct_arg) => {
184184
if ty.is_suggestable_infer_ty() {
185185
infer_placeholder_type(
186186
icx.lowerer(),
187187
def_id,
188-
body_id,
188+
ct_arg.hir_id,
189189
ty.span,
190190
item.ident,
191191
"associated constant",
@@ -209,7 +209,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
209209
infer_placeholder_type(
210210
icx.lowerer(),
211211
def_id,
212-
body_id,
212+
body_id.hir_id,
213213
ty.span,
214214
ident,
215215
"static variable",
@@ -218,12 +218,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
218218
icx.lower_ty(ty)
219219
}
220220
}
221-
ItemKind::Const(ident, ty, _, body_id) => {
221+
ItemKind::Const(ident, ty, _, body) => {
222222
if ty.is_suggestable_infer_ty() {
223223
infer_placeholder_type(
224224
icx.lowerer(),
225225
def_id,
226-
body_id,
226+
body.hir_id,
227227
ty.span,
228228
ident,
229229
"constant",
@@ -404,13 +404,13 @@ pub(super) fn type_of_opaque_hir_typeck(
404404
fn infer_placeholder_type<'tcx>(
405405
cx: &dyn HirTyLowerer<'tcx>,
406406
def_id: LocalDefId,
407-
body_id: hir::BodyId,
407+
hir_id: HirId,
408408
span: Span,
409409
item_ident: Ident,
410410
kind: &'static str,
411411
) -> Ty<'tcx> {
412412
let tcx = cx.tcx();
413-
let ty = tcx.typeck(def_id).node_type(body_id.hir_id);
413+
let ty = tcx.typeck(def_id).node_type(hir_id);
414414

415415
// If this came from a free `const` or `static mut?` item,
416416
// then the user may have written e.g. `const A = 42;`.
@@ -438,7 +438,7 @@ fn infer_placeholder_type<'tcx>(
438438
);
439439
} else {
440440
with_forced_trimmed_paths!(err.span_note(
441-
tcx.hir_body(body_id).value.span,
441+
tcx.hir_span(hir_id),
442442
format!("however, the inferred type `{ty}` cannot be named"),
443443
));
444444
}
@@ -481,7 +481,7 @@ fn infer_placeholder_type<'tcx>(
481481
);
482482
} else {
483483
with_forced_trimmed_paths!(diag.span_note(
484-
tcx.hir_body(body_id).value.span,
484+
tcx.hir_span(hir_id),
485485
format!("however, the inferred type `{ty}` cannot be named"),
486486
));
487487
}

0 commit comments

Comments
 (0)