Skip to content

Commit ed06230

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 383b9c4 commit ed06230

File tree

46 files changed

+513
-382
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

+513
-382
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3728,7 +3728,7 @@ pub struct ConstItem {
37283728
pub ident: Ident,
37293729
pub generics: Generics,
37303730
pub ty: P<Ty>,
3731-
pub expr: Option<P<Expr>>,
3731+
pub body: Option<P<AnonConst>>,
37323732
pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
37333733
}
37343734

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -171,37 +171,41 @@ impl<'hir> LoweringContext<'_, 'hir> {
171171
}
172172
ItemKind::Static(box ast::StaticItem {
173173
ident,
174-
ty: t,
174+
ty,
175175
safety: _,
176176
mutability: m,
177177
expr: e,
178178
define_opaque,
179179
}) => {
180180
let ident = self.lower_ident(*ident);
181-
let (ty, body_id) =
182-
self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy);
181+
let ty =
182+
self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
183+
let body_id = self.lower_const_body(span, e.as_deref());
183184
self.lower_define_opaque(hir_id, define_opaque);
184185
hir::ItemKind::Static(*m, ident, ty, body_id)
185186
}
186187
ItemKind::Const(box ast::ConstItem {
187188
ident,
188189
generics,
189190
ty,
190-
expr,
191+
body,
191192
define_opaque,
192193
..
193194
}) => {
194195
let ident = self.lower_ident(*ident);
195-
let (generics, (ty, body_id)) = self.lower_generics(
196+
let (generics, (ty, body)) = self.lower_generics(
196197
generics,
197198
id,
198199
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
199200
|this| {
200-
this.lower_const_item(ty, span, expr.as_deref(), ImplTraitPosition::ConstTy)
201+
let ty = this
202+
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
203+
let body = this.lower_anon_const_to_const_arg(body.as_deref().unwrap());
204+
(ty, body)
201205
},
202206
);
203207
self.lower_define_opaque(hir_id, &define_opaque);
204-
hir::ItemKind::Const(ident, generics, ty, body_id)
208+
hir::ItemKind::Const(ident, generics, ty, body)
205209
}
206210
ItemKind::Fn(box Fn {
207211
sig: FnSig { decl, header, span: fn_sig_span },
@@ -490,17 +494,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
490494
}
491495
}
492496

493-
fn lower_const_item(
494-
&mut self,
495-
ty: &Ty,
496-
span: Span,
497-
body: Option<&Expr>,
498-
impl_trait_position: ImplTraitPosition,
499-
) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
500-
let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(impl_trait_position));
501-
(ty, self.lower_const_body(span, body))
502-
}
503-
504497
#[instrument(level = "debug", skip(self))]
505498
fn lower_use_tree(
506499
&mut self,
@@ -829,7 +822,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
829822
ident,
830823
generics,
831824
ty,
832-
expr,
825+
body,
833826
define_opaque,
834827
..
835828
}) => {
@@ -840,14 +833,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
840833
|this| {
841834
let ty = this
842835
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
843-
let body = expr.as_ref().map(|x| this.lower_const_body(i.span, Some(x)));
844-
836+
let body =
837+
body.as_deref().map(|body| this.lower_anon_const_to_const_arg(body));
845838
hir::TraitItemKind::Const(ty, body)
846839
},
847840
);
848841

