Skip to content

Commit fce5588

Browse files
camelidBoxyUwU
andcommitted
mgca: Add ConstArg representation for const items
* Centralize const item lowering logic * Add dummy NodeId to AST const item for mgca lowering * wip on using ConstArg for const item bodies * wip on fixing const normalization ICEs * Extract helper function for normalizing free/assoc terms * more wip on fixing ICEs * Recurse through const items in instance resolution * Fix more ICEs * Use AnonConst as RHS of const items instead of side channel hack * Implement type_of for anon consts on RHS of const items * Fix yet more ICEs * wip on fixing more ICEs (this might make it worse) * Fix clippy and rustfmt * Address some review comments * Inherit generics correctly for anon const as const item RHS * Lower const item RHS to const path even on stable * wip on moving const RHS special-casing * intern + write to place * allow anon consts with expected types with generics Co-authored-by: Boxy <[email protected]>
1 parent ade8487 commit fce5588

File tree

46 files changed

+658
-381
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+658
-381
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3754,7 +3754,7 @@ pub struct ConstItem {
37543754
pub ident: Ident,
37553755
pub generics: Generics,
37563756
pub ty: Box<Ty>,
3757-
pub expr: Option<Box<Expr>>,
3757+
pub body: Option<Box<AnonConst>>,
37583758
pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
37593759
}
37603760

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -172,37 +172,41 @@ impl<'hir> LoweringContext<'_, 'hir> {
172172
}
173173
ItemKind::Static(box ast::StaticItem {
174174
ident,
175-
ty: t,
175+
ty,
176176
safety: _,
177177
mutability: m,
178178
expr: e,
179179
define_opaque,
180180
}) => {
181181
let ident = self.lower_ident(*ident);
182-
let (ty, body_id) =
183-
self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy);
182+
let ty =
183+
self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
184+
let body_id = self.lower_const_body(span, e.as_deref());
184185
self.lower_define_opaque(hir_id, define_opaque);
185186
hir::ItemKind::Static(*m, ident, ty, body_id)
186187
}
187188
ItemKind::Const(box ast::ConstItem {
188189
ident,
189190
generics,
190191
ty,
191-
expr,
192+
body,
192193
define_opaque,
193194
..
194195
}) => {
195196
let ident = self.lower_ident(*ident);
196-
let (generics, (ty, body_id)) = self.lower_generics(
197+
let (generics, (ty, body)) = self.lower_generics(
197198
generics,
198199
id,
199200
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
200201
|this| {
201-
this.lower_const_item(ty, span, expr.as_deref(), ImplTraitPosition::ConstTy)
202+
let ty = this
203+
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
204+
let body = this.lower_anon_const_to_const_arg(body.as_deref().unwrap());
205+
(ty, body)
202206
},
203207
);
204208
self.lower_define_opaque(hir_id, &define_opaque);
205-
hir::ItemKind::Const(ident, generics, ty, body_id)
209+
hir::ItemKind::Const(ident, generics, ty, body)
206210
}
207211
ItemKind::Fn(box Fn {
208212
sig: FnSig { decl, header, span: fn_sig_span },
@@ -463,17 +467,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
463467
}
464468
}
465469

466-
fn lower_const_item(
467-
&mut self,
468-
ty: &Ty,
469-
span: Span,
470-
body: Option<&Expr>,
471-
impl_trait_position: ImplTraitPosition,
472-
) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
473-
let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(impl_trait_position));
474-
(ty, self.lower_const_body(span, body))
475-
}
476-
477470
#[instrument(level = "debug", skip(self))]
478471
fn lower_use_tree(
479472
&mut self,
@@ -808,7 +801,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
808801
ident,
809802
generics,
810803
ty,
811-
expr,
804+
body,
812805
define_opaque,
813806
..
814807
}) => {
@@ -819,14 +812,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
819812
|this| {
820813
let ty = this
821814
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
822-
let body = expr.as_ref().map(|x| this.lower_const_body(i.span, Some(x)));
823-
815+
let body =
816+
body.as_deref().map(|body| this.lower_anon_const_to_const_arg(body));
824817
hir::TraitItemKind::Const(ty, body)
825818
},
826819
);
827820

