Skip to content

Commit 37ed7a4

Browse files
committed
Add ConstArgKind::Path and make ConstArg its own HIR node
This is a very large commit since a lot needs to be changed in order to make the tests pass. The salient changes are: - `ConstArgKind` gets a new `Path` variant, and all const params are now represented using it. Non-param paths still use `ConstArgKind::Anon` to prevent this change from getting too large, but they will soon use the `Path` variant too. - `ConstArg` gets a distinct `hir_id` field and its own variant in `hir::Node`. This affected many parts of the compiler that expected the parent of an `AnonConst` to be the containing context (e.g., an array repeat expression). They have been changed to check the "grandparent" where necessary. - 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.
1 parent 1c49d40 commit 37ed7a4

File tree

61 files changed

+541
-414
lines changed

Some content is hidden

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

61 files changed

+541
-414
lines changed

compiler/rustc_ast_lowering/src/asm.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -224,13 +224,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
224224
// Wrap the expression in an AnonConst.
225225
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,
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 {
236239
anon_const: self.lower_anon_const_to_anon_const(&anon_const),

compiler/rustc_ast_lowering/src/expr.rs

+72-55
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
}
@@ -380,8 +385,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
380385
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(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span);
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+
}
385393

386394
let anon_const = AnonConst { id: node_id, value: arg };
387395
generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const)));
@@ -616,6 +624,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
616624
coroutine_source: hir::CoroutineSource,
617625
body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
618626
) -> hir::ExprKind<'hir> {
627+
let closure_def_id = self.local_def_id(closure_node_id);
619628
let coroutine_kind = hir::CoroutineKind::Desugared(desugaring_kind, coroutine_source);
620629

621630
// The `async` desugaring takes a resume argument and maintains a `task_context`,
@@ -666,22 +675,24 @@ impl<'hir> LoweringContext<'_, 'hir> {
666675
lifetime_elision_allowed: false,
667676
});
668677

669-
let body = self.lower_body(move |this| {
670-
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);
671681

672-
let old_ctx = this.task_context;
673-
if task_context.is_some() {
674-
this.task_context = task_context;
675-
}
676-
let res = body(this);
677-
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;
678688

679-
(params, res)
689+
(params, res)
690+
})
680691
});
681692

682693
// `static |<_task_context?>| -> <return_ty> { <body> }`:
683694
hir::ExprKind::Closure(self.arena.alloc(hir::Closure {
684-
def_id: self.local_def_id(closure_node_id),
695+
def_id: closure_def_id,
685696
binder: hir::ClosureBinder::Default,
686697
capture_clause,
687698
bound_generic_params: &[],
@@ -960,35 +971,38 @@ impl<'hir> LoweringContext<'_, 'hir> {
960971
fn_decl_span: Span,
961972
fn_arg_span: Span,
962973
) -> hir::ExprKind<'hir> {
974+
let closure_def_id = self.local_def_id(closure_id);
963975
let (binder_clause, generic_params) = self.lower_closure_binder(binder);
964976

965977
let (body_id, closure_kind) = self.with_new_scopes(fn_decl_span, move |this| {
966-
let mut coroutine_kind = if this
967-
.attrs
968-
.get(&closure_hir_id.local_id)
969-
.is_some_and(|attrs| attrs.iter().any(|attr| attr.has_name(sym::coroutine)))
970-
{
971-
Some(hir::CoroutineKind::Coroutine(Movability::Movable))
972-
} else {
973-
None
974-
};
975-
let body_id = this.lower_fn_body(decl, |this| {
976-
this.coroutine_kind = coroutine_kind;
977-
let e = this.lower_expr_mut(body);
978-
coroutine_kind = this.coroutine_kind;
979-
e
980-
});
981-
let coroutine_option =
982-
this.closure_movability_for_fn(decl, fn_decl_span, coroutine_kind, movability);
983-
(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+
})
984998
});
985999

9861000
let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params);
9871001
// Lower outside new scope to preserve `is_in_loop_condition`.
9881002
let fn_decl = self.lower_fn_decl(decl, closure_id, fn_decl_span, FnDeclKind::Closure, None);
9891003

9901004
let c = self.arena.alloc(hir::Closure {
991-
def_id: self.local_def_id(closure_id),
1005+
def_id: closure_def_id,
9921006
binder: binder_clause,
9931007
capture_clause,
9941008
bound_generic_params,
@@ -1060,6 +1074,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10601074
fn_decl_span: Span,
10611075
fn_arg_span: Span,
10621076
) -> hir::ExprKind<'hir> {
1077+
let closure_def_id = self.local_def_id(closure_id);
10631078
let (binder_clause, generic_params) = self.lower_closure_binder(binder);
10641079

10651080
assert_matches!(
@@ -1069,27 +1084,29 @@ impl<'hir> LoweringContext<'_, 'hir> {
10691084
);
10701085

10711086
let body = self.with_new_scopes(fn_decl_span, |this| {
1072-
let inner_decl =
1073-
FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) };
1074-
1075-
// Transform `async |x: u8| -> X { ... }` into
1076-
// `|x: u8| || -> X { ... }`.
1077-
let body_id = this.lower_body(|this| {
1078-
let (parameters, expr) = this.lower_coroutine_body_with_moved_arguments(
1079-
&inner_decl,
1080-
|this| this.with_new_scopes(fn_decl_span, |this| this.lower_expr_mut(body)),
1081-
fn_decl_span,
1082-
body.span,
1083-
coroutine_kind,
1084-
hir::CoroutineSource::Closure,
1085-
);
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+
);
10861102

1087-
let hir_id = this.lower_node_id(coroutine_kind.closure_id());
1088-
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);
10891105

1090-
(parameters, expr)
1091-
});
1092-
body_id
1106+
(parameters, expr)
1107+
});
1108+
body_id
1109+
})
10931110
});
10941111

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

11021119
let c = self.arena.alloc(hir::Closure {
1103-
def_id: self.local_def_id(closure_id),
1120+
def_id: closure_def_id,
11041121
binder: binder_clause,
11051122
capture_clause,
11061123
bound_generic_params,

compiler/rustc_ast_lowering/src/index.rs

+10
Original file line numberDiff line numberDiff line change
@@ -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

+7-2
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
}
@@ -1631,8 +1634,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
16311634
span,
16321635
});
16331636
let default_ct = self.arena.alloc(hir::ConstArg {
1637+
hir_id: self.next_id(),
16341638
kind: hir::ConstArgKind::Anon(default_ac),
1635-
is_desugared_from_effects: true,
1639+
is_desugared_from_effects: false,
16361640
});
16371641
let param = hir::GenericParam {
16381642
def_id,
@@ -1657,6 +1661,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
16571661
}),
16581662
)),
16591663
)),
1664+
// FIXME(effects) we might not need a default.
16601665
default: Some(default_ct),
16611666
is_host_effect: true,
16621667
synthetic: true,

0 commit comments

Comments
 (0)