Skip to content

Commit 8c3a94a

Browse files
committed
Auto merge of rust-lang#125915 - camelid:const-arg-refactor, r=BoxyUwU
Represent type-level consts with new-and-improved `hir::ConstArg` ### Summary This is a step toward `min_generic_const_exprs`. We now represent all const generic arguments using an enum that differentiates between const *paths* (temporarily just bare const params) and arbitrary anon consts that may perform computations. This will enable us to cleanly implement the `min_generic_const_args` plan of allowing the use of generics in paths used as const args, while disallowing their use in arbitrary anon consts. Here is a summary of the salient aspects of this change: - Add `current_def_id_parent` to `LoweringContext` This is needed to track anon const parents properly once we implement `ConstArgKind::Path` (which requires moving anon const def-creation outside of `DefCollector`). - Create `hir::ConstArgKind` enum with `Path` and `Anon` variants. Use it in the existing `hir::ConstArg` struct, replacing the previous `hir::AnonConst` field. - Use `ConstArg` for all instances of const args. Specifically, use it instead of `AnonConst` for assoc item constraints, array lengths, and const param defaults. - Some `ast::AnonConst`s now have their `DefId`s created in rustc_ast_lowering rather than `DefCollector`. This is because in some cases they will end up becoming a `ConstArgKind::Path` instead, which has no `DefId`. We have to solve this in a hacky way where we guess whether the `AnonConst` could end up as a path const since we can't know for sure until after name resolution (`N` could refer to a free const or a nullary struct). If it has no chance as being a const param, then we create a `DefId` in `DefCollector` -- otherwise we decide during ast_lowering. This will have to be updated once all path consts use `ConstArgKind::Path`. - We explicitly use `ConstArgHasType` for array lengths, rather than implicitly relying on anon const type feeding -- this is due to the addition of `ConstArgKind::Path`. - Some tests have their outputs changed, but the changes are for the most part minor (including removing duplicate or almost-duplicate errors). One test now ICEs, but it is for an incomplete, unstable feature and is now tracked at rust-lang#127009. ### Followup items post-merge - Use `ConstArgKind::Path` for all const paths, not just const params. - Fix (no github dont close this issue) rust-lang#127009 - If a path in generic args doesn't resolve as a type, try to resolve as a const instead (do this in rustc_resolve). Then remove the special-casing from `rustc_ast_lowering`, so that all params will automatically be lowered as `ConstArgKind::Path`. - (?) Consider making `const_evaluatable_unchecked` a hard error, or at least trying it in crater r? `@BoxyUwU`
2 parents 3d68afc + c8457e6 commit 8c3a94a

File tree

72 files changed

+850
-540
lines changed

Some content is hidden

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

72 files changed

+850
-540
lines changed

compiler/rustc_ast_lowering/src/asm.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
187187
.emit();
188188
}
189189
hir::InlineAsmOperand::Const {
190-
anon_const: self.lower_anon_const(anon_const),
190+
anon_const: self.lower_anon_const_to_anon_const(anon_const),
191191
}
192192
}
193193
InlineAsmOperand::Sym { sym } => {
@@ -222,18 +222,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
222222
};
223223

224224
// Wrap the expression in an AnonConst.
225-
let parent_def_id = self.current_hir_id_owner;
225+
let parent_def_id = self.current_def_id_parent;
226226
let node_id = self.next_node_id();
227-
self.create_def(
228-
parent_def_id.def_id,
229-
node_id,
230-
kw::Empty,
231-
DefKind::AnonConst,
232-
*op_sp,
233-
);
227+
// HACK(min_generic_const_args): see lower_anon_const
228+
if !expr.is_potential_trivial_const_arg() {
229+
self.create_def(
230+
parent_def_id,
231+
node_id,
232+
kw::Empty,
233+
DefKind::AnonConst,
234+
*op_sp,
235+
);
236+
}
234237
let anon_const = AnonConst { id: node_id, value: P(expr) };
235238
hir::InlineAsmOperand::SymFn {
236-
anon_const: self.lower_anon_const(&anon_const),
239+
anon_const: self.lower_anon_const_to_anon_const(&anon_const),
237240
}
238241
}
239242
}

compiler/rustc_ast_lowering/src/expr.rs

