Skip to content

Commit bbdee60

Browse files
committed
Auto merge of rust-lang#124650 - oli-obk:pattern_types_syntax, r=<try>
Create const block DefIds in typeck instead of ast lowering r? `@ghost` this is a prerequisite for cleaning up pattern types and the range pattern HIR nodes in general. Right now they contain expressions, but they are supposed to only contain constants. In order to generate the anonymous constants lazily during typeck, we need to support generating new items with bodies during typeck in general. Transforming const blocks was the simplest change I could find to allow us to do that (everything else is much more invasive if we haven't already done it for const blocks).
2 parents b54dd08 + 8d59f8b commit bbdee60

File tree

39 files changed

+181
-236
lines changed

39 files changed

+181
-236
lines changed

compiler/rustc_ast/src/ast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1393,7 +1393,7 @@ pub enum ExprKind {
13931393
/// An array (e.g, `[a, b, c, d]`).
13941394
Array(ThinVec<P<Expr>>),
13951395
/// Allow anonymous constants from an inline `const` block
1396-
ConstBlock(AnonConst),
1396+
ConstBlock(P<Expr>),
13971397
/// A function call
13981398
///
13991399
/// The first field resolves to the function itself,

compiler/rustc_ast/src/mut_visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1411,7 +1411,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
14111411
match kind {
14121412
ExprKind::Array(exprs) => visit_thin_exprs(exprs, vis),
14131413
ExprKind::ConstBlock(anon_const) => {
1414-
vis.visit_anon_const(anon_const);
1414+
vis.visit_expr(anon_const);
14151415
}
14161416
ExprKind::Repeat(expr, count) => {
14171417
vis.visit_expr(expr);

compiler/rustc_ast/src/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
951951
ExprKind::Array(subexpressions) => {
952952
walk_list!(visitor, visit_expr, subexpressions);
953953
}
954-
ExprKind::ConstBlock(anon_const) => try_visit!(visitor.visit_anon_const(anon_const)),
954+
ExprKind::ConstBlock(anon_const) => try_visit!(visitor.visit_expr(anon_const)),
955955
ExprKind::Repeat(element, count) => {
956956
try_visit!(visitor.visit_expr(element));
957957
try_visit!(visitor.visit_anon_const(count));

compiler/rustc_ast_lowering/src/expr.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
7474

7575
let kind = match &e.kind {
7676
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
77-
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)),
82-
});
83-
hir::ExprKind::ConstBlock(c)
84-
}
77+
ExprKind::ConstBlock(c) => hir::ExprKind::ConstBlock(self.lower_expr(c)),
8578
ExprKind::Repeat(expr, count) => {
8679
let expr = self.lower_expr(expr);
8780
let count = self.lower_array_length(count);

compiler/rustc_ast_lowering/src/index.rs

-8
Original file line numberDiff line numberDiff line change
@@ -236,14 +236,6 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
236236
});
237237
}
238238

