rustc_mir_build/builder/expr/
as_temp.rs1use rustc_data_structures::stack::ensure_sufficient_stack;
4use rustc_hir::HirId;
5use rustc_middle::middle::region::{Scope, ScopeData, TempLifetime};
6use rustc_middle::mir::*;
7use rustc_middle::thir::*;
8use tracing::{debug, instrument};
9
10use crate::builder::scope::{DropKind, LintLevel};
11use crate::builder::{BlockAnd, BlockAndExtension, Builder};
12
13impl<'a, 'tcx> Builder<'a, 'tcx> {
14 pub(crate) fn as_temp(
17 &mut self,
18 block: BasicBlock,
19 temp_lifetime: TempLifetime,
20 expr_id: ExprId,
21 mutability: Mutability,
22 ) -> BlockAnd<Local> {
23 ensure_sufficient_stack(|| self.as_temp_inner(block, temp_lifetime, expr_id, mutability))
27 }
28
29 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("as_temp_inner",
"rustc_mir_build::builder::expr::as_temp",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/builder/expr/as_temp.rs"),
::tracing_core::__macro_support::Option::Some(29u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::builder::expr::as_temp"),
::tracing_core::field::FieldSet::new(&["block",
"temp_lifetime", "expr_id", "mutability"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&block)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&temp_lifetime)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&expr_id)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&mutability)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: BlockAnd<Local> = loop {};
return __tracing_attr_fake_return;
}
{
let this = self;
let expr = &this.thir[expr_id];
let expr_span = expr.span;
let source_info = this.source_info(expr_span);
if let ExprKind::Scope { region_scope, hir_id, value } = expr.kind
{
return this.in_scope((region_scope, source_info),
LintLevel::Explicit(hir_id),
|this|
this.as_temp(block, temp_lifetime, value, mutability));
}
let expr_ty = expr.ty;
let deduplicate_temps =
this.fixed_temps_scope.is_some() &&
this.fixed_temps_scope == temp_lifetime.temp_lifetime;
let temp =
if deduplicate_temps &&
let Some(temp_index) = this.fixed_temps.get(&expr_id) {
*temp_index
} else {
let mut local_decl = LocalDecl::new(expr_ty, expr_span);
if mutability.is_not() {
local_decl = local_decl.immutable();
}
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_build/src/builder/expr/as_temp.rs:61",
"rustc_mir_build::builder::expr::as_temp",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/builder/expr/as_temp.rs"),
::tracing_core::__macro_support::Option::Some(61u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::builder::expr::as_temp"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("creating temp {0:?} with block_context: {1:?}",
local_decl, this.block_context) as &dyn Value))])
});
} else { ; }
};
let local_info =
match expr.kind {
ExprKind::StaticRef { def_id, .. } => {
if !!this.tcx.is_thread_local_static(def_id) {
::core::panicking::panic("assertion failed: !this.tcx.is_thread_local_static(def_id)")
};
LocalInfo::StaticRef { def_id, is_thread_local: false }
}
ExprKind::ThreadLocalRef(def_id) => {
if !this.tcx.is_thread_local_static(def_id) {
::core::panicking::panic("assertion failed: this.tcx.is_thread_local_static(def_id)")
};
LocalInfo::StaticRef { def_id, is_thread_local: true }
}
ExprKind::NamedConst { def_id, .. } | ExprKind::ConstParam {
def_id, .. } => {
LocalInfo::ConstRef { def_id }
}
_ if
let Some(tail_info) =
this.block_context.currently_in_block_tail() => {
LocalInfo::BlockTailTemp(tail_info)
}
_ if
let Some(Scope { data: ScopeData::IfThenRescope, local_id })
= temp_lifetime.temp_lifetime => {
LocalInfo::IfThenRescopeTemp {
if_then: HirId { owner: this.hir_id.owner, local_id },
}
}
_ => LocalInfo::Boring,
};
**local_decl.local_info.as_mut().unwrap_crate_local() =
local_info;
this.local_decls.push(local_decl)
};
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_build/src/builder/expr/as_temp.rs:93",
"rustc_mir_build::builder::expr::as_temp",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/builder/expr/as_temp.rs"),
::tracing_core::__macro_support::Option::Some(93u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::builder::expr::as_temp"),
::tracing_core::field::FieldSet::new(&["temp"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&temp) as
&dyn Value))])
});
} else { ; }
};
if deduplicate_temps { this.fixed_temps.insert(expr_id, temp); }
let temp_place = Place::from(temp);
match expr.kind {
ExprKind::Break { .. } | ExprKind::Continue { .. } |
ExprKind::Return { .. } => (),
ExprKind::Block { block } if
let Block { expr: None, targeted_by_break: false, .. } =
this.thir[block] && expr_ty.is_never() => {}
_ => {
this.cfg.push(block,
Statement::new(source_info,
StatementKind::StorageLive(temp)));
if let Some(temp_lifetime) = temp_lifetime.temp_lifetime {
this.schedule_drop(expr_span, temp_lifetime, temp,
DropKind::Storage);
}
}
}
block =
this.expr_into_dest(temp_place, block, expr_id).into_block();
if let Some(temp_lifetime) = temp_lifetime.temp_lifetime {
this.schedule_drop(expr_span, temp_lifetime, temp,
DropKind::Value);
}
if let Some(backwards_incompatible) =
temp_lifetime.backwards_incompatible {
this.schedule_backwards_incompatible_drop(expr_span,
backwards_incompatible, temp);
}
block.and(temp)
}
}
}#[instrument(skip(self), level = "debug")]
30 fn as_temp_inner(
31 &mut self,
32 mut block: BasicBlock,
33 temp_lifetime: TempLifetime,
34 expr_id: ExprId,
35 mutability: Mutability,
36 ) -> BlockAnd<Local> {
37 let this = self; let expr = &this.thir[expr_id];
40 let expr_span = expr.span;
41 let source_info = this.source_info(expr_span);
42 if let ExprKind::Scope { region_scope, hir_id, value } = expr.kind {
43 return this.in_scope(
44 (region_scope, source_info),
45 LintLevel::Explicit(hir_id),
46 |this| this.as_temp(block, temp_lifetime, value, mutability),
47 );
48 }
49
50 let expr_ty = expr.ty;
51 let deduplicate_temps = this.fixed_temps_scope.is_some()
52 && this.fixed_temps_scope == temp_lifetime.temp_lifetime;
53 let temp = if deduplicate_temps && let Some(temp_index) = this.fixed_temps.get(&expr_id) {
54 *temp_index
55 } else {
56 let mut local_decl = LocalDecl::new(expr_ty, expr_span);
57 if mutability.is_not() {
58 local_decl = local_decl.immutable();
59 }
60
61 debug!("creating temp {:?} with block_context: {:?}", local_decl, this.block_context);
62 let local_info = match expr.kind {
63 ExprKind::StaticRef { def_id, .. } => {
64 assert!(!this.tcx.is_thread_local_static(def_id));
65 LocalInfo::StaticRef { def_id, is_thread_local: false }
66 }
67 ExprKind::ThreadLocalRef(def_id) => {
68 assert!(this.tcx.is_thread_local_static(def_id));
69 LocalInfo::StaticRef { def_id, is_thread_local: true }
70 }
71 ExprKind::NamedConst { def_id, .. } | ExprKind::ConstParam { def_id, .. } => {
72 LocalInfo::ConstRef { def_id }
73 }
74 _ if let Some(tail_info) = this.block_context.currently_in_block_tail() => {
77 LocalInfo::BlockTailTemp(tail_info)
78 }
79
80 _ if let Some(Scope { data: ScopeData::IfThenRescope, local_id }) =
81 temp_lifetime.temp_lifetime =>
82 {
83 LocalInfo::IfThenRescopeTemp {
84 if_then: HirId { owner: this.hir_id.owner, local_id },
85 }
86 }
87
88 _ => LocalInfo::Boring,
89 };
90 **local_decl.local_info.as_mut().unwrap_crate_local() = local_info;
91 this.local_decls.push(local_decl)
92 };
93 debug!(?temp);
94 if deduplicate_temps {
95 this.fixed_temps.insert(expr_id, temp);
96 }
97 let temp_place = Place::from(temp);
98
99 match expr.kind {
100 ExprKind::Break { .. } | ExprKind::Continue { .. } | ExprKind::Return { .. } => (),
103 ExprKind::Block { block }
104 if let Block { expr: None, targeted_by_break: false, .. } = this.thir[block]
105 && expr_ty.is_never() => {}
106 _ => {
107 this.cfg.push(block, Statement::new(source_info, StatementKind::StorageLive(temp)));
108
109 if let Some(temp_lifetime) = temp_lifetime.temp_lifetime {
123 this.schedule_drop(expr_span, temp_lifetime, temp, DropKind::Storage);
124 }
125 }
126 }
127
128 block = this.expr_into_dest(temp_place, block, expr_id).into_block();
129
130 if let Some(temp_lifetime) = temp_lifetime.temp_lifetime {
131 this.schedule_drop(expr_span, temp_lifetime, temp, DropKind::Value);
132 }
133
134 if let Some(backwards_incompatible) = temp_lifetime.backwards_incompatible {
135 this.schedule_backwards_incompatible_drop(expr_span, backwards_incompatible, temp);
136 }
137
138 block.and(temp)
139 }
140}