+73-62
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
7575
let kind = match &e.kind {
7676
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
7777
ExprKind::ConstBlock(c) => {
78-
let c = self.with_new_scopes(c.value.span, |this| hir::ConstBlock {
79-
def_id: this.local_def_id(c.id),
80-
hir_id: this.lower_node_id(c.id),
81-
body: this.lower_const_body(c.value.span, Some(&c.value)),
78+
let c = self.with_new_scopes(c.value.span, |this| {
79+
let def_id = this.local_def_id(c.id);
80+
hir::ConstBlock {
81+
def_id,
82+
hir_id: this.lower_node_id(c.id),
83+
body: this.with_def_id_parent(def_id, |this| {
84+
this.lower_const_body(c.value.span, Some(&c.value))
85+
}),
86+
}
8287
});
8388
hir::ExprKind::ConstBlock(c)
8489
}
@@ -377,17 +382,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
377382
let mut generic_args = ThinVec::new();
378383
for (idx, arg) in args.into_iter().enumerate() {
379384
if legacy_args_idx.contains(&idx) {
380-
let parent_def_id = self.current_hir_id_owner;
385+
let parent_def_id = self.current_def_id_parent;
381386
let node_id = self.next_node_id();
382387

383-
// Add a definition for the in-band const def.
384-
self.create_def(
385-
parent_def_id.def_id,
386-
node_id,
387-
kw::Empty,
388-
DefKind::AnonConst,
389-
f.span,
390-
);
388+
// HACK(min_generic_const_args): see lower_anon_const
389+
if !arg.is_potential_trivial_const_arg() {
390+
// Add a definition for the in-band const def.
391+
self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span);
392+
}
391393

392394
let anon_const = AnonConst { id: node_id, value: arg };
393395
generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const)));
@@ -622,6 +624,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
622624
coroutine_source: hir::CoroutineSource,
623625
body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
624626
) -> hir::ExprKind<'hir> {
627+
let closure_def_id = self.local_def_id(closure_node_id);
625628
let coroutine_kind = hir::CoroutineKind::Desugared(desugaring_kind, coroutine_source);
626629

627630
// The `async` desugaring takes a resume argument and maintains a `task_context`,
@@ -672,22 +675,24 @@ impl<'hir> LoweringContext<'_, 'hir> {
672675
lifetime_elision_allowed: false,
673676
});
674677

