rustc_mir_build/builder/expr/
as_temp.rs1use rustc_hir::HirId;
4use rustc_middle::middle::region::{Scope, ScopeData, TempLifetime};
5use rustc_middle::mir::*;
6use rustc_middle::thir::*;
7use tracing::{debug, instrument};
8
9use crate::builder::scope::LintLevel;
10use crate::builder::{BlockAnd, BlockAndExtension, Builder};
11
12impl<'a, 'tcx> Builder<'a, 'tcx> {
13 #[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",
"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(15u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::builder::expr::as_temp"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("block")
}> =
::tracing::__macro_support::FieldName::new("block");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("temp_lifetime")
}> =
::tracing::__macro_support::FieldName::new("temp_lifetime");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("expr_id")
}> =
::tracing::__macro_support::FieldName::new("expr_id");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("mutability")
}> =
::tracing::__macro_support::FieldName::new("mutability");
NAME.as_str()
}], ::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&block)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&temp_lifetime)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&expr_id)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&mutability)
as &dyn ::tracing::field::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:47",
"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(47u32),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("creating temp {0:?} with block_context: {1:?}",
local_decl, this.block_context) as
&dyn ::tracing::field::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:79",
"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(79u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::builder::expr::as_temp"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("temp")
}> =
::tracing::__macro_support::FieldName::new("temp");
NAME.as_str()
}], ::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&temp)
as &dyn ::tracing::field::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_storage(expr_span, temp_lifetime, temp);
}
}
}
block =
this.expr_into_dest(temp_place, block, expr_id).into_block();
if let Some(temp_lifetime) = temp_lifetime.temp_lifetime {
this.schedule_drop_value(expr_span, temp_lifetime, temp);
}
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")]
16 pub(crate) fn as_temp(
17 &mut self,
18 mut block: BasicBlock,
19 temp_lifetime: TempLifetime,
20 expr_id: ExprId,
21 mutability: Mutability,
22 ) -> BlockAnd<Local> {
23 let this = self; let expr = &this.thir[expr_id];
26 let expr_span = expr.span;
27 let source_info = this.source_info(expr_span);
28 if let ExprKind::Scope { region_scope, hir_id, value } = expr.kind {
29 return this.in_scope(
30 (region_scope, source_info),
31 LintLevel::Explicit(hir_id),
32 |this| this.as_temp(block, temp_lifetime, value, mutability),
33 );
34 }
35
36 let expr_ty = expr.ty;
37 let deduplicate_temps = this.fixed_temps_scope.is_some()
38 && this.fixed_temps_scope == temp_lifetime.temp_lifetime;
39 let temp = if deduplicate_temps && let Some(temp_index) = this.fixed_temps.get(&expr_id) {
40 *temp_index
41 } else {
42 let mut local_decl = LocalDecl::new(expr_ty, expr_span);
43 if mutability.is_not() {
44 local_decl = local_decl.immutable();
45 }
46
47 debug!("creating temp {:?} with block_context: {:?}", local_decl, this.block_context);
48 let local_info = match expr.kind {
49 ExprKind::StaticRef { def_id, .. } => {
50 assert!(!this.tcx.is_thread_local_static(def_id));
51 LocalInfo::StaticRef { def_id, is_thread_local: false }
52 }
53 ExprKind::ThreadLocalRef(def_id) => {
54 assert!(this.tcx.is_thread_local_static(def_id));
55 LocalInfo::StaticRef { def_id, is_thread_local: true }
56 }
57 ExprKind::NamedConst { def_id, .. } | ExprKind::ConstParam { def_id, .. } => {
58 LocalInfo::ConstRef { def_id }
59 }
60 _ if let Some(tail_info) = this.block_context.currently_in_block_tail() => {
63 LocalInfo::BlockTailTemp(tail_info)
64 }
65
66 _ if let Some(Scope { data: ScopeData::IfThenRescope, local_id }) =
67 temp_lifetime.temp_lifetime =>
68 {
69 LocalInfo::IfThenRescopeTemp {
70 if_then: HirId { owner: this.hir_id.owner, local_id },
71 }
72 }
73
74 _ => LocalInfo::Boring,
75 };
76 **local_decl.local_info.as_mut().unwrap_crate_local() = local_info;
77 this.local_decls.push(local_decl)
78 };
79 debug!(?temp);
80 if deduplicate_temps {
81 this.fixed_temps.insert(expr_id, temp);
82 }
83 let temp_place = Place::from(temp);
84
85 match expr.kind {
86 ExprKind::Break { .. } | ExprKind::Continue { .. } | ExprKind::Return { .. } => (),
89 ExprKind::Block { block }
90 if let Block { expr: None, targeted_by_break: false, .. } = this.thir[block]
91 && expr_ty.is_never() => {}
92 _ => {
93 this.cfg.push(block, Statement::new(source_info, StatementKind::StorageLive(temp)));
94
95 if let Some(temp_lifetime) = temp_lifetime.temp_lifetime {
109 this.schedule_drop_storage(expr_span, temp_lifetime, temp);
110 }
111 }
112 }
113
114 block = this.expr_into_dest(temp_place, block, expr_id).into_block();
115
116 if let Some(temp_lifetime) = temp_lifetime.temp_lifetime {
117 this.schedule_drop_value(expr_span, temp_lifetime, temp);
118 }
119
120 if let Some(backwards_incompatible) = temp_lifetime.backwards_incompatible {
121 this.schedule_backwards_incompatible_drop(expr_span, backwards_incompatible, temp);
122 }
123
124 block.and(temp)
125 }
126}