Auto merge of #148706 - dianne:slightly-lazier-temporary-scoping, r=cjgillot

compute temporary scopes when building MIR, not THIR

This accomplishes two things:
- Makes the THIR slightly smaller by not attaching a full `TempLifetime` to every expression.
- Reduces the number of traversals of the `ScopeTree` by only calling `ScopeTree::temporary_scope` when building MIR for something that needs to be dropped in a temporary scope.
This commit is contained in:
bors 2025-11-15 04:33:47 +00:00
commit 733108b6d4
20 changed files with 138 additions and 265 deletions

View file

@ -234,6 +234,17 @@ pub struct ScopeTree {
pub backwards_incompatible_scope: UnordMap<hir::ItemLocalId, Scope>,
}
/// Temporary lifetime information for expressions, used when lowering to MIR.
#[derive(Clone, Copy, Debug, HashStable)]
pub struct TempLifetime {
/// The scope in which a temporary should be dropped. If `None`, no drop is scheduled; this is
/// the case for lifetime-extended temporaries extended by a const/static item or const block.
pub temp_lifetime: Option<Scope>,
/// If `Some(lt)`, indicates that the lifetime of this temporary will change to `lt` in a future edition.
/// If `None`, then no changes are expected, or lints are disabled.
pub backwards_incompatible: Option<Scope>,
}
impl ScopeTree {
pub fn record_scope_parent(&mut self, child: Scope, parent: Option<Scope>) {
debug!("{:?}.parent = {:?}", child, parent);
@ -332,16 +343,16 @@ impl ScopeTree {
/// Returns the scope when the temp created by `expr_id` will be cleaned up.
/// It also emits a lint on potential backwards incompatible change to the temporary scope
/// which is *for now* always shortening.
pub fn temporary_scope(&self, expr_id: hir::ItemLocalId) -> (Option<Scope>, Option<Scope>) {
pub fn temporary_scope(&self, expr_id: hir::ItemLocalId) -> TempLifetime {
// Check for a designated extended temporary scope.
if let Some(&s) = self.extended_temp_scopes.get(&expr_id) {
debug!("temporary_scope({expr_id:?}) = {s:?} [custom]");
return (s, None);
return TempLifetime { temp_lifetime: s, backwards_incompatible: None };
}
// Otherwise, locate the innermost terminating scope.
let (scope, backward_incompatible) =
let (scope, backwards_incompatible) =
self.default_temporary_scope(Scope { local_id: expr_id, data: ScopeData::Node });
(Some(scope), backward_incompatible)
TempLifetime { temp_lifetime: Some(scope), backwards_incompatible }
}
}

View file

@ -256,25 +256,15 @@ pub struct Expr<'tcx> {
/// The type of this expression
pub ty: Ty<'tcx>,
/// The lifetime of this expression if it should be spilled into a
/// temporary
pub temp_lifetime: TempLifetime,
/// The id of the HIR expression whose [temporary scope] should be used for this expression.
///
/// [temporary scope]: https://doc.rust-lang.org/reference/destructors.html#temporary-scopes
pub temp_scope_id: hir::ItemLocalId,
/// span of the expression in the source
pub span: Span,
}
/// Temporary lifetime information for THIR expressions
#[derive(Clone, Copy, Debug, HashStable)]
pub struct TempLifetime {
/// Lifetime for temporaries as expected.
/// This should be `None` in a constant context.
pub temp_lifetime: Option<region::Scope>,
/// If `Some(lt)`, indicates that the lifetime of this temporary will change to `lt` in a future edition.
/// If `None`, then no changes are expected, or lints are disabled.
pub backwards_incompatible: Option<region::Scope>,
}
#[derive(Clone, Debug, HashStable)]
pub enum ExprKind<'tcx> {
/// `Scope`s are used to explicitly mark destruction scopes,
@ -1127,7 +1117,7 @@ mod size_asserts {
use super::*;
// tidy-alphabetical-start
static_assert_size!(Block, 48);
static_assert_size!(Expr<'_>, 72);
static_assert_size!(Expr<'_>, 64);
static_assert_size!(ExprKind<'_>, 40);
static_assert_size!(Pat<'_>, 64);
static_assert_size!(PatKind<'_>, 48);

View file

@ -45,7 +45,7 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
expr: &'thir Expr<'tcx>,
) {
use ExprKind::*;
let Expr { kind, ty: _, temp_lifetime: _, span: _ } = expr;
let Expr { kind, ty: _, temp_scope_id: _, span: _ } = expr;
match *kind {
Scope { value, region_scope: _, lint_level: _ } => {
visitor.visit_expr(&visitor.thir()[value])

View file

@ -21,7 +21,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
pub(crate) fn as_constant(&mut self, expr: &Expr<'tcx>) -> ConstOperand<'tcx> {
let this = self;
let tcx = this.tcx;
let Expr { ty, temp_lifetime: _, span, ref kind } = *expr;
let Expr { ty, temp_scope_id: _, span, ref kind } = *expr;
match kind {
ExprKind::Scope { region_scope: _, lint_level: _, value } => {
this.as_constant(&this.thir[*value])
@ -46,7 +46,7 @@ pub(crate) fn as_constant_inner<'tcx>(
push_cuta: impl FnMut(&Box<CanonicalUserType<'tcx>>) -> Option<UserTypeAnnotationIndex>,
tcx: TyCtxt<'tcx>,
) -> ConstOperand<'tcx> {
let Expr { ty, temp_lifetime: _, span, ref kind } = *expr;
let Expr { ty, temp_scope_id: _, span, ref kind } = *expr;
match *kind {
ExprKind::Literal { lit, neg } => {
let const_ = lit_to_mir_constant(tcx, LitToConstInput { lit: lit.node, ty, neg });

View file

@ -1,5 +1,6 @@
//! See docs in build/expr/mod.rs
use rustc_middle::middle::region::TempLifetime;
use rustc_middle::mir::*;
use rustc_middle::thir::*;
use tracing::{debug, instrument};

View file

@ -503,10 +503,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block.and(place_builder)
}
ExprKind::ValueTypeAscription { source, ref user_ty, user_ty_span } => {
let source_expr = &this.thir[source];
let temp = unpack!(
block = this.as_temp(block, source_expr.temp_lifetime, source, mutability)
);
let temp_lifetime =
this.region_scope_tree.temporary_scope(this.thir[source].temp_scope_id);
let temp = unpack!(block = this.as_temp(block, temp_lifetime, source, mutability));
if let Some(user_ty) = user_ty {
let ty_source_info = this.source_info(user_ty_span);
let annotation_index =
@ -539,10 +538,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block.and(place_builder.project(PlaceElem::UnwrapUnsafeBinder(expr.ty)))
}
ExprKind::ValueUnwrapUnsafeBinder { source } => {
let source_expr = &this.thir[source];
let temp = unpack!(
block = this.as_temp(block, source_expr.temp_lifetime, source, mutability)
);
let temp_lifetime =
this.region_scope_tree.temporary_scope(this.thir[source].temp_scope_id);
let temp = unpack!(block = this.as_temp(block, temp_lifetime, source, mutability));
block.and(PlaceBuilder::from(temp).project(PlaceElem::UnwrapUnsafeBinder(expr.ty)))
}
@ -590,8 +588,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
| ExprKind::WrapUnsafeBinder { .. } => {
// these are not places, so we need to make a temporary.
debug_assert!(!matches!(Category::of(&expr.kind), Some(Category::Place)));
let temp =
unpack!(block = this.as_temp(block, expr.temp_lifetime, expr_id, mutability));
let temp_lifetime = this.region_scope_tree.temporary_scope(expr.temp_scope_id);
let temp = unpack!(block = this.as_temp(block, temp_lifetime, expr_id, mutability));
block.and(PlaceBuilder::from(temp))
}
}
@ -637,7 +635,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// Making this a *fresh* temporary means we do not have to worry about
// the index changing later: Nothing will ever change this temporary.
// The "retagging" transformation (for Stacked Borrows) relies on this.
let index_lifetime = self.thir[index].temp_lifetime;
// Using the enclosing temporary scope for the index ensures it will live past where this
// place is used. This lifetime may be larger than strictly necessary but it means we don't
// need to pass a scope for operands to `as_place`.
let index_lifetime = self.region_scope_tree.temporary_scope(self.thir[index].temp_scope_id);
let idx = unpack!(block = self.as_temp(block, index_lifetime, index, Mutability::Not));
block = self.bounds_check(block, &base_place, idx, expr_span, source_info);

View file

@ -4,7 +4,7 @@ use rustc_abi::FieldIdx;
use rustc_hir::lang_items::LangItem;
use rustc_index::{Idx, IndexVec};
use rustc_middle::bug;
use rustc_middle::middle::region;
use rustc_middle::middle::region::{self, TempLifetime};
use rustc_middle::mir::interpret::Scalar;
use rustc_middle::mir::*;
use rustc_middle::thir::*;

View file

@ -2,7 +2,7 @@
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir::HirId;
use rustc_middle::middle::region::{Scope, ScopeData};
use rustc_middle::middle::region::{Scope, ScopeData, TempLifetime};
use rustc_middle::mir::*;
use rustc_middle::thir::*;
use tracing::{debug, instrument};

View file

@ -1,4 +1,4 @@
use rustc_middle::middle::region;
use rustc_middle::middle::region::{self, TempLifetime};
use rustc_middle::mir::*;
use rustc_middle::span_bug;
use rustc_middle::thir::*;

View file

@ -15,7 +15,7 @@ use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir::{BindingMode, ByRef, LangItem, LetStmt, LocalSource, Node, Pinnedness};
use rustc_middle::middle::region;
use rustc_middle::middle::region::{self, TempLifetime};
use rustc_middle::mir::*;
use rustc_middle::thir::{self, *};
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, ValTree, ValTreeKind};

View file

@ -71,7 +71,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
// Finally, wrap this up in the expr's scope.
expr = Expr {
temp_lifetime: expr.temp_lifetime,
temp_scope_id: expr_scope.local_id,
ty: expr.ty,
span: hir_expr.span,
kind: ExprKind::Scope {
@ -93,7 +93,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
adjustment: &Adjustment<'tcx>,
mut span: Span,
) -> Expr<'tcx> {
let Expr { temp_lifetime, .. } = expr;
let Expr { temp_scope_id, .. } = expr;
// Adjust the span from the block, to the last expression of the
// block. This is a better span when returning a mutable reference
@ -152,7 +152,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
Ty::new_fn_def(self.tcx, call_def_id, self.tcx.mk_args(&[expr.ty.into()]));
expr = Expr {
temp_lifetime,
temp_scope_id,
ty: Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased, expr.ty, deref.mutbl),
span,
kind: ExprKind::Borrow {
@ -199,13 +199,13 @@ impl<'tcx> ThirBuildCx<'tcx> {
variant_index: FIRST_VARIANT,
name: FieldIdx::ZERO,
};
let arg = Expr { temp_lifetime, ty: pin_ty, span, kind: pointer_target };
let arg = Expr { temp_scope_id, ty: pin_ty, span, kind: pointer_target };
let arg = self.thir.exprs.push(arg);
// arg = *pointer
let expr = ExprKind::Deref { arg };
let arg = self.thir.exprs.push(Expr {
temp_lifetime,
temp_scope_id,
ty: ptr_target_ty,
span,
kind: expr,
@ -219,7 +219,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
let new_pin_target =
Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased, ptr_target_ty, mutbl);
let expr = self.thir.exprs.push(Expr {
temp_lifetime,
temp_scope_id,
ty: new_pin_target,
span,
kind: ExprKind::Borrow { borrow_kind, arg },
@ -242,7 +242,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
}
};
Expr { temp_lifetime, ty: adjustment.target, span, kind }
Expr { temp_scope_id, ty: adjustment.target, span, kind }
}
/// Lowers a cast expression.
@ -251,7 +251,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
fn mirror_expr_cast(
&mut self,
source: &'tcx hir::Expr<'tcx>,
temp_lifetime: TempLifetime,
temp_scope_id: hir::ItemLocalId,
span: Span,
) -> ExprKind<'tcx> {
let tcx = self.tcx;
@ -309,7 +309,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
);
}
let kind = ExprKind::NonHirLiteral { lit, user_ty: None };
let offset = self.thir.exprs.push(Expr { temp_lifetime, ty: discr_ty, span, kind });
let offset = self.thir.exprs.push(Expr { temp_scope_id, ty: discr_ty, span, kind });
let source = match discr_did {
// in case we are offsetting from a computed discriminant
@ -317,9 +317,9 @@ impl<'tcx> ThirBuildCx<'tcx> {
Some(did) => {
let kind = ExprKind::NamedConst { def_id: did, args, user_ty: None };
let lhs =
self.thir.exprs.push(Expr { temp_lifetime, ty: discr_ty, span, kind });
self.thir.exprs.push(Expr { temp_scope_id, ty: discr_ty, span, kind });
let bin = ExprKind::Binary { op: BinOp::Add, lhs, rhs: offset };
self.thir.exprs.push(Expr { temp_lifetime, ty: discr_ty, span, kind: bin })
self.thir.exprs.push(Expr { temp_scope_id, ty: discr_ty, span, kind: bin })
}
None => offset,
};
@ -336,8 +336,6 @@ impl<'tcx> ThirBuildCx<'tcx> {
fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> {
let tcx = self.tcx;
let expr_ty = self.typeck_results.expr_ty(expr);
let (temp_lifetime, backwards_incompatible) =
self.region_scope_tree.temporary_scope(expr.hir_id.local_id);
let kind = match expr.kind {
// Here comes the interesting stuff:
@ -372,7 +370,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
let arg_tys = args.iter().map(|e| self.typeck_results.expr_ty_adjusted(e));
let tupled_args = Expr {
ty: Ty::new_tup_from_iter(tcx, arg_tys),
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
temp_scope_id: expr.hir_id.local_id,
span: expr.span,
kind: ExprKind::Tuple { fields: self.mirror_exprs(args) },
};
@ -398,7 +396,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
}
let value = &args[0];
return Expr {
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
temp_scope_id: expr.hir_id.local_id,
ty: expr_ty,
span: expr.span,
kind: ExprKind::Box { value: self.mirror_expr(value) },
@ -502,17 +500,15 @@ impl<'tcx> ThirBuildCx<'tcx> {
expr: Some(arg),
safety_mode: BlockSafety::Safe,
});
let (temp_lifetime, backwards_incompatible) =
self.region_scope_tree.temporary_scope(arg_expr.hir_id.local_id);
arg = self.thir.exprs.push(Expr {
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
temp_scope_id: arg_expr.hir_id.local_id,
ty: arg_ty,
span: arg_expr.span,
kind: ExprKind::Block { block },
});
}
let expr = self.thir.exprs.push(Expr {
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
temp_scope_id: expr.hir_id.local_id,
ty,
span: expr.span,
kind: ExprKind::Borrow { borrow_kind: mutbl.to_borrow_kind(), arg },
@ -995,12 +991,10 @@ impl<'tcx> ThirBuildCx<'tcx> {
}
} else {
let block_ty = self.typeck_results.node_type(body.hir_id);
let (temp_lifetime, backwards_incompatible) =
self.region_scope_tree.temporary_scope(body.hir_id.local_id);
let block = self.mirror_block(body);
let body = self.thir.exprs.push(Expr {
ty: block_ty,
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
temp_scope_id: body.hir_id.local_id,
span: self.thir[block].span,
kind: ExprKind::Block { block },
});
@ -1022,17 +1016,13 @@ impl<'tcx> ThirBuildCx<'tcx> {
expr, cast_ty.hir_id, user_ty,
);
let cast = self.mirror_expr_cast(
source,
TempLifetime { temp_lifetime, backwards_incompatible },
expr.span,
);
let cast = self.mirror_expr_cast(source, expr.hir_id.local_id, expr.span);
if let Some(user_ty) = user_ty {
// NOTE: Creating a new Expr and wrapping a Cast inside of it may be
// inefficient, revisit this when performance becomes an issue.
let cast_expr = self.thir.exprs.push(Expr {
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
temp_scope_id: expr.hir_id.local_id,
ty: expr_ty,
span: expr.span,
kind: cast,
@ -1091,12 +1081,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
hir::ExprKind::Err(_) => unreachable!("cannot lower a `hir::ExprKind::Err` to THIR"),
};
Expr {
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
ty: expr_ty,
span: expr.span,
kind,
}
Expr { temp_scope_id: expr.hir_id.local_id, ty: expr_ty, span: expr.span, kind }
}
fn user_args_applied_to_res(
@ -1140,8 +1125,6 @@ impl<'tcx> ThirBuildCx<'tcx> {
span: Span,
overloaded_callee: Option<Ty<'tcx>>,
) -> Expr<'tcx> {
let (temp_lifetime, backwards_incompatible) =
self.region_scope_tree.temporary_scope(expr.hir_id.local_id);
let (ty, user_ty) = match overloaded_callee {
Some(fn_def) => (fn_def, None),
None => {
@ -1158,7 +1141,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
}
};
Expr {
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
temp_scope_id: expr.hir_id.local_id,
ty,
span,
kind: ExprKind::ZstLiteral { user_ty },
@ -1235,8 +1218,6 @@ impl<'tcx> ThirBuildCx<'tcx> {
Res::Def(DefKind::Static { .. }, id) => {
// this is &raw for extern static or static mut, and & for other statics
let ty = self.tcx.static_ptr_ty(id, self.typing_env);
let (temp_lifetime, backwards_incompatible) =
self.region_scope_tree.temporary_scope(expr.hir_id.local_id);
let kind = if self.tcx.is_thread_local_static(id) {
ExprKind::ThreadLocalRef(id)
} else {
@ -1246,7 +1227,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
ExprKind::Deref {
arg: self.thir.exprs.push(Expr {
ty,
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
temp_scope_id: expr.hir_id.local_id,
span: expr.span,
kind,
}),
@ -1317,13 +1298,11 @@ impl<'tcx> ThirBuildCx<'tcx> {
// construct the complete expression `foo()` for the overloaded call,
// which will yield the &T type
let (temp_lifetime, backwards_incompatible) =
self.region_scope_tree.temporary_scope(expr.hir_id.local_id);
let fun = self.method_callee(expr, span, overloaded_callee);
let fun = self.thir.exprs.push(fun);
let fun_ty = self.thir[fun].ty;
let ref_expr = self.thir.exprs.push(Expr {
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
temp_scope_id: expr.hir_id.local_id,
ty: ref_ty,
span,
kind: ExprKind::Call { ty: fun_ty, fun, args, from_hir_call: false, fn_span: span },
@ -1338,8 +1317,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
closure_expr: &'tcx hir::Expr<'tcx>,
place: HirPlace<'tcx>,
) -> Expr<'tcx> {
let (temp_lifetime, backwards_incompatible) =
self.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id);
let temp_scope_id = closure_expr.hir_id.local_id;
let var_ty = place.base_ty;
// The result of capture analysis in `rustc_hir_typeck/src/upvar.rs` represents a captured path
@ -1353,7 +1331,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
};
let mut captured_place_expr = Expr {
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
temp_scope_id,
ty: var_ty,
span: closure_expr.span,
kind: self.convert_var(var_hir_id),
@ -1381,12 +1359,8 @@ impl<'tcx> ThirBuildCx<'tcx> {
}
};
captured_place_expr = Expr {
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
ty: proj.ty,
span: closure_expr.span,
kind,
};
captured_place_expr =
Expr { temp_scope_id, ty: proj.ty, span: closure_expr.span, kind };
}
captured_place_expr
@ -1401,8 +1375,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
let upvar_capture = captured_place.info.capture_kind;
let captured_place_expr =
self.convert_captured_hir_place(closure_expr, captured_place.place.clone());
let (temp_lifetime, backwards_incompatible) =
self.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id);
let temp_scope_id = closure_expr.hir_id.local_id;
match upvar_capture {
ty::UpvarCapture::ByValue => captured_place_expr,
@ -1411,7 +1384,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
let expr_id = self.thir.exprs.push(captured_place_expr);
Expr {
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
temp_scope_id,
ty: upvar_ty,
span: closure_expr.span,
kind: ExprKind::ByUse { expr: expr_id, span },
@ -1428,7 +1401,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
}
};
Expr {
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
temp_scope_id,
ty: upvar_ty,
span: closure_expr.span,
kind: ExprKind::Borrow {

View file

@ -10,7 +10,6 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::lang_items::LangItem;
use rustc_hir::{self as hir, HirId, find_attr};
use rustc_middle::bug;
use rustc_middle::middle::region;
use rustc_middle::thir::*;
use rustc_middle::ty::{self, TyCtxt};
use tracing::instrument;
@ -60,7 +59,6 @@ struct ThirBuildCx<'tcx> {
typing_env: ty::TypingEnv<'tcx>,
region_scope_tree: &'tcx region::ScopeTree,
typeck_results: &'tcx ty::TypeckResults<'tcx>,
/// False to indicate that adjustments should not be applied. Only used for `custom_mir`
@ -106,7 +104,6 @@ impl<'tcx> ThirBuildCx<'tcx> {
// FIXME(#132279): We're in a body, we should use a typing
// mode which reveals the opaque types defined by that body.
typing_env: ty::TypingEnv::non_body_analysis(tcx, def),
region_scope_tree: tcx.region_scope_tree(def),
typeck_results,
body_owner: def.to_def_id(),
apply_adjustments:

View file

@ -183,10 +183,10 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
}
fn print_expr(&mut self, expr: ExprId, depth_lvl: usize) {
let Expr { ty, temp_lifetime, span, kind } = &self.thir[expr];
let Expr { ty, temp_scope_id, span, kind } = &self.thir[expr];
print_indented!(self, "Expr {", depth_lvl);
print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 1);
print_indented!(self, format!("temp_lifetime: {:?}", temp_lifetime), depth_lvl + 1);
print_indented!(self, format!("temp_scope_id: {:?}", temp_scope_id), depth_lvl + 1);
print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
print_indented!(self, "kind: ", depth_lvl + 1);
self.print_expr_kind(kind, depth_lvl + 2);

View file

@ -34,7 +34,7 @@ params: [
body:
Expr {
ty: ()
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(6)), backwards_incompatible: None }
temp_scope_id: 6
span: $DIR/c-variadic.rs:7:39: 7:41 (#0)
kind:
Scope {
@ -43,7 +43,7 @@ body:
value:
Expr {
ty: ()
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(6)), backwards_incompatible: None }
temp_scope_id: 6
span: $DIR/c-variadic.rs:7:39: 7:41 (#0)
kind:
Block {

View file

@ -11,12 +11,7 @@ Thir {
fields: [],
},
ty: (),
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(3),
),
backwards_incompatible: None,
},
temp_scope_id: 7,
span: $DIR/thir-flat-const-variant.rs:12:32: 12:34 (#0),
},
Expr {
@ -28,12 +23,7 @@ Thir {
value: e0,
},
ty: (),
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(3),
),
backwards_incompatible: None,
},
temp_scope_id: 7,
span: $DIR/thir-flat-const-variant.rs:12:32: 12:34 (#0),
},
Expr {
@ -53,12 +43,7 @@ Thir {
},
),
ty: Foo,
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(3),
),
backwards_incompatible: None,
},
temp_scope_id: 3,
span: $DIR/thir-flat-const-variant.rs:12:23: 12:35 (#0),
},
Expr {
@ -70,12 +55,7 @@ Thir {
value: e2,
},
ty: Foo,
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(3),
),
backwards_incompatible: None,
},
temp_scope_id: 3,
span: $DIR/thir-flat-const-variant.rs:12:23: 12:35 (#0),
},
],
@ -96,12 +76,7 @@ Thir {
fields: [],
},
ty: (),
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(3),
),
backwards_incompatible: None,
},
temp_scope_id: 8,
span: $DIR/thir-flat-const-variant.rs:13:33: 13:35 (#0),
},
Expr {
@ -113,12 +88,7 @@ Thir {
value: e0,
},
ty: (),
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(3),
),
backwards_incompatible: None,
},
temp_scope_id: 8,
span: $DIR/thir-flat-const-variant.rs:13:33: 13:35 (#0),
},
Expr {
@ -138,12 +108,7 @@ Thir {
},
),
ty: Foo,
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(3),
),
backwards_incompatible: None,
},
temp_scope_id: 3,
span: $DIR/thir-flat-const-variant.rs:13:23: 13:36 (#0),
},
Expr {
@ -155,12 +120,7 @@ Thir {
value: e2,
},
ty: Foo,
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(3),
),
backwards_incompatible: None,
},
temp_scope_id: 3,
span: $DIR/thir-flat-const-variant.rs:13:23: 13:36 (#0),
},
],
@ -181,12 +141,7 @@ Thir {
fields: [],
},
ty: (),
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(3),
),
backwards_incompatible: None,
},
temp_scope_id: 7,
span: $DIR/thir-flat-const-variant.rs:14:33: 14:35 (#0),
},
Expr {
@ -198,12 +153,7 @@ Thir {
value: e0,
},
ty: (),
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(3),
),
backwards_incompatible: None,
},
temp_scope_id: 7,
span: $DIR/thir-flat-const-variant.rs:14:33: 14:35 (#0),
},
Expr {
@ -223,12 +173,7 @@ Thir {
},
),
ty: Foo,
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(3),
),
backwards_incompatible: None,
},
temp_scope_id: 3,
span: $DIR/thir-flat-const-variant.rs:14:24: 14:36 (#0),
},
Expr {
@ -240,12 +185,7 @@ Thir {
value: e2,
},
ty: Foo,
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(3),
),
backwards_incompatible: None,
},
temp_scope_id: 3,
span: $DIR/thir-flat-const-variant.rs:14:24: 14:36 (#0),
},
],
@ -266,12 +206,7 @@ Thir {
fields: [],
},
ty: (),
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(3),
),
backwards_incompatible: None,
},
temp_scope_id: 8,
span: $DIR/thir-flat-const-variant.rs:15:34: 15:36 (#0),
},
Expr {
@ -283,12 +218,7 @@ Thir {
value: e0,
},
ty: (),
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(3),
),
backwards_incompatible: None,
},
temp_scope_id: 8,
span: $DIR/thir-flat-const-variant.rs:15:34: 15:36 (#0),
},
Expr {
@ -308,12 +238,7 @@ Thir {
},
),
ty: Foo,
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(3),
),
backwards_incompatible: None,
},
temp_scope_id: 3,
span: $DIR/thir-flat-const-variant.rs:15:24: 15:37 (#0),
},
Expr {
@ -325,12 +250,7 @@ Thir {
value: e2,
},
ty: Foo,
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(3),
),
backwards_incompatible: None,
},
temp_scope_id: 3,
span: $DIR/thir-flat-const-variant.rs:15:24: 15:37 (#0),
},
],
@ -360,12 +280,7 @@ Thir {
block: b0,
},
ty: (),
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(2),
),
backwards_incompatible: None,
},
temp_scope_id: 2,
span: $DIR/thir-flat-const-variant.rs:18:11: 18:13 (#0),
},
Expr {
@ -377,12 +292,7 @@ Thir {
value: e0,
},
ty: (),
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(2),
),
backwards_incompatible: None,
},
temp_scope_id: 2,
span: $DIR/thir-flat-const-variant.rs:18:11: 18:13 (#0),
},
],