675-
let body = self.lower_body(move |this| {
676-
this.coroutine_kind = Some(coroutine_kind);
678+
let body = self.with_def_id_parent(closure_def_id, move |this| {
679+
this.lower_body(move |this| {
680+
this.coroutine_kind = Some(coroutine_kind);
677681

678-
let old_ctx = this.task_context;
679-
if task_context.is_some() {
680-
this.task_context = task_context;
681-
}
682-
let res = body(this);
683-
this.task_context = old_ctx;
682+
let old_ctx = this.task_context;
683+
if task_context.is_some() {
684+
this.task_context = task_context;
685+
}
686+
let res = body(this);
687+
this.task_context = old_ctx;
684688

685-
(params, res)
689+
(params, res)
690+
})
686691
});
687692

688693
// `static |<_task_context?>| -> <return_ty> { <body> }`:
689694
hir::ExprKind::Closure(self.arena.alloc(hir::Closure {
690-
def_id: self.local_def_id(closure_node_id),
695+
def_id: closure_def_id,
691696
binder: hir::ClosureBinder::Default,
692697
capture_clause,
693698
bound_generic_params: &[],
@@ -966,35 +971,38 @@ impl<'hir> LoweringContext<'_, 'hir> {
966971
fn_decl_span: Span,
967972
fn_arg_span: Span,
968973
) -> hir::ExprKind<'hir> {
974+
let closure_def_id = self.local_def_id(closure_id);
969975
let (binder_clause, generic_params) = self.lower_closure_binder(binder);
970976

971977
let (body_id, closure_kind) = self.with_new_scopes(fn_decl_span, move |this| {
972-
let mut coroutine_kind = if this
973-
.attrs
974-
.get(&closure_hir_id.local_id)
975-
.is_some_and(|attrs| attrs.iter().any(|attr| attr.has_name(sym::coroutine)))
976-
{
977-
Some(hir::CoroutineKind::Coroutine(Movability::Movable))
978-
} else {
979-
None
980-
};
981-
let body_id = this.lower_fn_body(decl, |this| {
982-
this.coroutine_kind = coroutine_kind;
983-
let e = this.lower_expr_mut(body);
984-
coroutine_kind = this.coroutine_kind;
985-
e
986-
});
987-
let coroutine_option =
988-
this.closure_movability_for_fn(decl, fn_decl_span, coroutine_kind, movability);
989-
(body_id, coroutine_option)
978+
this.with_def_id_parent(closure_def_id, move |this| {
979+
let mut coroutine_kind = if this
980+
.attrs
981+
.get(&closure_hir_id.local_id)
982+
.is_some_and(|attrs| attrs.iter().any(|attr| attr.has_name(sym::coroutine)))
983+
{
984+
Some(hir::CoroutineKind::Coroutine(Movability::Movable))
985+
} else {
986+
None
987+
};
988+
let body_id = this.lower_fn_body(decl, |this| {
989+
this.coroutine_kind = coroutine_kind;
990+
let e = this.lower_expr_mut(body);
991+
coroutine_kind = this.coroutine_kind;
992+
e
993+
});
994+
let coroutine_option =
995+
this.closure_movability_for_fn(decl, fn_decl_span, coroutine_kind, movability);
996+
(body_id, coroutine_option)
997+
})
990998
});
991999

9921000
let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params);
9931001
// Lower outside new scope to preserve `is_in_loop_condition`.
9941002
let fn_decl = self.lower_fn_decl(decl, closure_id, fn_decl_span, FnDeclKind::Closure, None);
9951003

9961004
let c = self.arena.alloc(hir::Closure {
997-
def_id: self.local_def_id(closure_id),
1005+
def_id: closure_def_id,
9981006
binder: binder_clause,
9991007
capture_clause,
10001008
bound_generic_params,
@@ -1066,6 +1074,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10661074
fn_decl_span: Span,
10671075
fn_arg_span: Span,
10681076
) -> hir::ExprKind<'hir> {
1077+
let closure_def_id = self.local_def_id(closure_id);
10691078
let (binder_clause, generic_params) = self.lower_closure_binder(binder);
10701079

10711080
assert_matches!(
@@ -1075,27 +1084,29 @@ impl<'hir> LoweringContext<'_, 'hir> {
10751084
);
10761085

10771086
let body = self.with_new_scopes(fn_decl_span, |this| {
1078-
let inner_decl =
1079-
FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) };
1080-
1081-
// Transform `async |x: u8| -> X { ... }` into
1082-
// `|x: u8| || -> X { ... }`.
1083-
let body_id = this.lower_body(|this| {
1084-
let (parameters, expr) = this.lower_coroutine_body_with_moved_arguments(
1085-
&inner_decl,
1086-
|this| this.with_new_scopes(fn_decl_span, |this| this.lower_expr_mut(body)),
1087-
fn_decl_span,
1088-
body.span,
1089-
coroutine_kind,
1090-
hir::CoroutineSource::Closure,
1091-
);
1087+
this.with_def_id_parent(closure_def_id, |this| {
1088+
let inner_decl =
1089+
FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) };
1090+
1091+
// Transform `async |x: u8| -> X { ... }` into
1092+
// `|x: u8| || -> X { ... }`.
1093+
let body_id = this.lower_body(|this| {
1094+
let (parameters, expr) = this.lower_coroutine_body_with_moved_arguments(
1095+
&inner_decl,
1096+
|this| this.with_new_scopes(fn_decl_span, |this| this.lower_expr_mut(body)),
1097+
fn_decl_span,
1098+
body.span,
1099+
coroutine_kind,
1100+
hir::CoroutineSource::Closure,
1101+
);
10921102

1093-
let hir_id = this.lower_node_id(coroutine_kind.closure_id());
1094-
this.maybe_forward_track_caller(body.span, closure_hir_id, hir_id);
1103+
let hir_id = this.lower_node_id(coroutine_kind.closure_id());
1104+
this.maybe_forward_track_caller(body.span, closure_hir_id, hir_id);
10951105

1096-
(parameters, expr)
1097-
});
1098-
body_id
1106+
(parameters, expr)
1107+
});
1108+
body_id
1109+
})
10991110
});
11001111

11011112
let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params);
@@ -1106,7 +1117,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
11061117
self.lower_fn_decl(&decl, closure_id, fn_decl_span, FnDeclKind::Closure, None);
11071118

