Skip to content

Commit 73be83c

Browse files
committed
Delay def collection for expression-like nodes
These expression-like nodes are anon const args, const blocks, closures, and generators. They need to have their def collection delayed because some anon const args turn into `ConstArgKind::Path`, which has no DefId. Thus defs that could have an anon const as their parent must be delayed as well.
1 parent 86e7875 commit 73be83c

File tree

4 files changed

+74
-118
lines changed

4 files changed

+74
-118
lines changed

compiler/rustc_ast_lowering/src/asm.rs

-12
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
77
use rustc_hir as hir;
88
use rustc_hir::def::{DefKind, Res};
99
use rustc_session::parse::feature_err;
10-
use rustc_span::symbol::kw;
1110
use rustc_span::{sym, Span};
1211
use rustc_target::asm;
1312

@@ -222,18 +221,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
222221
};
223222

224223
// Wrap the expression in an AnonConst.
225-
let parent_def_id = self.current_def_id_parent;
226224
let node_id = self.next_node_id();
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-
}
237225
let anon_const = AnonConst { id: node_id, value: P(expr) };
238226
hir::InlineAsmOperand::SymFn {
239227
anon_const: self.lower_anon_const_to_anon_const(&anon_const),

compiler/rustc_ast_lowering/src/expr.rs

+47-34
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
7777
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
7878
ExprKind::ConstBlock(c) => {
7979
let c = self.with_new_scopes(c.value.span, |this| {
80-
let def_id = this.local_def_id(c.id);
80+
let def_id = this.create_def(
81+
this.current_def_id_parent,
82+
c.id,
83+
kw::Empty,
84+
DefKind::InlineConst,
85+
c.value.span,
86+
);
8187
hir::ConstBlock {
8288
def_id,
8389
hir_id: this.lower_node_id(c.id),
@@ -207,31 +213,40 @@ impl<'hir> LoweringContext<'_, 'hir> {
207213
body,
208214
fn_decl_span,
209215
fn_arg_span,
210-
}) => match coroutine_kind {
211-
Some(coroutine_kind) => self.lower_expr_coroutine_closure(
212-
binder,
213-
*capture_clause,
214-
e.id,
215-
hir_id,
216-
*coroutine_kind,
217-
fn_decl,
218-
body,
219-
*fn_decl_span,
220-
*fn_arg_span,
221-
),
222-
None => self.lower_expr_closure(
223-
binder,
224-
*capture_clause,
216+
}) => {
217+
let closure_def = self.create_def(
218+
self.current_def_id_parent,
225219
e.id,
226-
hir_id,
227-
*constness,
228-
*movability,
229-
fn_decl,
230-
body,
231-
*fn_decl_span,
232-
*fn_arg_span,
233-
),
234-
},
220+
kw::Empty,
221+
DefKind::Closure,
222+
e.span,
223+
);
224+
self.with_def_id_parent(closure_def, |this| match coroutine_kind {
225+
Some(coroutine_kind) => this.lower_expr_coroutine_closure(
226+
binder,
227+
*capture_clause,
228+
e.id,
229+
hir_id,
230+
*coroutine_kind,
231+
fn_decl,
232+
body,
233+
*fn_decl_span,
234+
*fn_arg_span,
235+
),
236+
None => this.lower_expr_closure(
237+
binder,
238+
*capture_clause,
239+
e.id,
240+
hir_id,
241+
*constness,
242+
*movability,
243+
fn_decl,
244+
body,
245+
*fn_decl_span,
246+
*fn_arg_span,
247+
),
248+
})
249+
}
235250
ExprKind::Gen(capture_clause, block, genblock_kind, decl_span) => {
236251
let desugaring_kind = match genblock_kind {
237252
GenBlockKind::Async => hir::CoroutineDesugaring::Async,
@@ -383,15 +398,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
383398
let mut generic_args = ThinVec::new();
384399
for (idx, arg) in args.into_iter().enumerate() {
385400
if legacy_args_idx.contains(&idx) {
386-
let parent_def_id = self.current_def_id_parent;
387401
let node_id = self.next_node_id();
388-
389-
// HACK(min_generic_const_args): see lower_anon_const
390-
if !arg.is_potential_trivial_const_arg() {
391-
// Add a definition for the in-band const def.
392-
self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span);
393-
}
394-
395402
let anon_const = AnonConst { id: node_id, value: arg };
396403
generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const)));
397404
} else {
@@ -625,7 +632,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
625632
coroutine_source: hir::CoroutineSource,
626633
body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
627634
) -> hir::ExprKind<'hir> {
628-
let closure_def_id = self.local_def_id(closure_node_id);
635+
let closure_def_id = self.create_def(
636+
self.current_def_id_parent,
637+
closure_node_id,
638+
kw::Empty,
639+
DefKind::Closure,
640+
span,
641+
);
629642
let coroutine_kind = hir::CoroutineKind::Desugared(desugaring_kind, coroutine_source);
630643

631644
// The `async` desugaring takes a resume argument and maintains a `task_context`,

compiler/rustc_ast_lowering/src/lib.rs