View file

@ -20,12 +20,7 @@ Thir {
block: b0,
},
ty: (),
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(2),
),
backwards_incompatible: None,
},
temp_scope_id: 2,
span: $DIR/thir-flat.rs:4:15: 4:17 (#0),
},
Expr {
@ -37,12 +32,7 @@ Thir {
value: e0,
},
ty: (),
temp_lifetime: TempLifetime {
temp_lifetime: Some(
Node(2),
),
backwards_incompatible: None,
},
temp_scope_id: 2,
span: $DIR/thir-flat.rs:4:15: 4:17 (#0),
},
],

View file

@ -27,7 +27,7 @@ params: [
body:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None }
temp_scope_id: 28
span: $DIR/thir-tree-loop-match.rs:7:37: 20:2 (#0)
kind:
Scope {
@ -36,7 +36,7 @@ body:
value:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None }
temp_scope_id: 28
span: $DIR/thir-tree-loop-match.rs:7:37: 20:2 (#0)
kind:
Block {
@ -48,7 +48,7 @@ body:
expr:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None }
temp_scope_id: 4
span: $DIR/thir-tree-loop-match.rs:9:5: 19:6 (#0)
kind:
Scope {
@ -57,21 +57,21 @@ body:
value:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None }
temp_scope_id: 4
span: $DIR/thir-tree-loop-match.rs:9:5: 19:6 (#0)
kind:
NeverToAny {
source:
Expr {
ty: !
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None }
temp_scope_id: 4
span: $DIR/thir-tree-loop-match.rs:9:5: 19:6 (#0)
kind:
LoopMatch {
state:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(5)), backwards_incompatible: None }
temp_scope_id: 7
span: $DIR/thir-tree-loop-match.rs:10:9: 10:14 (#0)
kind:
Scope {
@ -80,7 +80,7 @@ body:
value:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(5)), backwards_incompatible: None }
temp_scope_id: 7
span: $DIR/thir-tree-loop-match.rs:10:9: 10:14 (#0)
kind:
VarRef {
@ -96,7 +96,7 @@ body:
scrutinee:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(5)), backwards_incompatible: None }
temp_scope_id: 12
span: $DIR/thir-tree-loop-match.rs:11:19: 11:24 (#0)
kind:
Scope {
@ -105,7 +105,7 @@ body:
value:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(5)), backwards_incompatible: None }
temp_scope_id: 12
span: $DIR/thir-tree-loop-match.rs:11:19: 11:24 (#0)
kind:
VarRef {
@ -130,7 +130,7 @@ body:
body:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(16)), backwards_incompatible: None }
temp_scope_id: 17
span: $DIR/thir-tree-loop-match.rs:12:25: 15:18 (#0)
kind:
Scope {
@ -139,14 +139,14 @@ body:
value:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(16)), backwards_incompatible: None }
temp_scope_id: 17
span: $DIR/thir-tree-loop-match.rs:12:25: 15:18 (#0)
kind:
NeverToAny {
source:
Expr {
ty: !
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(16)), backwards_incompatible: None }
temp_scope_id: 17
span: $DIR/thir-tree-loop-match.rs:12:25: 15:18 (#0)
kind:
Block {
@ -161,7 +161,7 @@ body:
expr:
Expr {
ty: !
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(21)), backwards_incompatible: None }
temp_scope_id: 19
span: $DIR/thir-tree-loop-match.rs:14:21: 14:37 (#0)
kind:
Scope {
@ -170,7 +170,7 @@ body:
value:
Expr {
ty: !
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(21)), backwards_incompatible: None }
temp_scope_id: 19
span: $DIR/thir-tree-loop-match.rs:14:21: 14:37 (#0)
kind:
ConstContinue (
@ -178,7 +178,7 @@ body:
value:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(21)), backwards_incompatible: None }
temp_scope_id: 20
span: $DIR/thir-tree-loop-match.rs:14:32: 14:37 (#0)
kind:
Scope {
@ -187,7 +187,7 @@ body:
value:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(21)), backwards_incompatible: None }
temp_scope_id: 20
span: $DIR/thir-tree-loop-match.rs:14:32: 14:37 (#0)
kind:
Literal( lit: Spanned { node: Bool(false), span: $DIR/thir-tree-loop-match.rs:14:32: 14:37 (#0) }, neg: false)
@ -228,7 +228,7 @@ body:
body:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(24)), backwards_incompatible: None }
temp_scope_id: 25
span: $DIR/thir-tree-loop-match.rs:16:26: 16:38 (#0)
kind:
Scope {
@ -237,21 +237,21 @@ body:
value:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(24)), backwards_incompatible: None }
temp_scope_id: 25
span: $DIR/thir-tree-loop-match.rs:16:26: 16:38 (#0)
kind:
NeverToAny {
source:
Expr {
ty: !
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(24)), backwards_incompatible: None }
temp_scope_id: 25
span: $DIR/thir-tree-loop-match.rs:16:26: 16:38 (#0)
kind:
Return {
value:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(24)), backwards_incompatible: None }
temp_scope_id: 26
span: $DIR/thir-tree-loop-match.rs:16:33: 16:38 (#0)
kind:
Scope {
@ -260,7 +260,7 @@ body:
value:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(24)), backwards_incompatible: None }
temp_scope_id: 26
span: $DIR/thir-tree-loop-match.rs:16:33: 16:38 (#0)
kind:
VarRef {
@ -299,7 +299,7 @@ params: [
body:
Expr {
ty: ()
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(2)), backwards_incompatible: None }
temp_scope_id: 2
span: $DIR/thir-tree-loop-match.rs:22:11: 22:13 (#0)
kind:
Scope {
@ -308,7 +308,7 @@ body:
value:
Expr {
ty: ()
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(2)), backwards_incompatible: None }
temp_scope_id: 2
span: $DIR/thir-tree-loop-match.rs:22:11: 22:13 (#0)
kind:
Block {

View file

@ -27,7 +27,7 @@ params: [
body:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None }
temp_scope_id: 28
span: $DIR/thir-tree-match.rs:15:32: 21:2 (#0)
kind:
Scope {
@ -36,7 +36,7 @@ body:
value:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None }
temp_scope_id: 28
span: $DIR/thir-tree-match.rs:15:32: 21:2 (#0)
kind:
Block {
@ -48,7 +48,7 @@ body:
expr:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None }
temp_scope_id: 4
span: $DIR/thir-tree-match.rs:16:5: 20:6 (#0)
kind:
Scope {
@ -57,14 +57,14 @@ body:
value:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None }
temp_scope_id: 4
span: $DIR/thir-tree-match.rs:16:5: 20:6 (#0)
kind:
Match {
scrutinee:
Expr {
ty: Foo
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None }
temp_scope_id: 5
span: $DIR/thir-tree-match.rs:16:11: 16:14 (#0)
kind:
Scope {
@ -73,7 +73,7 @@ body:
value:
Expr {
ty: Foo
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None }
temp_scope_id: 5
span: $DIR/thir-tree-match.rs:16:11: 16:14 (#0)
kind:
VarRef {
@ -124,7 +124,7 @@ body:
body:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(14)), backwards_incompatible: None }
temp_scope_id: 15
span: $DIR/thir-tree-match.rs:17:36: 17:40 (#0)
kind:
Scope {
@ -133,7 +133,7 @@ body:
value:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(14)), backwards_incompatible: None }
temp_scope_id: 15
span: $DIR/thir-tree-match.rs:17:36: 17:40 (#0)
kind:
Literal( lit: Spanned { node: Bool(true), span: $DIR/thir-tree-match.rs:17:36: 17:40 (#0) }, neg: false)
@ -176,7 +176,7 @@ body:
body:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(20)), backwards_incompatible: None }
temp_scope_id: 21
span: $DIR/thir-tree-match.rs:18:27: 18:32 (#0)
kind:
Scope {
@ -185,7 +185,7 @@ body:
value:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(20)), backwards_incompatible: None }
temp_scope_id: 21
span: $DIR/thir-tree-match.rs:18:27: 18:32 (#0)
kind:
Literal( lit: Spanned { node: Bool(false), span: $DIR/thir-tree-match.rs:18:27: 18:32 (#0) }, neg: false)
@ -220,7 +220,7 @@ body:
body:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(26)), backwards_incompatible: None }
temp_scope_id: 27
span: $DIR/thir-tree-match.rs:19:24: 19:28 (#0)
kind:
Scope {
@ -229,7 +229,7 @@ body:
value:
Expr {
ty: bool
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(26)), backwards_incompatible: None }
temp_scope_id: 27
span: $DIR/thir-tree-match.rs:19:24: 19:28 (#0)
kind:
Literal( lit: Spanned { node: Bool(true), span: $DIR/thir-tree-match.rs:19:24: 19:28 (#0) }, neg: false)
@ -258,7 +258,7 @@ params: [
body:
Expr {
ty: ()
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(2)), backwards_incompatible: None }
temp_scope_id: 2
span: $DIR/thir-tree-match.rs:23:11: 23:13 (#0)
kind:
Scope {
@ -267,7 +267,7 @@ body:
value:
Expr {
ty: ()
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(2)), backwards_incompatible: None }
temp_scope_id: 2
span: $DIR/thir-tree-match.rs:23:11: 23:13 (#0)
kind:
Block {

View file

@ -4,7 +4,7 @@ params: [
body:
Expr {
ty: ()
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(2)), backwards_incompatible: None }
temp_scope_id: 2
span: $DIR/thir-tree.rs:4:15: 4:17 (#0)
kind:
Scope {
@ -13,7 +13,7 @@ body:
value:
Expr {
ty: ()
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(2)), backwards_incompatible: None }
temp_scope_id: 2
span: $DIR/thir-tree.rs:4:15: 4:17 (#0)
kind:
Block {

View file

@ -4,7 +4,7 @@ params: [
body:
Expr {
ty: ()
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(11)), backwards_incompatible: None }
temp_scope_id: 11
span: $DIR/box.rs:6:11: 8:2 (#0)
kind:
Scope {
@ -13,7 +13,7 @@ body:
value:
Expr {
ty: ()
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(11)), backwards_incompatible: None }
temp_scope_id: 11
span: $DIR/box.rs:6:11: 8:2 (#0)
kind:
Block {
@ -38,7 +38,7 @@ body:
initializer: Some(
Expr {
ty: std::boxed::Box<i32, std::alloc::Global>
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(2)), backwards_incompatible: None }
temp_scope_id: 3
span: $DIR/box.rs:7:13: 7:35 (#0)
kind:
Scope {
@ -47,13 +47,13 @@ body:
value:
Expr {
ty: std::boxed::Box<i32, std::alloc::Global>
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(2)), backwards_incompatible: None }
temp_scope_id: 3
span: $DIR/box.rs:7:13: 7:35 (#0)
kind:
Box {
Expr {
ty: i32
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(2)), backwards_incompatible: None }
temp_scope_id: 8
span: $DIR/box.rs:7:33: 7:34 (#0)
kind:
Scope {
@ -62,7 +62,7 @@ body:
value:
Expr {
ty: i32
temp_lifetime: TempLifetime { temp_lifetime: Some(Node(2)), backwards_incompatible: None }
temp_scope_id: 8
span: $DIR/box.rs:7:33: 7:34 (#0)
kind:
Literal( lit: Spanned { node: Int(Pu128(1), Unsuffixed), span: $DIR/box.rs:7:33: 7:34 (#0) }, neg: false)