11081119
let c = self.arena.alloc(hir::Closure {
1109-
def_id: self.local_def_id(closure_id),
1120+
def_id: closure_def_id,
11101121
binder: binder_clause,
11111122
capture_clause,
11121123
bound_generic_params,

compiler/rustc_ast_lowering/src/index.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
181181
intravisit::walk_generic_param(self, param);
182182
}
183183

184-
fn visit_const_param_default(&mut self, param: HirId, ct: &'hir AnonConst) {
184+
fn visit_const_param_default(&mut self, param: HirId, ct: &'hir ConstArg<'hir>) {
185185
self.with_parent(param, |this| {
186186
intravisit::walk_const_param_default(this, ct);
187187
})
@@ -229,6 +229,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
229229
}
230230

231231
fn visit_anon_const(&mut self, constant: &'hir AnonConst) {
232+
// FIXME: use real span?
232233
self.insert(DUMMY_SP, constant.hir_id, Node::AnonConst(constant));
233234

234235
self.with_parent(constant.hir_id, |this| {
@@ -244,6 +245,15 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
244245
});
245246
}
246247

248+
fn visit_const_arg(&mut self, const_arg: &'hir ConstArg<'hir>) {
249+
// FIXME: use real span?
250+
self.insert(DUMMY_SP, const_arg.hir_id, Node::ConstArg(const_arg));
251+
252+
self.with_parent(const_arg.hir_id, |this| {
253+
intravisit::walk_const_arg(this, const_arg);
254+
});
255+
}
256+
247257
fn visit_expr(&mut self, expr: &'hir Expr<'hir>) {
248258
self.insert(expr.span, expr.hir_id, Node::Expr(expr));
249259

compiler/rustc_ast_lowering/src/item.rs

+19-10
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
6161

6262
for (def_id, info) in lctx.children {
6363
let owner = self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
64-
debug_assert!(matches!(owner, hir::MaybeOwner::Phantom));
64+
debug_assert!(
65+
matches!(owner, hir::MaybeOwner::Phantom),
66+
"duplicate copy of {def_id:?} in lctx.children"
67+
);
6568
*owner = info;
6669
}
6770
}
@@ -713,7 +716,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
713716
hir_id,
714717
def_id: self.local_def_id(v.id),
715718
data: self.lower_variant_data(hir_id, &v.data),
716-
disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const(e)),
719+
disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const_to_anon_const(e)),
717720
ident: self.lower_ident(v.ident),
718721
span: self.lower_span(v.span),
719722
}
@@ -1601,15 +1604,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
16011604

16021605
if let Some((span, hir_id, def_id)) = host_param_parts {
16031606
let const_node_id = self.next_node_id();
1604-
let anon_const =
1607+
let anon_const_did =
16051608
self.create_def(def_id, const_node_id, kw::Empty, DefKind::AnonConst, span);
16061609

16071610
let const_id = self.next_id();
16081611
let const_expr_id = self.next_id();
16091612
let bool_id = self.next_id();
16101613

16111614
self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));
1612-
self.children.push((anon_const, hir::MaybeOwner::NonOwner(const_id)));
1615+
self.children.push((anon_const_did, hir::MaybeOwner::NonOwner(const_id)));
16131616

16141617
let const_body = self.lower_body(|this| {
16151618
(
@@ -1624,6 +1627,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
16241627
)
16251628
});
16261629

1630+
let default_ac = self.arena.alloc(hir::AnonConst {
1631+
def_id: anon_const_did,
1632+
hir_id: const_id,
1633+
body: const_body,
1634+
span,
1635+
});
1636+
let default_ct = self.arena.alloc(hir::ConstArg {
1637+
hir_id: self.next_id(),
1638+
kind: hir::ConstArgKind::Anon(default_ac),
1639+
is_desugared_from_effects: false,
1640+
});
16271641
let param = hir::GenericParam {
16281642
def_id,
16291643
hir_id,
@@ -1648,12 +1662,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
16481662
)),
16491663
)),
16501664
// FIXME(effects) we might not need a default.
1651-
default: Some(self.arena.alloc(hir::AnonConst {
1652-
def_id: anon_const,
1653-
hir_id: const_id,
1654-
body: const_body,
1655-
span,
1656-
})),
1665+
default: Some(default_ct),
16571666
is_host_effect: true,
16581667
synthetic: true,
16591668
},

0 commit comments

Comments
 (0)