+10-13
Original file line numberDiff line numberDiff line change
@@ -2465,19 +2465,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
24652465
/// See [`hir::ConstArg`] for when to use this function vs
24662466
/// [`Self::lower_anon_const_to_const_arg`].
24672467
fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
2468-
if c.value.is_potential_trivial_const_arg() {
2469-
// HACK(min_generic_const_args): see DefCollector::visit_anon_const
2470-
// Over there, we guess if this is a bare param and only create a def if
2471-
// we think it's not. However we may can guess wrong (see there for example)
2472-
// in which case we have to create the def here.
2473-
self.create_def(
2474-
self.current_def_id_parent,
2475-
c.id,
2476-
kw::Empty,
2477-
DefKind::AnonConst,
2478-
c.value.span,
2479-
);
2480-
}
2468+
// HACK(min_generic_const_args): see DefCollector::visit_anon_const
2469+
// We delay creation of defs for expression-like things, including anon consts.
2470+
// This is because some anon consts end up as `ConstArgKind::Path`'s instead.
2471+
self.create_def(
2472+
self.current_def_id_parent,
2473+
c.id,
2474+
kw::Empty,
2475+
DefKind::AnonConst,
2476+
c.value.span,
2477+
);
24812478

24822479
self.arena.alloc(self.with_new_scopes(c.value.span, |this| {
24832480
let def_id = this.local_def_id(c.id);

compiler/rustc_resolve/src/def_collector.rs

+17-59
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,10 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
182182
});
183183
}
184184

185-
fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
185+
fn visit_fn(&mut self, fn_kind: FnKind<'a>, _: Span, _: NodeId) {
186186
if let FnKind::Fn(_, _, sig, _, generics, body) = fn_kind {
187187
match sig.header.coroutine_kind {
188-
Some(coroutine_kind) => {
188+
Some(_) => {
189189
self.visit_generics(generics);
190190

191191
// For async functions, we need to create their inner defs inside of a
@@ -196,17 +196,10 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
196196
self.visit_param(param);
197197
}
198198
self.visit_fn_ret_ty(&sig.decl.output);
199-
// If this async fn has no body (i.e. it's an async fn signature in a trait)
200-
// then the closure_def will never be used, and we should avoid generating a
201-
// def-id for it.
202199
if let Some(body) = body {
203-
let closure_def = self.create_def(
204-
coroutine_kind.closure_id(),
205-
kw::Empty,
206-
DefKind::Closure,
207-
span,
208-
);
209-
self.with_parent(closure_def, |this| this.visit_block(body));
200+
// HACK(min_generic_const_args): expression-like things (including coroutines)
201+
// have their defs created later, in ast_lowering
202+
self.visit_block(body);
210203
}
211204
return;
212205
}
@@ -314,64 +307,29 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
314307
}
315308

316309
fn visit_anon_const(&mut self, constant: &'a AnonConst) {
317-
// HACK(min_generic_const_args): don't create defs for anon consts if we think they will
318-
// later be turned into ConstArgKind::Path's. because this is before resolve is done, we
319-
// may accidentally identify a construction of a unit struct as a param and not create a
320-
// def. we'll then create a def later in ast lowering in this case. the parent of nested
321-
// items will be messed up, but that's ok because there can't be any if we're just looking
322-
// for bare idents.
323-
if constant.value.is_potential_trivial_const_arg() {
324-
visit::walk_anon_const(self, constant)
325-
} else {
326-
let def =
327-
self.create_def(constant.id, kw::Empty, DefKind::AnonConst, constant.value.span);
328-
self.with_parent(def, |this| visit::walk_anon_const(this, constant));
329-
}
310+
// HACK(min_generic_const_args): expressions with defs (const blocks,
311+
// anon consts, closures/generators) have their defs created later,
312+
// during ast_lowering
313+
visit::walk_anon_const(self, constant)
330314
}
331315

332316
fn visit_expr(&mut self, expr: &'a Expr) {
333-
let parent_def = match expr.kind {
317+
// HACK(min_generic_const_args): expressions with defs (const blocks,
318+
// anon consts, closures/generators) have their defs created later,
319+
// during ast_lowering
320+
match expr.kind {
334321
ExprKind::MacCall(..) => return self.visit_macro_invoc(expr.id),
335-
ExprKind::Closure(ref closure) => {
336-
// Async closures desugar to closures inside of closures, so
337-
// we must create two defs.
338-
let closure_def = self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span);
339-
match closure.coroutine_kind {
340-
Some(coroutine_kind) => {
341-
self.with_parent(closure_def, |this| {
342-
let coroutine_def = this.create_def(
343-
coroutine_kind.closure_id(),
344-
kw::Empty,
345-
DefKind::Closure,
346-
expr.span,
347-
);
348-
this.with_parent(coroutine_def, |this| visit::walk_expr(this, expr));
349-
});
350-
return;
351-
}
352-
None => closure_def,
353-
}
354-
}
355-
ExprKind::Gen(_, _, _, _) => {
356-
self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span)
357-
}
358322
ExprKind::ConstBlock(ref constant) => {
359323
for attr in &expr.attrs {
360324
visit::walk_attribute(self, attr);
361325
}
362-
let def = self.create_def(
363-
constant.id,
364-
kw::Empty,
365-
DefKind::InlineConst,
366-
constant.value.span,
367-
);
368-
self.with_parent(def, |this| visit::walk_anon_const(this, constant));
326+
visit::walk_anon_const(self, constant);
369327
return;
370328
}
371-
_ => self.parent_def,
372-
};
329+
_ => {}
330+
}
373331

374-
self.with_parent(parent_def, |this| visit::walk_expr(this, expr));
332+
visit::walk_expr(self, expr);
375333
}
376334

377335
fn visit_ty(&mut self, ty: &'a Ty) {

0 commit comments

Comments
 (0)