239-
fn visit_inline_const(&mut self, constant: &'hir ConstBlock) {
240-
self.insert(DUMMY_SP, constant.hir_id, Node::ConstBlock(constant));
241-
242-
self.with_parent(constant.hir_id, |this| {
243-
intravisit::walk_inline_const(this, constant);
244-
});
245-
}
246-
247239
fn visit_expr(&mut self, expr: &'hir Expr<'hir>) {
248240
self.insert(expr.span, expr.hir_id, Node::Expr(expr));
249241

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -380,8 +380,9 @@ impl<'a> State<'a> {
380380
ast::ExprKind::Array(exprs) => {
381381
self.print_expr_vec(exprs);
382382
}
383-
ast::ExprKind::ConstBlock(anon_const) => {
384-
self.print_expr_anon_const(anon_const, attrs);
383+
ast::ExprKind::ConstBlock(expr) => {
384+
self.word_space("const");
385+
self.print_expr(expr, FixupContext::default());
385386
}
386387
ast::ExprKind::Repeat(element, count) => {
387388
self.print_expr_repeat(element, count);

compiler/rustc_const_eval/src/const_eval/fn_queries.rs

-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
3838
match node {
3939
hir::Node::Ctor(_)
4040
| hir::Node::AnonConst(_)
41-
| hir::Node::ConstBlock(_)
4241
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => {
4342
hir::Constness::Const
4443
}

compiler/rustc_const_eval/src/const_eval/machine.rs

+1-13
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use std::ops::ControlFlow;
66
use rustc_ast::Mutability;
77
use rustc_data_structures::fx::FxIndexMap;
88
use rustc_data_structures::fx::IndexEntry;
9-
use rustc_hir::def::DefKind;
109
use rustc_hir::def_id::DefId;
1110
use rustc_hir::def_id::LocalDefId;
1211
use rustc_hir::LangItem;
@@ -392,18 +391,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
392391
instance: ty::InstanceDef<'tcx>,
393392
) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> {
394393
match instance {
395-
ty::InstanceDef::Item(def) => {
396-
if ecx.tcx.is_ctfe_mir_available(def) {
397-
Ok(ecx.tcx.mir_for_ctfe(def))
398-
} else if ecx.tcx.def_kind(def) == DefKind::AssocConst {
399-
ecx.tcx.dcx().bug("This is likely a const item that is missing from its impl");
400-
} else {
401-
// `find_mir_or_eval_fn` checks that this is a const fn before even calling us,
402-
// so this should be unreachable.
403-
let path = ecx.tcx.def_path_str(def);
404-
bug!("trying to call extern function `{path}` at compile-time");
405-
}
406-
}
394+
ty::InstanceDef::Item(def) => Ok(ecx.tcx.mir_for_ctfe(def)),
407395
_ => Ok(ecx.tcx.instance_mir(instance)),
408396
}
409397
}

compiler/rustc_hir/src/hir.rs

+1-13
Original file line numberDiff line numberDiff line change
@@ -1592,14 +1592,6 @@ pub struct AnonConst {
15921592
pub span: Span,
15931593
}
15941594

1595-
/// An inline constant expression `const { something }`.
1596-
#[derive(Copy, Clone, Debug, HashStable_Generic)]
1597-
pub struct ConstBlock {
1598-
pub hir_id: HirId,
1599-
pub def_id: LocalDefId,
1600-
pub body: BodyId,
1601-
}
1602-
16031595
/// An expression.
16041596
#[derive(Debug, Clone, Copy, HashStable_Generic)]
16051597
pub struct Expr<'hir> {
@@ -1886,7 +1878,7 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool {
18861878
#[derive(Debug, Clone, Copy, HashStable_Generic)]
18871879
pub enum ExprKind<'hir> {
18881880
/// Allow anonymous constants from an inline `const` block
1889-
ConstBlock(ConstBlock),
1881+
ConstBlock(&'hir Expr<'hir>),
18901882
/// An array (e.g., `[a, b, c, d]`).
18911883
Array(&'hir [Expr<'hir>]),
18921884
/// A function call.
@@ -3609,7 +3601,6 @@ pub enum Node<'hir> {
36093601
Variant(&'hir Variant<'hir>),
36103602
Field(&'hir FieldDef<'hir>),
36113603
AnonConst(&'hir AnonConst),
3612-
ConstBlock(&'hir ConstBlock),
36133604
Expr(&'hir Expr<'hir>),
36143605
ExprField(&'hir ExprField<'hir>),
36153606
Stmt(&'hir Stmt<'hir>),
@@ -3670,7 +3661,6 @@ impl<'hir> Node<'hir> {
36703661
Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident),
36713662
Node::Param(..)
36723663
| Node::AnonConst(..)
3673-
| Node::ConstBlock(..)
36743664
| Node::Expr(..)
36753665
| Node::Stmt(..)
36763666
| Node::Block(..)
@@ -3768,7 +3758,6 @@ impl<'hir> Node<'hir> {
37683758
}
37693759

37703760
Node::AnonConst(constant) => Some((constant.def_id, constant.body)),
3771-
Node::ConstBlock(constant) => Some((constant.def_id, constant.body)),
37723761

37733762
_ => None,
37743763
}
@@ -3837,7 +3826,6 @@ impl<'hir> Node<'hir> {
38373826
expect_variant, &'hir Variant<'hir>, Node::Variant(n), n;
38383827
expect_field, &'hir FieldDef<'hir>, Node::Field(n), n;
38393828
expect_anon_const, &'hir AnonConst, Node::AnonConst(n), n;
3840-
expect_inline_const, &'hir ConstBlock, Node::ConstBlock(n), n;
38413829
expect_expr, &'hir Expr<'hir>, Node::Expr(n), n;
38423830
expect_expr_field, &'hir ExprField<'hir>, Node::ExprField(n), n;
38433831
expect_stmt, &'hir Stmt<'hir>, Node::Stmt(n), n;

compiler/rustc_hir/src/intravisit.rs

+1-12
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,6 @@ pub trait Visitor<'v>: Sized {
344344
fn visit_anon_const(&mut self, c: &'v AnonConst) -> Self::Result {
345345
walk_anon_const(self, c)
346346
}
347-
fn visit_inline_const(&mut self, c: &'v ConstBlock) -> Self::Result {
348-
walk_inline_const(self, c)
349-
}
350347
fn visit_expr(&mut self, ex: &'v Expr<'v>) -> Self::Result {
351348
walk_expr(self, ex)
352349
}
@@ -716,22 +713,14 @@ pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonCo
716713
visitor.visit_nested_body(constant.body)
717714
}
718715

719-
pub fn walk_inline_const<'v, V: Visitor<'v>>(
720-
visitor: &mut V,
721-
constant: &'v ConstBlock,
722-
) -> V::Result {
723-
try_visit!(visitor.visit_id(constant.hir_id));
724-
visitor.visit_nested_body(constant.body)
725-
}
726-
727716
pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) -> V::Result {
728717
try_visit!(visitor.visit_id(expression.hir_id));
729718
match expression.kind {
730719
ExprKind::Array(subexpressions) => {
731720
walk_list!(visitor, visit_expr, subexpressions);
732721
}
733722
ExprKind::ConstBlock(ref const_block) => {
734-
try_visit!(visitor.visit_inline_const(const_block))
723+
try_visit!(visitor.visit_expr(const_block))
735724
}
736725
ExprKind::Repeat(ref element, ref count) => {
737726
try_visit!(visitor.visit_expr(element));

compiler/rustc_hir_analysis/src/check/region.rs

+64-55
Original file line numberDiff line numberDiff line change
@@ -407,11 +407,14 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
407407
match expr.kind {
408408
// Manually recurse over closures and inline consts, because they are the only
409409
// case of nested bodies that share the parent environment.
410-
hir::ExprKind::Closure(&hir::Closure { body, .. })
411-
| hir::ExprKind::ConstBlock(hir::ConstBlock { body, .. }) => {
410+
hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
412411
let body = visitor.tcx.hir().body(body);
413412
visitor.visit_body(body);
414413
}
414+
hir::ExprKind::ConstBlock(expr) => visitor.enter_body(expr.hir_id, |this| {
415+
this.cx.var_parent = None;
416+
resolve_local(this, None, Some(expr));
417+
}),
415418
hir::ExprKind::AssignOp(_, left_expr, right_expr) => {
416419
debug!(
417420
"resolve_expr - enabling pessimistic_yield, was previously {}",
@@ -782,25 +785,8 @@ impl<'tcx> RegionResolutionVisitor<'tcx> {
782785
}
783786
self.enter_scope(Scope { id, data: ScopeData::Node });
784787
}
785-
}
786-
787-
impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
788-
fn visit_block(&mut self, b: &'tcx Block<'tcx>) {
789-
resolve_block(self, b);
790-
}
791-
792-
fn visit_body(&mut self, body: &'tcx hir::Body<'tcx>) {
793-
let body_id = body.id();
794-
let owner_id = self.tcx.hir().body_owner_def_id(body_id);
795-
796-
debug!(
797-
"visit_body(id={:?}, span={:?}, body.id={:?}, cx.parent={:?})",
798-
owner_id,
799-
self.tcx.sess.source_map().span_to_diagnostic_string(body.value.span),
800-
body_id,
801-
self.cx.parent
802-
);
803788

789+
fn enter_body(&mut self, hir_id: hir::HirId, f: impl FnOnce(&mut Self)) {
804790
// Save all state that is specific to the outer function
805791
// body. These will be restored once down below, once we've
806792
// visited the body.
@@ -812,50 +798,73 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
812798
// control flow assumptions. This doesn't apply to nested
813799
// bodies within the `+=` statements. See #69307.
814800
let outer_pessimistic_yield = mem::replace(&mut self.pessimistic_yield, false);
815-
self.terminating_scopes.insert(body.value.hir_id.local_id);
816-
817-
self.enter_scope(Scope { id: body.value.hir_id.local_id, data: ScopeData::CallSite });
818-
self.enter_scope(Scope { id: body.value.hir_id.local_id, data: ScopeData::Arguments });
801+
self.terminating_scopes.insert(hir_id.local_id);
819802

820-
// The arguments and `self` are parented to the fn.
821-
self.cx.var_parent = self.cx.parent.take();
822-
for param in body.params {
823-
self.visit_pat(param.pat);
824-
}
803+
self.enter_scope(Scope { id: hir_id.local_id, data: ScopeData::CallSite });
804+
self.enter_scope(Scope { id: hir_id.local_id, data: ScopeData::Arguments });
825805

826-
// The body of the every fn is a root scope.
827-
self.cx.parent = self.cx.var_parent;
828-
if self.tcx.hir().body_owner_kind(owner_id).is_fn_or_closure() {
829-
self.visit_expr(body.value)
830-
} else {
831-
// Only functions have an outer terminating (drop) scope, while
832-
// temporaries in constant initializers may be 'static, but only
833-
// according to rvalue lifetime semantics, using the same
834-
// syntactical rules used for let initializers.
835-
//
836-
// e.g., in `let x = &f();`, the temporary holding the result from
837-
// the `f()` call lives for the entirety of the surrounding block.
838-
//
839-
// Similarly, `const X: ... = &f();` would have the result of `f()`
840-
// live for `'static`, implying (if Drop restrictions on constants
841-
// ever get lifted) that the value *could* have a destructor, but
842-
// it'd get leaked instead of the destructor running during the
843-
// evaluation of `X` (if at all allowed by CTFE).
844-
//
845-
// However, `const Y: ... = g(&f());`, like `let y = g(&f());`,
846-
// would *not* let the `f()` temporary escape into an outer scope
847-
// (i.e., `'static`), which means that after `g` returns, it drops,
848-
// and all the associated destruction scope rules apply.
849-
self.cx.var_parent = None;
850-
resolve_local(self, None, Some(body.value));
851-
}
806+
f(self);
852807

853808
// Restore context we had at the start.
854809
self.expr_and_pat_count = outer_ec;
855810
self.cx = outer_cx;
856811
self.terminating_scopes = outer_ts;
857812
self.pessimistic_yield = outer_pessimistic_yield;
858813
}
814+
}
815+
816+
impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
817+
fn visit_block(&mut self, b: &'tcx Block<'tcx>) {
818+
resolve_block(self, b);
819+
}
820+
821+
fn visit_body(&mut self, body: &'tcx hir::Body<'tcx>) {
822+
let body_id = body.id();
823+
let owner_id = self.tcx.hir().body_owner_def_id(body_id);
824+
825+
debug!(
826+
"visit_body(id={:?}, span={:?}, body.id={:?}, cx.parent={:?})",
827+
owner_id,
828+
self.tcx.sess.source_map().span_to_diagnostic_string(body.value.span),
829+
body_id,
830+
self.cx.parent
831+
);
832+
833+
self.enter_body(body.value.hir_id, |this| {
834+
if this.tcx.hir().body_owner_kind(owner_id).is_fn_or_closure() {
835+
// The arguments and `self` are parented to the fn.
836+
this.cx.var_parent = this.cx.parent.take();
837+
for param in body.params {
838+
this.visit_pat(param.pat);
839+
}
840+
841+
// The body of the every fn is a root scope.
842+
this.cx.parent = this.cx.var_parent;
843+
this.visit_expr(body.value)
844+
} else {
845+
// Only functions have an outer terminating (drop) scope, while
846+
// temporaries in constant initializers may be 'static, but only
847+
// according to rvalue lifetime semantics, using the same
848+
// syntactical rules used for let initializers.
849+
//
850+
// e.g., in `let x = &f();`, the temporary holding the result from
851+
// the `f()` call lives for the entirety of the surrounding block.
852+
//
853+
// Similarly, `const X: ... = &f();` would have the result of `f()`
854+
// live for `'static`, implying (if Drop restrictions on constants
855+
// ever get lifted) that the value *could* have a destructor, but
856+
// it'd get leaked instead of the destructor running during the
857+
// evaluation of `X` (if at all allowed by CTFE).
858+
//
859+
// However, `const Y: ... = g(&f());`, like `let y = g(&f());`,
860+
// would *not* let the `f()` temporary escape into an outer scope
861+
// (i.e., `'static`), which means that after `g` returns, it drops,
862+
// and all the associated destruction scope rules apply.
863+
this.cx.var_parent = None;
864+
resolve_local(this, None, Some(body.value));
865+
}
866+
})
867+
}
859868

860869
fn visit_arm(&mut self, a: &'tcx Arm<'tcx>) {
861870
resolve_arm(self, a);

compiler/rustc_hir_analysis/src/collect/generics_of.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,10 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
177177
}
178178
}
179179
}
180-
Node::ConstBlock(_)
181-
| Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
182-
Some(tcx.typeck_root_def_id(def_id.to_def_id()))
183-
}
180+
Node::Expr(&hir::Expr {
181+
kind: hir::ExprKind::Closure { .. } | hir::ExprKind::ConstBlock { .. },
182+
..
183+
}) => Some(tcx.typeck_root_def_id(def_id.to_def_id())),
184184
Node::Item(item) => match item.kind {
185185
ItemKind::OpaqueTy(&hir::OpaqueTy {
186186
origin:
@@ -414,7 +414,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
414414
}
415415

416416
// provide junk type parameter defs for const blocks.
417-
if let Node::ConstBlock(_) = node {
417+
if let Node::Expr(Expr { kind: ExprKind::ConstBlock(..), .. }) = node {
418418
own_params.push(ty::GenericParamDef {
419419
index: next_index(),
420420
name: Symbol::intern("<const_ty>"),

compiler/rustc_hir_analysis/src/collect/type_of.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -484,8 +484,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
484484
}
485485

486486
Node::AnonConst(_) => anon_const_type_of(tcx, def_id),
487-
488-
Node::ConstBlock(_) => {
487+
Node::Expr(&Expr { kind: ExprKind::ConstBlock(..), .. }) => {
489488
let args = ty::GenericArgs::identity_for_item(tcx, def_id.to_def_id());
490489
args.as_inline_const().ty()
491490
}

0 commit comments

Comments
 (0)