Skip to content

Commit eeec347

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 79734f1 + edb59c9 commit eeec347

File tree

38 files changed

+184
-240
lines changed

38 files changed

+184
-240
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 (`[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
@@ -1383,7 +1383,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
13831383
match kind {
13841384
ExprKind::Array(exprs) => visit_thin_exprs(exprs, vis),
13851385
ExprKind::ConstBlock(anon_const) => {
1386-
vis.visit_anon_const(anon_const);
1386+
vis.visit_expr(anon_const);
13871387
}
13881388
ExprKind::Repeat(expr, count) => {
13891389
vis.visit_expr(expr);

compiler/rustc_ast/src/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
925925
ExprKind::Array(subexpressions) => {
926926
walk_list!(visitor, visit_expr, subexpressions);
927927
}
928-
ExprKind::ConstBlock(anon_const) => try_visit!(visitor.visit_anon_const(anon_const)),
928+
ExprKind::ConstBlock(anon_const) => try_visit!(visitor.visit_expr(anon_const)),
929929
ExprKind::Repeat(element, count) => {
930930
try_visit!(visitor.visit_expr(element));
931931
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;
@@ -390,18 +389,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
390389
instance: ty::InstanceDef<'tcx>,
391390
) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> {
392391
match instance {
393-
ty::InstanceDef::Item(def) => {
394-
if ecx.tcx.is_ctfe_mir_available(def) {
395-
Ok(ecx.tcx.mir_for_ctfe(def))
396-
} else if ecx.tcx.def_kind(def) == DefKind::AssocConst {
397-
ecx.tcx.dcx().bug("This is likely a const item that is missing from its impl");
398-
} else {
399-
// `find_mir_or_eval_fn` checks that this is a const fn before even calling us,
400-
// so this should be unreachable.
401-
let path = ecx.tcx.def_path_str(def);
402-
bug!("trying to call extern function `{path}` at compile-time");
403-
}
404-
}
392+
ty::InstanceDef::Item(def) => Ok(ecx.tcx.mir_for_ctfe(def)),
405393
_ => Ok(ecx.tcx.instance_mir(instance)),
406394
}
407395
}

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 body: BodyId,
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.
@@ -3606,7 +3598,6 @@ pub enum Node<'hir> {
36063598
Variant(&'hir Variant<'hir>),
36073599
Field(&'hir FieldDef<'hir>),
36083600
AnonConst(&'hir AnonConst),
3609-
ConstBlock(&'hir ConstBlock),
36103601
Expr(&'hir Expr<'hir>),
36113602
ExprField(&'hir ExprField<'hir>),
36123603
Stmt(&'hir Stmt<'hir>),
@@ -3669,7 +3660,6 @@ impl<'hir> Node<'hir> {
36693660
Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident),
36703661
Node::Param(..)
36713662
| Node::AnonConst(..)
3672-
| Node::ConstBlock(..)
36733663
| Node::Expr(..)
36743664
| Node::Stmt(..)
36753665
| Node::Block(..)
@@ -3767,7 +3757,6 @@ impl<'hir> Node<'hir> {
37673757
}
37683758

37693759
Node::AnonConst(constant) => Some((constant.def_id, constant.body)),
3770-
Node::ConstBlock(constant) => Some((constant.def_id, constant.body)),
37713760

37723761
_ => None,
37733762
}
@@ -3836,7 +3825,6 @@ impl<'hir> Node<'hir> {
38363825
expect_variant, &'hir Variant<'hir>, Node::Variant(n), n;
38373826
expect_field, &'hir FieldDef<'hir>, Node::Field(n), n;
38383827
expect_anon_const, &'hir AnonConst, Node::AnonConst(n), n;
3839-
expect_inline_const, &'hir ConstBlock, Node::ConstBlock(n), n;
38403828
expect_expr, &'hir Expr<'hir>, Node::Expr(n), n;
38413829
expect_expr_field, &'hir ExprField<'hir>, Node::ExprField(n), n;
38423830
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
@@ -406,11 +406,14 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
406406
match expr.kind {
407407
// Manually recurse over closures and inline consts, because they are the only
408408
// case of nested bodies that share the parent environment.
409-
hir::ExprKind::Closure(&hir::Closure { body, .. })
410-
| hir::ExprKind::ConstBlock(hir::ConstBlock { body, .. }) => {
409+
hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
411410
let body = visitor.tcx.hir().body(body);
412411
visitor.visit_body(body);
413412
}
413+
hir::ExprKind::ConstBlock(expr) => visitor.enter_body(expr.hir_id, |this| {
414+
this.cx.var_parent = None;
415+
resolve_local(this, None, Some(expr));
416+
}),
414417
hir::ExprKind::AssignOp(_, left_expr, right_expr) => {
415418
debug!(
416419
"resolve_expr - enabling pessimistic_yield, was previously {}",
@@ -781,25 +784,8 @@ impl<'tcx> RegionResolutionVisitor<'tcx> {
781784
}
782785
self.enter_scope(Scope { id, data: ScopeData::Node });
783786
}
784-
}
785-
786-
impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
787-
fn visit_block(&mut self, b: &'tcx Block<'tcx>) {
788-
resolve_block(self, b);
789-
}
790-
791-
fn visit_body(&mut self, body: &'tcx hir::Body<'tcx>) {
792-
let body_id = body.id();
793-
let owner_id = self.tcx.hir().body_owner_def_id(body_id);
794-
795-
debug!(
796-
"visit_body(id={:?}, span={:?}, body.id={:?}, cx.parent={:?})",
797-
owner_id,
798-
self.tcx.sess.source_map().span_to_diagnostic_string(body.value.span),
799-
body_id,
800-
self.cx.parent
801-
);
802787

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

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

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

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

859868
fn visit_arm(&mut self, a: &'tcx Arm<'tcx>) {
860869
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
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
@@ -487,8 +487,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
487487
}
488488

489489
Node::AnonConst(_) => anon_const_type_of(tcx, def_id),
490-
491-
Node::ConstBlock(_) => {
490+
Node::Expr(&Expr { kind: ExprKind::ConstBlock(..), .. }) => {
492491
let args = ty::GenericArgs::identity_for_item(tcx, def_id.to_def_id());
493492
args.as_inline_const().ty()
494493
}

0 commit comments

Comments
 (0)