849842
if define_opaque.is_some() {
850-
if expr.is_some() {
843+
if body.is_some() {
851844
self.lower_define_opaque(hir_id, &define_opaque);
852845
} else {
853846
self.dcx().span_err(
@@ -857,7 +850,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
857850
}
858851
}
859852

860-
(*ident, generics, kind, expr.is_some())
853+
(*ident, generics, kind, body.is_some())
861854
}
862855
AssocItemKind::Fn(box Fn {
863856
sig, ident, generics, body: None, define_opaque, ..
@@ -999,7 +992,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
999992
ident,
1000993
generics,
1001994
ty,
1002-
expr,
995+
body,
1003996
define_opaque,
1004997
..
1005998
}) => (
@@ -1011,8 +1004,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
10111004
|this| {
10121005
let ty = this
10131006
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
1014-
let body = this.lower_const_body(i.span, expr.as_deref());
10151007
this.lower_define_opaque(hir_id, &define_opaque);
1008+
let body = this.lower_anon_const_to_const_arg(body.as_deref().unwrap());
10161009
hir::ImplItemKind::Const(ty, body)
10171010
},
10181011
),

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,9 +1196,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
11961196
_ => visit::walk_item(self, item),
11971197
}
11981198
}
1199-
ItemKind::Const(box ConstItem { defaultness, expr, .. }) => {
1199+
ItemKind::Const(box ConstItem { defaultness, body, .. }) => {
12001200
self.check_defaultness(item.span, *defaultness);
1201-
if expr.is_none() {
1201+
if body.is_none() {
12021202
self.dcx().emit_err(errors::ConstWithoutBody {
12031203
span: item.span,
12041204
replace_span: self.ending_semi_or_hi(item.span),
@@ -1538,7 +1538,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
15381538

15391539
if let AssocCtxt::Impl { .. } = ctxt {
15401540
match &item.kind {
1541-
AssocItemKind::Const(box ConstItem { expr: None, .. }) => {
1541+
AssocItemKind::Const(box ConstItem { body: None, .. }) => {
15421542
self.dcx().emit_err(errors::AssocConstWithoutBody {
15431543
span: item.span,
15441544
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
@@ -214,15 +214,15 @@ impl<'a> State<'a> {
214214
ident,
215215
generics,
216216
ty,
217-
expr,
217+
body,
218218
define_opaque,
219219
}) => {
220220
self.print_item_const(
221221
*ident,
222222
None,
223223
generics,
224224
ty,
225-
expr.as_deref(),
225+
body.as_deref().map(|ct| &*ct.value),
226226
&item.vis,
227227
ast::Safety::Default,
228228
*defaultness,
@@ -565,15 +565,15 @@ impl<'a> State<'a> {
565565
ident,
566566
generics,
567567
ty,
568-
expr,
568+
body,
569569
define_opaque,
570570
}) => {
571571
self.print_item_const(
572572
*ident,
573573
None,
574574
generics,
575575
ty,
576-
expr.as_deref(),
576+
body.as_deref().map(|ct| &*ct.value),
577577
vis,
578578
ast::Safety::Default,
579579
*defaultness,

compiler/rustc_builtin_macros/src/alloc_error_handler.rs

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

4444
// Generate anonymous constant serving as container for the allocator methods.
4545
let const_ty = ecx.ty(sig_span, TyKind::Tup(ThinVec::new()));
46-
let const_body = ecx.expr_block(ecx.block(span, stmts));
46+
let const_body = ecx.anon_const_block(ecx.block(span, stmts));
4747
let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body);
4848
let const_item = if is_stmt {
4949
Annotatable::Stmt(P(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
@@ -48,7 +48,7 @@ pub(crate) fn expand(
4848

4949
// Generate anonymous constant serving as container for the allocator methods.
5050
let const_ty = ecx.ty(ty_span, TyKind::Tup(ThinVec::new()));
51-
let const_body = ecx.expr_block(ecx.block(span, stmts));
51+
let const_body = ecx.anon_const_block(ecx.block(span, stmts));
5252
let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body);
5353
let const_item = if is_stmt {
5454
Annotatable::Stmt(P(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
@@ -391,7 +391,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
391391
cx.attr_nested_word(sym::allow, sym::deprecated, span),
392392
]);
393393

394-
let block = cx.expr_block(
394+
let block = cx.anon_const_block(
395395
cx.block(span, thin_vec![cx.stmt_item(span, krate), cx.stmt_item(span, decls_static)]),
396396
);
397397

compiler/rustc_builtin_macros/src/test.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,8 +287,9 @@ pub(crate) fn expand_test_or_bench(
287287
ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
288288
define_opaque: None,
289289
// test::TestDescAndFn {
290-
expr: Some(
291-
cx.expr_struct(
290+
body: Some(P(ast::AnonConst {
291+
id: ast::DUMMY_NODE_ID,
292+
value: cx.expr_struct(
292293
sp,
293294
test_path("TestDescAndFn"),
294295
thin_vec![
@@ -369,7 +370,7 @@ pub(crate) fn expand_test_or_bench(
369370
field("testfn", test_fn), // }
370371
],
371372
), // }
372-
),
373+
})),
373374
}
374375
.into(),
375376
),

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};
@@ -368,8 +369,12 @@ where
368369
// check performed after the promotion. Verify that with an assertion.
369370
assert!(promoted.is_none() || Q::ALLOW_PROMOTED);
370371

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

375380
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
@@ -340,6 +340,31 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
340340
trace!("const eval: {:?} ({})", key, instance);
341341
}
342342

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

0 commit comments

Comments
 (0)