828821
if define_opaque.is_some() {
829-
if expr.is_some() {
822+
if body.is_some() {
830823
self.lower_define_opaque(hir_id, &define_opaque);
831824
} else {
832825
self.dcx().span_err(
@@ -836,7 +829,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
836829
}
837830
}
838831

839-
(*ident, generics, kind, expr.is_some())
832+
(*ident, generics, kind, body.is_some())
840833
}
841834
AssocItemKind::Fn(box Fn {
842835
sig, ident, generics, body: None, define_opaque, ..
@@ -1021,7 +1014,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10211014
ident,
10221015
generics,
10231016
ty,
1024-
expr,
1017+
body,
10251018
define_opaque,
10261019
..
10271020
}) => (
@@ -1033,8 +1026,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
10331026
|this| {
10341027
let ty = this
10351028
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
1036-
let body = this.lower_const_body(i.span, expr.as_deref());
10371029
this.lower_define_opaque(hir_id, &define_opaque);
1030+
let body = this.lower_anon_const_to_const_arg(body.as_deref().unwrap());
10381031
hir::ImplItemKind::Const(ty, body)
10391032
},
10401033
),

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,9 +1236,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
12361236
}
12371237
});
12381238
}
1239-
ItemKind::Const(box ConstItem { defaultness, expr, .. }) => {
1239+
ItemKind::Const(box ConstItem { defaultness, body, .. }) => {
12401240
self.check_defaultness(item.span, *defaultness);
1241-
if expr.is_none() {
1241+
if body.is_none() {
12421242
self.dcx().emit_err(errors::ConstWithoutBody {
12431243
span: item.span,
12441244
replace_span: self.ending_semi_or_hi(item.span),
@@ -1578,7 +1578,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
15781578

15791579
if let AssocCtxt::Impl { .. } = ctxt {
15801580
match &item.kind {
1581-
AssocItemKind::Const(box ConstItem { expr: None, .. }) => {
1581+
AssocItemKind::Const(box ConstItem { body: None, .. }) => {
15821582
self.dcx().emit_err(errors::AssocConstWithoutBody {
15831583
span: item.span,
15841584
replace_span: self.ending_semi_or_hi(item.span),

compiler/rustc_ast_pretty/src/pprust/state/item.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,15 +213,15 @@ impl<'a> State<'a> {
213213
ident,
214214
generics,
215215
ty,
216-
expr,
216+
body,
217217
define_opaque,
218218
}) => {
219219
self.print_item_const(
220220
*ident,
221221
None,
222222
generics,
223223
ty,
224-
expr.as_deref(),
224+
body.as_deref().map(|ct| &*ct.value),
225225
&item.vis,
226226
ast::Safety::Default,
227227
*defaultness,
@@ -566,15 +566,15 @@ impl<'a> State<'a> {
566566
ident,
567567
generics,
568568
ty,
569-
expr,
569+
body,
570570
define_opaque,
571571
}) => {
572572
self.print_item_const(
573573
*ident,
574574
None,
575575
generics,
576576
ty,
577-
expr.as_deref(),
577+
body.as_deref().map(|ct| &*ct.value),
578578
vis,
579579
ast::Safety::Default,
580580
*defaultness,

compiler/rustc_builtin_macros/src/alloc_error_handler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub(crate) fn expand(
4242

4343
// Generate anonymous constant serving as container for the allocator methods.
4444
let const_ty = ecx.ty(sig_span, TyKind::Tup(ThinVec::new()));
45-
let const_body = ecx.expr_block(ecx.block(span, stmts));
45+
let const_body = ecx.anon_const_block(ecx.block(span, stmts));
4646
let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body);
4747
let const_item = if is_stmt {
4848
Annotatable::Stmt(Box::new(ecx.stmt_item(span, const_item)))

compiler/rustc_builtin_macros/src/global_allocator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub(crate) fn expand(
4747

4848
// Generate anonymous constant serving as container for the allocator methods.
4949
let const_ty = ecx.ty(ty_span, TyKind::Tup(ThinVec::new()));
50-
let const_body = ecx.expr_block(ecx.block(span, stmts));
50+
let const_body = ecx.anon_const_block(ecx.block(span, stmts));
5151
let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body);
5252
let const_item = if is_stmt {
5353
Annotatable::Stmt(Box::new(ecx.stmt_item(span, const_item)))

compiler/rustc_builtin_macros/src/proc_macro_harness.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> Box<ast::Item> {
385385
cx.attr_nested_word(sym::allow, sym::deprecated, span),
386386
]);
387387

388-
let block = cx.expr_block(
388+
let block = cx.anon_const_block(
389389
cx.block(span, thin_vec![cx.stmt_item(span, krate), cx.stmt_item(span, decls_static)]),
390390
);
391391

compiler/rustc_builtin_macros/src/test.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,9 @@ pub(crate) fn expand_test_or_bench(
289289
ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
290290
define_opaque: None,
291291
// test::TestDescAndFn {
292-
expr: Some(
293-
cx.expr_struct(
292+
body: Some(Box::new(ast::AnonConst {
293+
id: ast::DUMMY_NODE_ID,
294+
value: cx.expr_struct(
294295
sp,
295296
test_path("TestDescAndFn"),
296297
thin_vec![
@@ -371,7 +372,7 @@ pub(crate) fn expand_test_or_bench(
371372
field("testfn", test_fn), // }
372373
],
373374
), // }
374-
),
375+
})),
375376
}
376377
.into(),
377378
),

compiler/rustc_const_eval/src/check_consts/qualifs.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
use rustc_errors::ErrorGuaranteed;
99
use rustc_hir::LangItem;
10+
use rustc_hir::def::DefKind;
1011
use rustc_infer::infer::TyCtxtInferExt;
1112
use rustc_middle::mir::*;
1213
use rustc_middle::ty::{self, AdtDef, Ty};
@@ -366,8 +367,12 @@ where
366367
// check performed after the promotion. Verify that with an assertion.
367368
assert!(promoted.is_none() || Q::ALLOW_PROMOTED);
368369

369-
// Don't peek inside trait associated constants.
370-
if promoted.is_none() && cx.tcx.trait_of_assoc(def).is_none() {
370+
// Const items don't themselves have bodies -- they will have either a path or an anon const instead.
371+
// FIXME(mgca): is this really the right behavior? should we return the qualifs of the anon const body instead?
372+
// (note also that original code ignored trait assoc items)
373+
if promoted.is_none()
374+
&& !matches!(cx.tcx.def_kind(def), DefKind::Const | DefKind::AssocConst)
375+
{
371376
let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def);
372377

373378
if !Q::in_qualifs(&qualifs) {

compiler/rustc_const_eval/src/const_eval/eval_queries.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,31 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
347347
trace!("const eval: {:?} ({})", key, instance);
348348
}
349349

350+
if let ty::InstanceKind::Item(def_id) = key.value.instance.def
351+
&& matches!(tcx.def_kind(def_id), DefKind::Const | DefKind::AssocConst)
352+
{
353+
let ct = tcx.const_of_item(def_id).instantiate(tcx, key.value.instance.args);
354+
match ct.kind() {
355+
ty::ConstKind::Unevaluated(_) => {
356+
return Err(ErrorHandled::TooGeneric(DUMMY_SP));
357+
}
358+
ty::ConstKind::Value(cv) => return Ok(tcx.valtree_to_const_alloc(cv)),
359+
ty::ConstKind::Error(guar) => {
360+
return Err(ErrorHandled::Reported(
361+
ReportedErrorInfo::const_eval_error(guar),
362+
DUMMY_SP,
363+
));
364+
}
365+
ty::ConstKind::Expr(_) => return Err(ErrorHandled::TooGeneric(DUMMY_SP)),
366+
ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(_) => {
367+
return Err(ErrorHandled::TooGeneric(DUMMY_SP));
368+
}
369+
ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) => {
370+
bug!("unexpected constant {ct:?}")
371+
}
372+
}
373+
}
374+
350375
eval_in_interpreter(tcx, key.value, key.typing_env)
351376
}
352377

0 commit comments

Comments
 (0)