1use itertools::Itertools;
2use rustc_abi::{FIRST_VARIANT, FieldIdx, Size, VariantIdx};
3use rustc_ast::UnsafeBinderCastKind;
4use rustc_data_structures::stack::ensure_sufficient_stack;
5use rustc_data_structures::thin_vec::ThinVec;
6use rustc_hir as hir;
7use rustc_hir::attrs::{AttributeKind, HasAttrs};
8use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
9use rustc_hir::{HirId, LangItem, find_attr};
10use rustc_index::Idx;
11use rustc_middle::hir::place::{
12 Place as HirPlace, PlaceBase as HirPlaceBase, ProjectionKind as HirProjectionKind,
13};
14use rustc_middle::middle::region;
15use rustc_middle::mir::{self, AssignOp, BinOp, BorrowKind, UnOp};
16use rustc_middle::thir::*;
17use rustc_middle::ty::adjustment::{
18 Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, DerefAdjustKind, PointerCoercion,
19};
20use rustc_middle::ty::{
21 self, AdtKind, GenericArgs, InlineConstArgs, InlineConstArgsParts, ScalarInt, Ty, TyCtxt,
22 UpvarArgs,
23};
24use rustc_middle::{bug, span_bug};
25use rustc_span::Span;
26use tracing::{debug, info, instrument, trace};
27
28use crate::diagnostics::*;
29use crate::thir::cx::ThirBuildCx;
30
31fn parsed_attrs(id: HirId, tcx: TyCtxt<'_>) -> ThinVec<AttributeKind> {
32 HasAttrs::get_attrs(id, &tcx)
33 .into_iter()
34 .filter_map(|attr| match attr {
35 hir::Attribute::Parsed(attrkind) => Some(attrkind.clone()),
36 hir::Attribute::Unparsed(_) => None,
37 })
38 .collect()
39}
40
41impl<'tcx> ThirBuildCx<'tcx> {
42 pub(crate) fn mirror_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> ExprId {
51 ensure_sufficient_stack(|| self.mirror_expr_inner(expr))
53 }
54
55 pub(crate) fn mirror_exprs(&mut self, exprs: &'tcx [hir::Expr<'tcx>]) -> Box<[ExprId]> {
56 ensure_sufficient_stack(|| exprs.iter().map(|expr| self.mirror_expr_inner(expr)).collect())
60 }
61
62 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::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("mirror_expr_inner",
"rustc_mir_build::thir::cx::expr", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
::tracing_core::__macro_support::Option::Some(62u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
::tracing_core::field::FieldSet::new(&[],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::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,
&{ meta.fields().value_set(&[]) })
} 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: ExprId = loop {};
return __tracing_attr_fake_return;
}
{
let expr_scope =
region::Scope {
local_id: hir_expr.hir_id.local_id,
data: region::ScopeData::Node,
};
{
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/thir/cx/expr.rs:67",
"rustc_mir_build::thir::cx::expr", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
::tracing_core::__macro_support::Option::Some(67u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
::tracing_core::field::FieldSet::new(&["hir_expr.hir_id",
"hir_expr.span"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::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(&hir_expr.hir_id)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&hir_expr.span)
as &dyn Value))])
});
} else { ; }
};
let mut expr = self.make_mirror_unadjusted(hir_expr);
{
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/thir/cx/expr.rs:71",
"rustc_mir_build::thir::cx::expr", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
::tracing_core::__macro_support::Option::Some(71u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
::tracing_core::field::FieldSet::new(&["expr.ty"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::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(&expr.ty) as
&dyn Value))])
});
} else { ; }
};
let mut attrs = ThinVec::new();
if let ExprKind::Loop { .. } = expr.kind {
if let hir::Node::Block(_) =
self.tcx.parent_hir_node(hir_expr.hir_id) {
attrs = parsed_attrs(hir_expr.hir_id, self.tcx);
}
if let hir::Node::Arm(arm) =
self.tcx.parent_hir_node(hir_expr.hir_id) &&
let hir::Node::Expr(expr) =
self.tcx.parent_hir_node(arm.hir_id) &&
let hir::Node::Expr(expr) =
self.tcx.parent_hir_node(expr.hir_id) {
attrs = parsed_attrs(expr.hir_id, self.tcx);
}
}
if self.apply_adjustments {
for adjustment in
self.typeck_results.expr_adjustments(hir_expr) {
{
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/thir/cx/expr.rs:93",
"rustc_mir_build::thir::cx::expr", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
::tracing_core::__macro_support::Option::Some(93u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
::tracing_core::field::FieldSet::new(&["expr",
"adjustment"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::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(&expr) as
&dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&adjustment)
as &dyn Value))])
});
} else { ; }
};
let span = expr.span;
expr =
self.apply_adjustment(hir_expr, expr, adjustment, span);
}
}
{
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/thir/cx/expr.rs:99",
"rustc_mir_build::thir::cx::expr", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
::tracing_core::__macro_support::Option::Some(99u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
::tracing_core::field::FieldSet::new(&["message",
"expr.ty"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::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!("after adjustments")
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&expr.ty) as
&dyn Value))])
});
} else { ; }
};
let ty = expr.ty;
let value = self.thir.exprs.push(expr);
if !attrs.is_empty() {
self.thir.attributes.insert(value, attrs);
}
expr =
Expr {
temp_scope_id: expr_scope.local_id,
ty,
span: hir_expr.span,
kind: ExprKind::Scope {
region_scope: expr_scope,
value,
hir_id: hir_expr.hir_id,
},
};
self.thir.exprs.push(expr)
}
}
}#[instrument(level = "trace", skip(self, hir_expr))]
63 pub(super) fn mirror_expr_inner(&mut self, hir_expr: &'tcx hir::Expr<'tcx>) -> ExprId {
64 let expr_scope =
65 region::Scope { local_id: hir_expr.hir_id.local_id, data: region::ScopeData::Node };
66
67 trace!(?hir_expr.hir_id, ?hir_expr.span);
68
69 let mut expr = self.make_mirror_unadjusted(hir_expr);
70
71 trace!(?expr.ty);
72
73 let mut attrs = ThinVec::new();
74
75 if let ExprKind::Loop { .. } = expr.kind {
76 if let hir::Node::Block(_) = self.tcx.parent_hir_node(hir_expr.hir_id) {
78 attrs = parsed_attrs(hir_expr.hir_id, self.tcx);
79 }
80
81 if let hir::Node::Arm(arm) = self.tcx.parent_hir_node(hir_expr.hir_id)
83 && let hir::Node::Expr(expr) = self.tcx.parent_hir_node(arm.hir_id)
84 && let hir::Node::Expr(expr) = self.tcx.parent_hir_node(expr.hir_id)
85 {
86 attrs = parsed_attrs(expr.hir_id, self.tcx);
87 }
88 }
89
90 if self.apply_adjustments {
92 for adjustment in self.typeck_results.expr_adjustments(hir_expr) {
93 trace!(?expr, ?adjustment);
94 let span = expr.span;
95 expr = self.apply_adjustment(hir_expr, expr, adjustment, span);
96 }
97 }
98
99 trace!(?expr.ty, "after adjustments");
100
101 let ty = expr.ty;
102 let value = self.thir.exprs.push(expr);
103
104 if !attrs.is_empty() {
105 self.thir.attributes.insert(value, attrs);
106 }
107
108 expr = Expr {
110 temp_scope_id: expr_scope.local_id,
111 ty,
112 span: hir_expr.span,
113 kind: ExprKind::Scope { region_scope: expr_scope, value, hir_id: hir_expr.hir_id },
114 };
115
116 self.thir.exprs.push(expr)
118 }
119
120 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::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("apply_adjustment",
"rustc_mir_build::thir::cx::expr", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
::tracing_core::__macro_support::Option::Some(120u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
::tracing_core::field::FieldSet::new(&["hir_expr",
"adjustment"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::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(&hir_expr)
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(&adjustment)
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: Expr<'tcx> = loop {};
return __tracing_attr_fake_return;
}
{
let Expr { temp_scope_id, .. } = expr;
let mut adjust_span =
|expr: &mut Expr<'tcx>|
{
if let ExprKind::Block { block } = expr.kind &&
let Some(last_expr) = self.thir[block].expr {
span = self.thir[last_expr].span;
expr.span = span;
}
};
let kind =
match adjustment.kind {
Adjust::Pointer(cast) => {
if cast == PointerCoercion::Unsize {
adjust_span(&mut expr);
}
let is_from_as_cast =
if let hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Cast(..), span: cast_span, .. }) =
self.tcx.parent_hir_node(hir_expr.hir_id) {
span = *cast_span;
true
} else { false };
ExprKind::PointerCoercion {
cast,
source: self.thir.exprs.push(expr),
is_from_as_cast,
}
}
Adjust::NeverToAny if adjustment.target.is_never() =>
return expr,
Adjust::NeverToAny =>
ExprKind::NeverToAny { source: self.thir.exprs.push(expr) },
Adjust::Deref(DerefAdjustKind::Builtin) => {
adjust_span(&mut expr);
ExprKind::Deref { arg: self.thir.exprs.push(expr) }
}
Adjust::Deref(DerefAdjustKind::Pin) => {
adjust_span(&mut expr);
let pin_ty =
expr.ty.pinned_ty().expect("Deref(Pin) with non-Pin type");
let pointer_target =
ExprKind::Field {
lhs: self.thir.exprs.push(expr),
variant_index: FIRST_VARIANT,
name: FieldIdx::ZERO,
};
let expr =
Expr {
temp_scope_id,
ty: pin_ty,
span,
kind: pointer_target,
};
ExprKind::Deref { arg: self.thir.exprs.push(expr) }
}
Adjust::Deref(DerefAdjustKind::Overloaded(deref)) => {
let call_def_id = deref.method_call(self.tcx);
let overloaded_callee =
Ty::new_fn_def(self.tcx, call_def_id,
self.tcx.mk_args(&[expr.ty.into()]));
expr =
Expr {
temp_scope_id,
ty: Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased,
expr.ty, deref.mutbl),
span,
kind: ExprKind::Borrow {
borrow_kind: deref.mutbl.to_borrow_kind(),
arg: self.thir.exprs.push(expr),
},
};
let expr = Box::new([self.thir.exprs.push(expr)]);
self.overloaded_place(hir_expr, adjustment.target,
Some(overloaded_callee), expr, deref.span)
}
Adjust::Borrow(AutoBorrow::Ref(m)) =>
ExprKind::Borrow {
borrow_kind: m.to_borrow_kind(),
arg: self.thir.exprs.push(expr),
},
Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => {
ExprKind::RawBorrow {
mutability,
arg: self.thir.exprs.push(expr),
}
}
Adjust::Borrow(AutoBorrow::Pin(mutbl)) => {
let borrow_kind =
match mutbl {
hir::Mutability::Mut =>
BorrowKind::Mut { kind: mir::MutBorrowKind::Default },
hir::Mutability::Not => BorrowKind::Shared,
};
let new_pin_target =
Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased, expr.ty,
mutbl);
let arg = self.thir.exprs.push(expr);
let expr =
self.thir.exprs.push(Expr {
temp_scope_id,
ty: new_pin_target,
span,
kind: ExprKind::Borrow { borrow_kind, arg },
});
let pin_did =
self.tcx.require_lang_item(rustc_hir::LangItem::Pin, span);
let args = self.tcx.mk_args(&[new_pin_target.into()]);
let kind =
ExprKind::Adt(Box::new(AdtExpr {
adt_def: self.tcx.adt_def(pin_did),
variant_index: FIRST_VARIANT,
args,
fields: Box::new([FieldExpr {
name: FieldIdx::ZERO,
expr,
}]),
user_ty: None,
base: AdtExprBase::None,
}));
{
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/thir/cx/expr.rs:254",
"rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
::tracing_core::__macro_support::Option::Some(254u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
::tracing_core::field::FieldSet::new(&["kind"],
::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(&kind) as
&dyn Value))])
});
} else { ; }
};
kind
}
Adjust::GenericReborrow(mutability) => {
let expr = self.thir.exprs.push(expr);
let kind =
ExprKind::Reborrow {
source: expr,
mutability,
target: adjustment.target,
};
kind
}
};
Expr { temp_scope_id, ty: adjustment.target, span, kind }
}
}
}#[instrument(level = "trace", skip(self, expr, span))]
121 fn apply_adjustment(
122 &mut self,
123 hir_expr: &'tcx hir::Expr<'tcx>,
124 mut expr: Expr<'tcx>,
125 adjustment: &Adjustment<'tcx>,
126 mut span: Span,
127 ) -> Expr<'tcx> {
128 let Expr { temp_scope_id, .. } = expr;
129
130 let mut adjust_span = |expr: &mut Expr<'tcx>| {
141 if let ExprKind::Block { block } = expr.kind
142 && let Some(last_expr) = self.thir[block].expr
143 {
144 span = self.thir[last_expr].span;
145 expr.span = span;
146 }
147 };
148
149 let kind = match adjustment.kind {
150 Adjust::Pointer(cast) => {
151 if cast == PointerCoercion::Unsize {
152 adjust_span(&mut expr);
153 }
154
155 let is_from_as_cast = if let hir::Node::Expr(hir::Expr {
156 kind: hir::ExprKind::Cast(..),
157 span: cast_span,
158 ..
159 }) = self.tcx.parent_hir_node(hir_expr.hir_id)
160 {
161 span = *cast_span;
163 true
164 } else {
165 false
166 };
167 ExprKind::PointerCoercion {
168 cast,
169 source: self.thir.exprs.push(expr),
170 is_from_as_cast,
171 }
172 }
173 Adjust::NeverToAny if adjustment.target.is_never() => return expr,
174 Adjust::NeverToAny => ExprKind::NeverToAny { source: self.thir.exprs.push(expr) },
175 Adjust::Deref(DerefAdjustKind::Builtin) => {
176 adjust_span(&mut expr);
177 ExprKind::Deref { arg: self.thir.exprs.push(expr) }
178 }
179 Adjust::Deref(DerefAdjustKind::Pin) => {
180 adjust_span(&mut expr);
181 let pin_ty = expr.ty.pinned_ty().expect("Deref(Pin) with non-Pin type");
183 let pointer_target = ExprKind::Field {
184 lhs: self.thir.exprs.push(expr),
185 variant_index: FIRST_VARIANT,
186 name: FieldIdx::ZERO,
187 };
188 let expr = Expr { temp_scope_id, ty: pin_ty, span, kind: pointer_target };
189 ExprKind::Deref { arg: self.thir.exprs.push(expr) }
191 }
192 Adjust::Deref(DerefAdjustKind::Overloaded(deref)) => {
193 let call_def_id = deref.method_call(self.tcx);
196 let overloaded_callee =
197 Ty::new_fn_def(self.tcx, call_def_id, self.tcx.mk_args(&[expr.ty.into()]));
198
199 expr = Expr {
200 temp_scope_id,
201 ty: Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased, expr.ty, deref.mutbl),
202 span,
203 kind: ExprKind::Borrow {
204 borrow_kind: deref.mutbl.to_borrow_kind(),
205 arg: self.thir.exprs.push(expr),
206 },
207 };
208
209 let expr = Box::new([self.thir.exprs.push(expr)]);
210
211 self.overloaded_place(
212 hir_expr,
213 adjustment.target,
214 Some(overloaded_callee),
215 expr,
216 deref.span,
217 )
218 }
219 Adjust::Borrow(AutoBorrow::Ref(m)) => ExprKind::Borrow {
220 borrow_kind: m.to_borrow_kind(),
221 arg: self.thir.exprs.push(expr),
222 },
223 Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => {
224 ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) }
225 }
226 Adjust::Borrow(AutoBorrow::Pin(mutbl)) => {
227 let borrow_kind = match mutbl {
229 hir::Mutability::Mut => BorrowKind::Mut { kind: mir::MutBorrowKind::Default },
230 hir::Mutability::Not => BorrowKind::Shared,
231 };
232 let new_pin_target =
233 Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased, expr.ty, mutbl);
234 let arg = self.thir.exprs.push(expr);
235 let expr = self.thir.exprs.push(Expr {
236 temp_scope_id,
237 ty: new_pin_target,
238 span,
239 kind: ExprKind::Borrow { borrow_kind, arg },
240 });
241
242 let pin_did = self.tcx.require_lang_item(rustc_hir::LangItem::Pin, span);
244 let args = self.tcx.mk_args(&[new_pin_target.into()]);
245 let kind = ExprKind::Adt(Box::new(AdtExpr {
246 adt_def: self.tcx.adt_def(pin_did),
247 variant_index: FIRST_VARIANT,
248 args,
249 fields: Box::new([FieldExpr { name: FieldIdx::ZERO, expr }]),
250 user_ty: None,
251 base: AdtExprBase::None,
252 }));
253
254 debug!(?kind);
255 kind
256 }
257 Adjust::GenericReborrow(mutability) => {
258 let expr = self.thir.exprs.push(expr);
259 let kind =
260 ExprKind::Reborrow { source: expr, mutability, target: adjustment.target };
261
262 kind
263 }
264 };
265
266 Expr { temp_scope_id, ty: adjustment.target, span, kind }
267 }
268
269 fn mirror_expr_cast(
273 &mut self,
274 source: &'tcx hir::Expr<'tcx>,
275 temp_scope_id: hir::ItemLocalId,
276 span: Span,
277 ) -> ExprKind<'tcx> {
278 let tcx = self.tcx;
279
280 if self.typeck_results.is_coercion_cast(source.hir_id) {
283 ExprKind::Use { source: self.mirror_expr(source) }
285 } else if self.typeck_results.expr_ty(source).is_ref() {
286 ExprKind::PointerCoercion {
290 source: self.mirror_expr(source),
291 cast: PointerCoercion::ArrayToPointer,
292 is_from_as_cast: true,
293 }
294 } else if let hir::ExprKind::Path(ref qpath) = source.kind
295 && let res = self.typeck_results.qpath_res(qpath, source.hir_id)
296 && let ty = self.typeck_results.node_type(source.hir_id)
297 && let ty::Adt(adt_def, args) = ty.kind()
298 && let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), variant_ctor_id) = res
299 {
300 let idx = adt_def.variant_index_with_ctor_id(variant_ctor_id);
313 let (discr_did, discr_offset) = adt_def.discriminant_def_for_variant(idx);
314
315 use rustc_middle::ty::util::IntTypeExt;
316 let ty = adt_def.repr().discr_type();
317 let discr_ty = ty.to_ty(tcx);
318
319 let size = tcx
320 .layout_of(self.typing_env.as_query_input(discr_ty))
321 .unwrap_or_else(|e| {
::core::panicking::panic_fmt(format_args!("could not compute layout for {0:?}: {1:?}",
discr_ty, e));
}panic!("could not compute layout for {discr_ty:?}: {e:?}"))
322 .size;
323
324 let (lit, overflowing) = ScalarInt::truncate_from_uint(discr_offset as u128, size);
325 if overflowing {
326 self.tcx.dcx().span_delayed_bug(
328 source.span,
329 "overflowing enum wasn't rejected by hir analysis",
330 );
331 }
332 let kind = ExprKind::NonHirLiteral { lit, user_ty: None };
333 let offset = self.thir.exprs.push(Expr { temp_scope_id, ty: discr_ty, span, kind });
334
335 let source = match discr_did {
336 Some(did) => {
339 let kind = ExprKind::NamedConst { def_id: did, args, user_ty: None };
340 let lhs =
341 self.thir.exprs.push(Expr { temp_scope_id, ty: discr_ty, span, kind });
342 let bin = ExprKind::Binary { op: BinOp::Add, lhs, rhs: offset };
343 self.thir.exprs.push(Expr { temp_scope_id, ty: discr_ty, span, kind: bin })
344 }
345 None => offset,
346 };
347
348 ExprKind::Cast { source }
349 } else {
350 ExprKind::Cast { source: self.mirror_expr(source) }
353 }
354 }
355
356 x;#[instrument(level = "debug", skip(self), ret)]
357 fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> {
358 let tcx = self.tcx;
359 let expr_ty = self.typeck_results.expr_ty(expr);
360 let mk_expr =
361 |kind, ty| Expr { temp_scope_id: expr.hir_id.local_id, span: expr.span, ty, kind };
362
363 let kind = match expr.kind {
364 hir::ExprKind::MethodCall(segment, receiver, args, fn_span) => {
366 let expr = self.method_callee(expr, segment.ident.span, None);
368 info!("Using method span: {:?}", expr.span);
369 let args = std::iter::once(receiver)
370 .chain(args.iter())
371 .map(|expr| self.mirror_expr(expr))
372 .collect();
373 ExprKind::Call {
374 ty: expr.ty,
375 fun: self.thir.exprs.push(expr),
376 args,
377 from_hir_call: true,
378 fn_span,
379 }
380 }
381
382 hir::ExprKind::Call(fun, ref args) => {
383 if self.typeck_results.is_method_call(expr) {
384 let method = self.method_callee(expr, fun.span, None);
392
393 let arg_tys = args.iter().map(|e| self.typeck_results.expr_ty_adjusted(e));
394 let tupled_args = Expr {
395 ty: Ty::new_tup_from_iter(tcx, arg_tys),
396 temp_scope_id: expr.hir_id.local_id,
397 span: expr.span,
398 kind: ExprKind::Tuple { fields: self.mirror_exprs(args) },
399 };
400 let tupled_args = self.thir.exprs.push(tupled_args);
401
402 ExprKind::Call {
403 ty: method.ty,
404 fun: self.thir.exprs.push(method),
405 args: Box::new([self.mirror_expr(fun), tupled_args]),
406 from_hir_call: true,
407 fn_span: expr.span,
408 }
409 } else {
410 let adt_data = if let hir::ExprKind::Path(ref qpath) = fun.kind
412 && let Some(adt_def) = expr_ty.ty_adt_def()
413 {
414 match qpath {
415 hir::QPath::Resolved(_, path) => match path.res {
416 Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_id) => {
417 Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
418 }
419 Res::SelfCtor(..) => Some((adt_def, FIRST_VARIANT)),
420 _ => None,
421 },
422 hir::QPath::TypeRelative(_ty, _) => {
423 if let Some((DefKind::Ctor(_, CtorKind::Fn), ctor_id)) =
424 self.typeck_results.type_dependent_def(fun.hir_id)
425 {
426 Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
427 } else {
428 None
429 }
430 }
431 }
432 } else {
433 None
434 };
435 if let Some((adt_def, index)) = adt_data {
436 let node_args = self.typeck_results.node_args(fun.hir_id);
437 let user_provided_types = self.typeck_results.user_provided_types();
438 let user_ty =
439 user_provided_types.get(fun.hir_id).copied().map(|mut u_ty| {
440 if let ty::UserTypeKind::TypeOf(did, _) = &mut u_ty.value.kind {
441 *did = adt_def.did();
442 }
443 Box::new(u_ty)
444 });
445 debug!("make_mirror_unadjusted: (call) user_ty={:?}", user_ty);
446
447 let field_refs = args
448 .iter()
449 .enumerate()
450 .map(|(idx, e)| FieldExpr {
451 name: FieldIdx::new(idx),
452 expr: self.mirror_expr(e),
453 })
454 .collect();
455 ExprKind::Adt(Box::new(AdtExpr {
456 adt_def,
457 args: node_args,
458 variant_index: index,
459 fields: field_refs,
460 user_ty,
461 base: AdtExprBase::None,
462 }))
463 } else {
464 ExprKind::Call {
465 ty: self.typeck_results.node_type(fun.hir_id),
466 fun: self.mirror_expr(fun),
467 args: self.mirror_exprs(args),
468 from_hir_call: true,
469 fn_span: expr.span,
470 }
471 }
472 }
473 }
474
475 hir::ExprKind::Use(expr, span) => {
476 ExprKind::ByUse { expr: self.mirror_expr(expr), span }
477 }
478
479 hir::ExprKind::AddrOf(hir::BorrowKind::Ref, mutbl, arg) => {
480 ExprKind::Borrow { borrow_kind: mutbl.to_borrow_kind(), arg: self.mirror_expr(arg) }
481 }
482
483 hir::ExprKind::AddrOf(hir::BorrowKind::Raw, mutability, arg) => {
484 ExprKind::RawBorrow { mutability, arg: self.mirror_expr(arg) }
485 }
486
487 hir::ExprKind::AddrOf(hir::BorrowKind::Pin, mutbl, arg_expr) => match expr_ty.kind() {
490 &ty::Adt(adt_def, args) if tcx.is_lang_item(adt_def.did(), hir::LangItem::Pin) => {
491 let ty = args.type_at(0);
492 let arg_ty = self.typeck_results.expr_ty(arg_expr);
493 let mut arg = self.mirror_expr(arg_expr);
494 if mutbl.is_mut() && !arg_ty.is_unpin(self.tcx, self.typing_env) {
497 let block = self.thir.blocks.push(Block {
498 targeted_by_break: false,
499 region_scope: region::Scope {
500 local_id: arg_expr.hir_id.local_id,
501 data: region::ScopeData::Node,
502 },
503 span: arg_expr.span,
504 stmts: Box::new([]),
505 expr: Some(arg),
506 safety_mode: BlockSafety::Safe,
507 });
508 arg = self.thir.exprs.push(Expr {
509 temp_scope_id: arg_expr.hir_id.local_id,
510 ty: arg_ty,
511 span: arg_expr.span,
512 kind: ExprKind::Block { block },
513 });
514 }
515 let expr = self.thir.exprs.push(Expr {
516 temp_scope_id: expr.hir_id.local_id,
517 ty,
518 span: expr.span,
519 kind: ExprKind::Borrow { borrow_kind: mutbl.to_borrow_kind(), arg },
520 });
521 ExprKind::Adt(Box::new(AdtExpr {
522 adt_def,
523 variant_index: FIRST_VARIANT,
524 args,
525 fields: Box::new([FieldExpr { name: FieldIdx::from(0u32), expr }]),
526 user_ty: None,
527 base: AdtExprBase::None,
528 }))
529 }
530 _ => span_bug!(expr.span, "unexpected type for pinned borrow: {:?}", expr_ty),
531 },
532
533 hir::ExprKind::Block(blk, _) => ExprKind::Block { block: self.mirror_block(blk) },
534
535 hir::ExprKind::Assign(lhs, rhs, _) => {
536 ExprKind::Assign { lhs: self.mirror_expr(lhs), rhs: self.mirror_expr(rhs) }
537 }
538
539 hir::ExprKind::AssignOp(op, lhs, rhs) => {
540 if self.typeck_results.is_method_call(expr) {
541 let lhs = self.mirror_expr(lhs);
542 let rhs = self.mirror_expr(rhs);
543 self.overloaded_operator(expr, Box::new([lhs, rhs]))
544 } else {
545 ExprKind::AssignOp {
546 op: assign_op(op.node),
547 lhs: self.mirror_expr(lhs),
548 rhs: self.mirror_expr(rhs),
549 }
550 }
551 }
552
553 hir::ExprKind::Lit(lit) => ExprKind::Literal { lit, neg: false },
554
555 hir::ExprKind::Binary(op, lhs, rhs) => {
556 if self.typeck_results.is_method_call(expr) {
557 let lhs = self.mirror_expr(lhs);
558 let rhs = self.mirror_expr(rhs);
559 self.overloaded_operator(expr, Box::new([lhs, rhs]))
560 } else {
561 match op.node {
562 hir::BinOpKind::And => ExprKind::LogicalOp {
563 op: LogicalOp::And,
564 lhs: self.mirror_expr(lhs),
565 rhs: self.mirror_expr(rhs),
566 },
567 hir::BinOpKind::Or => ExprKind::LogicalOp {
568 op: LogicalOp::Or,
569 lhs: self.mirror_expr(lhs),
570 rhs: self.mirror_expr(rhs),
571 },
572 _ => {
573 let op = bin_op(op.node);
574 ExprKind::Binary {
575 op,
576 lhs: self.mirror_expr(lhs),
577 rhs: self.mirror_expr(rhs),
578 }
579 }
580 }
581 }
582 }
583
584 hir::ExprKind::Index(lhs, index, brackets_span) => {
585 if self.typeck_results.is_method_call(expr) {
586 let lhs = self.mirror_expr(lhs);
587 let index = self.mirror_expr(index);
588 self.overloaded_place(
589 expr,
590 expr_ty,
591 None,
592 Box::new([lhs, index]),
593 brackets_span,
594 )
595 } else {
596 ExprKind::Index { lhs: self.mirror_expr(lhs), index: self.mirror_expr(index) }
597 }
598 }
599
600 hir::ExprKind::Unary(hir::UnOp::Deref, arg) => {
601 if self.typeck_results.is_method_call(expr) {
602 let arg = self.mirror_expr(arg);
603 self.overloaded_place(expr, expr_ty, None, Box::new([arg]), expr.span)
604 } else {
605 ExprKind::Deref { arg: self.mirror_expr(arg) }
606 }
607 }
608
609 hir::ExprKind::Unary(hir::UnOp::Not, arg) => {
610 if self.typeck_results.is_method_call(expr) {
611 let arg = self.mirror_expr(arg);
612 self.overloaded_operator(expr, Box::new([arg]))
613 } else {
614 ExprKind::Unary { op: UnOp::Not, arg: self.mirror_expr(arg) }
615 }
616 }
617
618 hir::ExprKind::Unary(hir::UnOp::Neg, arg) => {
619 if self.typeck_results.is_method_call(expr) {
620 let arg = self.mirror_expr(arg);
621 self.overloaded_operator(expr, Box::new([arg]))
622 } else if let hir::ExprKind::Lit(lit) = arg.kind {
623 ExprKind::Literal { lit, neg: true }
624 } else {
625 ExprKind::Unary { op: UnOp::Neg, arg: self.mirror_expr(arg) }
626 }
627 }
628
629 hir::ExprKind::Struct(qpath, fields, ref base) => match expr_ty.kind() {
630 ty::Adt(adt, args) => match adt.adt_kind() {
631 AdtKind::Struct | AdtKind::Union => {
632 let user_provided_types = self.typeck_results.user_provided_types();
633 let user_ty = user_provided_types.get(expr.hir_id).copied().map(Box::new);
634 debug!("make_mirror_unadjusted: (struct/union) user_ty={:?}", user_ty);
635 ExprKind::Adt(Box::new(AdtExpr {
636 adt_def: *adt,
637 variant_index: FIRST_VARIANT,
638 args,
639 user_ty,
640 fields: self.field_refs(fields),
641 base: match base {
642 hir::StructTailExpr::Base(base) => AdtExprBase::Base(FruInfo {
643 base: self.mirror_expr(base),
644 field_types: self.typeck_results.fru_field_types()[expr.hir_id]
645 .iter()
646 .copied()
647 .collect(),
648 }),
649 hir::StructTailExpr::DefaultFields(_) => {
650 AdtExprBase::DefaultFields(
651 self.typeck_results.fru_field_types()[expr.hir_id]
652 .iter()
653 .copied()
654 .collect(),
655 )
656 }
657 hir::StructTailExpr::None
658 | hir::StructTailExpr::NoneWithError(_) => AdtExprBase::None,
659 },
660 }))
661 }
662 AdtKind::Enum => {
663 let res = self.typeck_results.qpath_res(qpath, expr.hir_id);
664 match res {
665 Res::Def(DefKind::Variant, variant_id) => {
666 assert!(matches!(
667 base,
668 hir::StructTailExpr::None
669 | hir::StructTailExpr::DefaultFields(_)
670 | hir::StructTailExpr::NoneWithError(_)
671 ));
672
673 let index = adt.variant_index_with_id(variant_id);
674 let user_provided_types = self.typeck_results.user_provided_types();
675 let user_ty =
676 user_provided_types.get(expr.hir_id).copied().map(Box::new);
677 debug!("make_mirror_unadjusted: (variant) user_ty={:?}", user_ty);
678 ExprKind::Adt(Box::new(AdtExpr {
679 adt_def: *adt,
680 variant_index: index,
681 args,
682 user_ty,
683 fields: self.field_refs(fields),
684 base: match base {
685 hir::StructTailExpr::DefaultFields(_) => {
686 AdtExprBase::DefaultFields(
687 self.typeck_results.fru_field_types()[expr.hir_id]
688 .iter()
689 .copied()
690 .collect(),
691 )
692 }
693 hir::StructTailExpr::Base(base) => {
694 span_bug!(base.span, "unexpected res: {:?}", res);
695 }
696 hir::StructTailExpr::None
697 | hir::StructTailExpr::NoneWithError(_) => {
698 AdtExprBase::None
699 }
700 },
701 }))
702 }
703 _ => {
704 span_bug!(expr.span, "unexpected res: {:?}", res);
705 }
706 }
707 }
708 },
709 _ => {
710 span_bug!(expr.span, "unexpected type for struct literal: {:?}", expr_ty);
711 }
712 },
713
714 hir::ExprKind::Closure(hir::Closure { .. }) => {
715 let closure_ty = self.typeck_results.expr_ty(expr);
716 let (def_id, args, movability) = match *closure_ty.kind() {
717 ty::Closure(def_id, args) => (def_id, UpvarArgs::Closure(args), None),
718 ty::Coroutine(def_id, args) => {
719 (def_id, UpvarArgs::Coroutine(args), Some(tcx.coroutine_movability(def_id)))
720 }
721 ty::CoroutineClosure(def_id, args) => {
722 (def_id, UpvarArgs::CoroutineClosure(args), None)
723 }
724 _ => {
725 span_bug!(expr.span, "closure expr w/o closure type: {:?}", closure_ty);
726 }
727 };
728 let def_id = def_id.expect_local();
729
730 let upvars = self
731 .tcx
732 .closure_captures(def_id)
733 .iter()
734 .zip_eq(args.upvar_tys())
735 .map(|(captured_place, ty)| {
736 let upvars = self.capture_upvar(expr, captured_place, ty);
737 self.thir.exprs.push(upvars)
738 })
739 .collect();
740
741 let fake_reads = match self.typeck_results.closure_fake_reads.get(&def_id) {
743 Some(fake_reads) => fake_reads
744 .iter()
745 .map(|(place, cause, hir_id)| {
746 let expr = self.convert_captured_hir_place(expr, place.clone());
747 (self.thir.exprs.push(expr), *cause, *hir_id)
748 })
749 .collect(),
750 None => Vec::new(),
751 };
752
753 ExprKind::Closure(Box::new(ClosureExpr {
754 closure_id: def_id,
755 args,
756 upvars,
757 movability,
758 fake_reads,
759 }))
760 }
761
762 hir::ExprKind::Path(ref qpath) => {
763 let res = self.typeck_results.qpath_res(qpath, expr.hir_id);
764 self.convert_path_expr(expr, res)
765 }
766
767 hir::ExprKind::InlineAsm(asm) => ExprKind::InlineAsm(Box::new(InlineAsmExpr {
768 asm_macro: asm.asm_macro,
769 template: asm.template,
770 operands: asm
771 .operands
772 .iter()
773 .map(|(op, _op_sp)| match *op {
774 hir::InlineAsmOperand::In { reg, expr } => {
775 InlineAsmOperand::In { reg, expr: self.mirror_expr(expr) }
776 }
777 hir::InlineAsmOperand::Out { reg, late, ref expr } => {
778 InlineAsmOperand::Out {
779 reg,
780 late,
781 expr: expr.map(|expr| self.mirror_expr(expr)),
782 }
783 }
784 hir::InlineAsmOperand::InOut { reg, late, expr } => {
785 InlineAsmOperand::InOut { reg, late, expr: self.mirror_expr(expr) }
786 }
787 hir::InlineAsmOperand::SplitInOut { reg, late, in_expr, ref out_expr } => {
788 InlineAsmOperand::SplitInOut {
789 reg,
790 late,
791 in_expr: self.mirror_expr(in_expr),
792 out_expr: out_expr.map(|expr| self.mirror_expr(expr)),
793 }
794 }
795 hir::InlineAsmOperand::Const { ref anon_const } => {
796 let ty = self.typeck_results.node_type(anon_const.hir_id);
797 let did = anon_const.def_id;
798 let typeck_root_def_id = tcx.typeck_root_def_id_local(did);
799 let parent_args = tcx.erase_and_anonymize_regions(
800 GenericArgs::identity_for_item(tcx, typeck_root_def_id),
801 );
802 let args =
803 InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty })
804 .args;
805
806 let uneval = mir::UnevaluatedConst::new(did.to_def_id(), args);
807 let value = mir::Const::Unevaluated(uneval, ty);
808 InlineAsmOperand::Const { value, span: tcx.def_span(did) }
809 }
810 hir::InlineAsmOperand::SymFn { expr } => {
811 InlineAsmOperand::SymFn { value: self.mirror_expr(expr) }
812 }
813 hir::InlineAsmOperand::SymStatic { path: _, def_id } => {
814 InlineAsmOperand::SymStatic { def_id }
815 }
816 hir::InlineAsmOperand::Label { block } => {
817 InlineAsmOperand::Label { block: self.mirror_block(block) }
818 }
819 })
820 .collect(),
821 options: asm.options,
822 line_spans: asm.line_spans,
823 })),
824
825 hir::ExprKind::OffsetOf(_, _) => {
826 let offset_of_intrinsic = tcx.require_lang_item(LangItem::OffsetOf, expr.span);
827 let mk_u32_kind = |val: u32| ExprKind::NonHirLiteral {
828 lit: ScalarInt::try_from_uint(val, Size::from_bits(32)).unwrap(),
829 user_ty: None,
830 };
831 let mk_usize_kind = |val: u64| ExprKind::NonHirLiteral {
832 lit: ScalarInt::try_from_target_usize(val, tcx).unwrap(),
833 user_ty: None,
834 };
835 let mk_call =
836 |thir: &mut Thir<'tcx>, ty: Ty<'tcx>, variant: VariantIdx, field: FieldIdx| {
837 let fun_ty =
838 Ty::new_fn_def(tcx, offset_of_intrinsic, [ty::GenericArg::from(ty)]);
839 let fun = thir
840 .exprs
841 .push(mk_expr(ExprKind::ZstLiteral { user_ty: None }, fun_ty));
842 let variant =
843 thir.exprs.push(mk_expr(mk_u32_kind(variant.as_u32()), tcx.types.u32));
844 let field =
845 thir.exprs.push(mk_expr(mk_u32_kind(field.as_u32()), tcx.types.u32));
846 let args = Box::new([variant, field]);
847 ExprKind::Call {
848 ty: fun_ty,
849 fun,
850 args,
851 from_hir_call: false,
852 fn_span: expr.span,
853 }
854 };
855
856 let indices = self.typeck_results.offset_of_data().get(expr.hir_id).unwrap();
857 let mut expr = None::<ExprKind<'_>>;
858
859 for &(container, variant, field) in indices.iter() {
860 let next = mk_call(&mut self.thir, container, variant, field);
861 expr = Some(match expr.take() {
862 None => next,
863 Some(last) => {
864 let last = self.thir.exprs.push(mk_expr(last, tcx.types.usize));
865 let next = self.thir.exprs.push(mk_expr(next, tcx.types.usize));
866 ExprKind::Binary { op: BinOp::Add, lhs: last, rhs: next }
867 }
868 });
869 }
870
871 expr.unwrap_or_else(|| mk_usize_kind(0))
872 }
873
874 hir::ExprKind::ConstBlock(ref anon_const) => {
875 let ty = self.typeck_results.node_type(anon_const.hir_id);
876 let did = anon_const.def_id;
877 let typeck_root_def_id = tcx.typeck_root_def_id_local(did);
878 let parent_args = tcx.erase_and_anonymize_regions(GenericArgs::identity_for_item(
879 tcx,
880 typeck_root_def_id,
881 ));
882 let args = InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty }).args;
883
884 ExprKind::ConstBlock { did: did.to_def_id(), args }
885 }
886 hir::ExprKind::Repeat(v, _) => {
888 let ty = self.typeck_results.expr_ty(expr);
889 let ty::Array(_, count) = ty.kind() else {
890 span_bug!(expr.span, "unexpected repeat expr ty: {:?}", ty);
891 };
892
893 ExprKind::Repeat { value: self.mirror_expr(v), count: *count }
894 }
895 hir::ExprKind::Ret(v) => ExprKind::Return { value: v.map(|v| self.mirror_expr(v)) },
896 hir::ExprKind::Become(call) => ExprKind::Become { value: self.mirror_expr(call) },
897 hir::ExprKind::Break(dest, ref value) => {
898 if find_attr!(self.tcx, expr.hir_id, ConstContinue(_)) {
899 match dest.target_id {
900 Ok(target_id) => {
901 let (Some(value), Some(_)) = (value, dest.label) else {
902 let span = expr.span;
903 self.tcx.dcx().emit_fatal(ConstContinueMissingLabelOrValue { span })
904 };
905
906 ExprKind::ConstContinue {
907 label: region::Scope {
908 local_id: target_id.local_id,
909 data: region::ScopeData::Node,
910 },
911 value: self.mirror_expr(value),
912 }
913 }
914 Err(err) => bug!("invalid loop id for break: {}", err),
915 }
916 } else {
917 match dest.target_id {
918 Ok(target_id) => ExprKind::Break {
919 label: region::Scope {
920 local_id: target_id.local_id,
921 data: region::ScopeData::Node,
922 },
923 value: value.map(|value| self.mirror_expr(value)),
924 },
925 Err(err) => bug!("invalid loop id for break: {}", err),
926 }
927 }
928 }
929 hir::ExprKind::Continue(dest) => match dest.target_id {
930 Ok(loop_id) => ExprKind::Continue {
931 label: region::Scope {
932 local_id: loop_id.local_id,
933 data: region::ScopeData::Node,
934 },
935 },
936 Err(err) => bug!("invalid loop id for continue: {}", err),
937 },
938 hir::ExprKind::Let(let_expr) => ExprKind::Let {
939 expr: self.mirror_expr(let_expr.init),
940 pat: self.pattern_from_hir(let_expr.pat),
941 },
942 hir::ExprKind::If(cond, then, else_opt) => ExprKind::If {
943 if_then_scope: region::Scope {
944 local_id: then.hir_id.local_id,
945 data: {
946 if expr.span.at_least_rust_2024() {
947 region::ScopeData::IfThenRescope
948 } else {
949 region::ScopeData::IfThen
950 }
951 },
952 },
953 cond: self.mirror_expr(cond),
954 then: self.mirror_expr(then),
955 else_opt: else_opt.map(|el| self.mirror_expr(el)),
956 },
957 hir::ExprKind::Match(discr, arms, match_source) => ExprKind::Match {
958 scrutinee: self.mirror_expr(discr),
959 arms: arms.iter().map(|a| self.convert_arm(a)).collect(),
960 match_source,
961 },
962 hir::ExprKind::Loop(body, ..) => {
963 if find_attr!(self.tcx, expr.hir_id, LoopMatch(_)) {
964 let dcx = self.tcx.dcx();
965
966 let loop_body_expr = match body.stmts {
968 [] => match body.expr {
969 Some(expr) => expr,
970 None => dcx.emit_fatal(LoopMatchMissingAssignment { span: body.span }),
971 },
972 [single] if body.expr.is_none() => match single.kind {
973 hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr) => expr,
974 _ => dcx.emit_fatal(LoopMatchMissingAssignment { span: body.span }),
975 },
976 [first @ last] | [first, .., last] => dcx
977 .emit_fatal(LoopMatchBadStatements { span: first.span.to(last.span) }),
978 };
979
980 let hir::ExprKind::Assign(state, rhs_expr, _) = loop_body_expr.kind else {
981 dcx.emit_fatal(LoopMatchMissingAssignment { span: loop_body_expr.span })
982 };
983
984 let hir::ExprKind::Block(block_body, _) = rhs_expr.kind else {
985 dcx.emit_fatal(LoopMatchBadRhs { span: rhs_expr.span })
986 };
987
988 for stmt in block_body.stmts {
991 if !matches!(stmt.kind, rustc_hir::StmtKind::Item(_)) {
992 dcx.emit_fatal(LoopMatchBadStatements { span: stmt.span })
993 }
994 }
995
996 let Some(block_body_expr) = block_body.expr else {
997 dcx.emit_fatal(LoopMatchBadRhs { span: block_body.span })
998 };
999
1000 let hir::ExprKind::Match(scrutinee, arms, _match_source) = block_body_expr.kind
1001 else {
1002 dcx.emit_fatal(LoopMatchBadRhs { span: block_body_expr.span })
1003 };
1004
1005 fn local(
1006 cx: &mut ThirBuildCx<'_>,
1007 expr: &rustc_hir::Expr<'_>,
1008 ) -> Option<hir::HirId> {
1009 if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = expr.kind
1010 && let Res::Local(hir_id) = path.res
1011 && !cx.is_upvar(hir_id)
1012 {
1013 return Some(hir_id);
1014 }
1015
1016 None
1017 }
1018
1019 let Some(scrutinee_hir_id) = local(self, scrutinee) else {
1020 dcx.emit_fatal(LoopMatchInvalidMatch { span: scrutinee.span })
1021 };
1022
1023 if local(self, state) != Some(scrutinee_hir_id) {
1024 dcx.emit_fatal(LoopMatchInvalidUpdate {
1025 scrutinee: scrutinee.span,
1026 lhs: state.span,
1027 })
1028 }
1029
1030 ExprKind::LoopMatch {
1031 state: self.mirror_expr(state),
1032 region_scope: region::Scope {
1033 local_id: block_body.hir_id.local_id,
1034 data: region::ScopeData::Node,
1035 },
1036
1037 match_data: Box::new(LoopMatchMatchData {
1038 scrutinee: self.mirror_expr(scrutinee),
1039 arms: arms.iter().map(|a| self.convert_arm(a)).collect(),
1040 span: block_body_expr.span,
1041 }),
1042 }
1043 } else {
1044 let block_ty = self.typeck_results.node_type(body.hir_id);
1045 let block = self.mirror_block(body);
1046 let body = self.thir.exprs.push(Expr {
1047 ty: block_ty,
1048 temp_scope_id: body.hir_id.local_id,
1049 span: self.thir[block].span,
1050 kind: ExprKind::Block { block },
1051 });
1052 ExprKind::Loop { body }
1053 }
1054 }
1055 hir::ExprKind::Field(source, ..) => ExprKind::Field {
1056 lhs: self.mirror_expr(source),
1057 variant_index: FIRST_VARIANT,
1058 name: self.typeck_results.field_index(expr.hir_id),
1059 },
1060 hir::ExprKind::Cast(source, cast_ty) => {
1061 let user_provided_types = self.typeck_results.user_provided_types();
1063 let user_ty = user_provided_types.get(cast_ty.hir_id);
1064
1065 debug!(
1066 "cast({:?}) has ty w/ hir_id {:?} and user provided ty {:?}",
1067 expr, cast_ty.hir_id, user_ty,
1068 );
1069
1070 let cast = self.mirror_expr_cast(source, expr.hir_id.local_id, expr.span);
1071
1072 if let Some(user_ty) = user_ty {
1073 let cast_expr = self.thir.exprs.push(Expr {
1076 temp_scope_id: expr.hir_id.local_id,
1077 ty: expr_ty,
1078 span: expr.span,
1079 kind: cast,
1080 });
1081 debug!("make_mirror_unadjusted: (cast) user_ty={:?}", user_ty);
1082
1083 ExprKind::ValueTypeAscription {
1084 source: cast_expr,
1085 user_ty: Some(Box::new(*user_ty)),
1086 user_ty_span: cast_ty.span,
1087 }
1088 } else {
1089 cast
1090 }
1091 }
1092 hir::ExprKind::Type(source, ty) => {
1093 let user_provided_types = self.typeck_results.user_provided_types();
1094 let user_ty = user_provided_types.get(ty.hir_id).copied().map(Box::new);
1095 debug!("make_mirror_unadjusted: (type) user_ty={:?}", user_ty);
1096 let mirrored = self.mirror_expr(source);
1097 if source.is_syntactic_place_expr() {
1098 ExprKind::PlaceTypeAscription {
1099 source: mirrored,
1100 user_ty,
1101 user_ty_span: ty.span,
1102 }
1103 } else {
1104 ExprKind::ValueTypeAscription {
1105 source: mirrored,
1106 user_ty,
1107 user_ty_span: ty.span,
1108 }
1109 }
1110 }
1111
1112 hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Unwrap, source, _ty) => {
1113 let mirrored = self.mirror_expr(source);
1115 if source.is_syntactic_place_expr() {
1116 ExprKind::PlaceUnwrapUnsafeBinder { source: mirrored }
1117 } else {
1118 ExprKind::ValueUnwrapUnsafeBinder { source: mirrored }
1119 }
1120 }
1121 hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Wrap, source, _ty) => {
1122 let mirrored = self.mirror_expr(source);
1124 ExprKind::WrapUnsafeBinder { source: mirrored }
1125 }
1126
1127 hir::ExprKind::DropTemps(source) => ExprKind::Use { source: self.mirror_expr(source) },
1128 hir::ExprKind::Array(fields) => ExprKind::Array { fields: self.mirror_exprs(fields) },
1129 hir::ExprKind::Tup(fields) => ExprKind::Tuple { fields: self.mirror_exprs(fields) },
1130
1131 hir::ExprKind::Yield(v, _) => ExprKind::Yield { value: self.mirror_expr(v) },
1132 hir::ExprKind::Err(_) => unreachable!("cannot lower a `hir::ExprKind::Err` to THIR"),
1133 };
1134
1135 mk_expr(kind, expr_ty)
1136 }
1137
1138 fn user_args_applied_to_res(
1139 &mut self,
1140 hir_id: hir::HirId,
1141 res: Res,
1142 ) -> Option<Box<ty::CanonicalUserType<'tcx>>> {
1143 {
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/thir/cx/expr.rs:1143",
"rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
::tracing_core::__macro_support::Option::Some(1143u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
::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!("user_args_applied_to_res: res={0:?}",
res) as &dyn Value))])
});
} else { ; }
};debug!("user_args_applied_to_res: res={:?}", res);
1144 let user_provided_type = match res {
1145 Res::Def(DefKind::Fn, _)
1149 | Res::Def(DefKind::AssocFn, _)
1150 | Res::Def(DefKind::Ctor(_, CtorKind::Fn), _)
1151 | Res::Def(DefKind::Const { .. }, _)
1152 | Res::Def(DefKind::AssocConst { .. }, _) => {
1153 self.typeck_results.user_provided_types().get(hir_id).copied().map(Box::new)
1154 }
1155
1156 Res::Def(DefKind::Ctor(_, CtorKind::Const), _) => {
1161 self.user_args_applied_to_ty_of_hir_id(hir_id).map(Box::new)
1162 }
1163
1164 Res::SelfCtor(_) => self.user_args_applied_to_ty_of_hir_id(hir_id).map(Box::new),
1166
1167 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("user_args_applied_to_res: unexpected res {0:?} at {1:?}",
res, hir_id))bug!("user_args_applied_to_res: unexpected res {:?} at {:?}", res, hir_id),
1168 };
1169 {
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/thir/cx/expr.rs:1169",
"rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
::tracing_core::__macro_support::Option::Some(1169u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
::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!("user_args_applied_to_res: user_provided_type={0:?}",
user_provided_type) as &dyn Value))])
});
} else { ; }
};debug!("user_args_applied_to_res: user_provided_type={:?}", user_provided_type);
1170 user_provided_type
1171 }
1172
1173 fn method_callee(
1174 &mut self,
1175 expr: &hir::Expr<'_>,
1176 span: Span,
1177 overloaded_callee: Option<Ty<'tcx>>,
1178 ) -> Expr<'tcx> {
1179 let (ty, user_ty) = match overloaded_callee {
1180 Some(fn_def) => (fn_def, None),
1181 None => {
1182 let (kind, def_id) =
1183 self.typeck_results.type_dependent_def(expr.hir_id).unwrap_or_else(|| {
1184 ::rustc_middle::util::bug::span_bug_fmt(expr.span,
format_args!("no type-dependent def for method callee"))span_bug!(expr.span, "no type-dependent def for method callee")
1185 });
1186 let user_ty = self.user_args_applied_to_res(expr.hir_id, Res::Def(kind, def_id));
1187 {
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/thir/cx/expr.rs:1187",
"rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
::tracing_core::__macro_support::Option::Some(1187u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
::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!("method_callee: user_ty={0:?}",
user_ty) as &dyn Value))])
});
} else { ; }
};debug!("method_callee: user_ty={:?}", user_ty);
1188 (
1189 Ty::new_fn_def(self.tcx, def_id, self.typeck_results.node_args(expr.hir_id)),
1190 user_ty,
1191 )
1192 }
1193 };
1194 Expr {
1195 temp_scope_id: expr.hir_id.local_id,
1196 ty,
1197 span,
1198 kind: ExprKind::ZstLiteral { user_ty },
1199 }
1200 }
1201
1202 fn convert_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) -> ArmId {
1203 let arm = Arm {
1204 pattern: self.pattern_from_hir(&arm.pat),
1205 guard: arm.guard.as_ref().map(|g| self.mirror_expr(g)),
1206 body: self.mirror_expr(arm.body),
1207 hir_id: arm.hir_id,
1208 scope: region::Scope { local_id: arm.hir_id.local_id, data: region::ScopeData::Node },
1209 span: arm.span,
1210 };
1211 self.thir.arms.push(arm)
1212 }
1213
1214 fn convert_path_expr(&mut self, expr: &'tcx hir::Expr<'tcx>, res: Res) -> ExprKind<'tcx> {
1215 let args = self.typeck_results.node_args(expr.hir_id);
1216 match res {
1217 Res::Def(DefKind::Fn, _)
1219 | Res::Def(DefKind::AssocFn, _)
1220 | Res::Def(DefKind::Ctor(_, CtorKind::Fn), _)
1221 | Res::SelfCtor(_) => {
1222 let user_ty = self.user_args_applied_to_res(expr.hir_id, res);
1223 ExprKind::ZstLiteral { user_ty }
1224 }
1225
1226 Res::Def(DefKind::ConstParam, def_id) => {
1227 let hir_id = self.tcx.local_def_id_to_hir_id(def_id.expect_local());
1228 let generics = self.tcx.generics_of(hir_id.owner);
1229 let Some(&index) = generics.param_def_id_to_index.get(&def_id) else {
1230 ::rustc_middle::util::bug::span_bug_fmt(expr.span,
format_args!("Should have already errored about late bound consts: {0:?}",
def_id));span_bug!(
1231 expr.span,
1232 "Should have already errored about late bound consts: {def_id:?}"
1233 );
1234 };
1235 let name = self.tcx.hir_name(hir_id);
1236 let param = ty::ParamConst::new(index, name);
1237
1238 ExprKind::ConstParam { param, def_id }
1239 }
1240
1241 Res::Def(DefKind::Const { .. }, def_id)
1242 | Res::Def(DefKind::AssocConst { .. }, def_id) => {
1243 let user_ty = self.user_args_applied_to_res(expr.hir_id, res);
1244 ExprKind::NamedConst { def_id, args, user_ty }
1245 }
1246
1247 Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id) => {
1248 let user_provided_types = self.typeck_results.user_provided_types();
1249 let user_ty = user_provided_types.get(expr.hir_id).copied().map(Box::new);
1250 {
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/thir/cx/expr.rs:1250",
"rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
::tracing_core::__macro_support::Option::Some(1250u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
::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!("convert_path_expr: user_ty={0:?}",
user_ty) as &dyn Value))])
});
} else { ; }
};debug!("convert_path_expr: user_ty={:?}", user_ty);
1251 let ty = self.typeck_results.node_type(expr.hir_id);
1252 match ty.kind() {
1253 ty::Adt(adt_def, args) => ExprKind::Adt(Box::new(AdtExpr {
1256 adt_def: *adt_def,
1257 variant_index: adt_def.variant_index_with_ctor_id(def_id),
1258 args,
1259 user_ty,
1260 fields: Box::new([]),
1261 base: AdtExprBase::None,
1262 })),
1263 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected ty: {0:?}", ty))bug!("unexpected ty: {:?}", ty),
1264 }
1265 }
1266
1267 Res::Def(DefKind::Static { .. }, id) => {
1271 let ty = self.tcx.static_ptr_ty(id, self.typing_env);
1273 let kind = if self.tcx.is_thread_local_static(id) {
1274 ExprKind::ThreadLocalRef(id)
1275 } else {
1276 let alloc_id = self.tcx.reserve_and_set_static_alloc(id);
1277 ExprKind::StaticRef { alloc_id, ty, def_id: id }
1278 };
1279 ExprKind::Deref {
1280 arg: self.thir.exprs.push(Expr {
1281 ty,
1282 temp_scope_id: expr.hir_id.local_id,
1283 span: expr.span,
1284 kind,
1285 }),
1286 }
1287 }
1288
1289 Res::Local(var_hir_id) => self.convert_var(var_hir_id),
1290
1291 _ => ::rustc_middle::util::bug::span_bug_fmt(expr.span,
format_args!("res `{0:?}` not yet implemented", res))span_bug!(expr.span, "res `{:?}` not yet implemented", res),
1292 }
1293 }
1294
1295 fn convert_var(&mut self, var_hir_id: hir::HirId) -> ExprKind<'tcx> {
1296 let is_upvar = self.is_upvar(var_hir_id);
1299
1300 {
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/thir/cx/expr.rs:1300",
"rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
::tracing_core::__macro_support::Option::Some(1300u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
::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!("convert_var({0:?}): is_upvar={1}, body_owner={2:?}",
var_hir_id, is_upvar, self.body_owner) as &dyn Value))])
});
} else { ; }
};debug!(
1301 "convert_var({:?}): is_upvar={}, body_owner={:?}",
1302 var_hir_id, is_upvar, self.body_owner
1303 );
1304
1305 if is_upvar {
1306 ExprKind::UpvarRef {
1307 closure_def_id: self.body_owner,
1308 var_hir_id: LocalVarId(var_hir_id),
1309 }
1310 } else {
1311 ExprKind::VarRef { id: LocalVarId(var_hir_id) }
1312 }
1313 }
1314
1315 fn overloaded_operator(
1316 &mut self,
1317 expr: &'tcx hir::Expr<'tcx>,
1318 args: Box<[ExprId]>,
1319 ) -> ExprKind<'tcx> {
1320 let fun = self.method_callee(expr, expr.span, None);
1321 let fun = self.thir.exprs.push(fun);
1322 ExprKind::Call {
1323 ty: self.thir[fun].ty,
1324 fun,
1325 args,
1326 from_hir_call: false,
1327 fn_span: expr.span,
1328 }
1329 }
1330
1331 fn overloaded_place(
1332 &mut self,
1333 expr: &'tcx hir::Expr<'tcx>,
1334 place_ty: Ty<'tcx>,
1335 overloaded_callee: Option<Ty<'tcx>>,
1336 args: Box<[ExprId]>,
1337 span: Span,
1338 ) -> ExprKind<'tcx> {
1339 let ty::Ref(region, _, mutbl) = *self.thir[args[0]].ty.kind() else {
1347 ::rustc_middle::util::bug::span_bug_fmt(span,
format_args!("overloaded_place: receiver is not a reference"));span_bug!(span, "overloaded_place: receiver is not a reference");
1348 };
1349 let ref_ty = Ty::new_ref(self.tcx, region, place_ty, mutbl);
1350
1351 let fun = self.method_callee(expr, span, overloaded_callee);
1354 let fun = self.thir.exprs.push(fun);
1355 let fun_ty = self.thir[fun].ty;
1356 let ref_expr = self.thir.exprs.push(Expr {
1357 temp_scope_id: expr.hir_id.local_id,
1358 ty: ref_ty,
1359 span,
1360 kind: ExprKind::Call { ty: fun_ty, fun, args, from_hir_call: false, fn_span: span },
1361 });
1362
1363 ExprKind::Deref { arg: ref_expr }
1365 }
1366
1367 fn convert_captured_hir_place(
1368 &mut self,
1369 closure_expr: &'tcx hir::Expr<'tcx>,
1370 place: HirPlace<'tcx>,
1371 ) -> Expr<'tcx> {
1372 let temp_scope_id = closure_expr.hir_id.local_id;
1373 let var_ty = place.base_ty;
1374
1375 let var_hir_id = match place.base {
1381 HirPlaceBase::Upvar(upvar_id) => upvar_id.var_path.hir_id,
1382 base => ::rustc_middle::util::bug::bug_fmt(format_args!("Expected an upvar, found {0:?}",
base))bug!("Expected an upvar, found {:?}", base),
1383 };
1384
1385 let mut captured_place_expr = Expr {
1386 temp_scope_id,
1387 ty: var_ty,
1388 span: closure_expr.span,
1389 kind: self.convert_var(var_hir_id),
1390 };
1391
1392 for proj in place.projections.iter() {
1393 let kind = match proj.kind {
1394 HirProjectionKind::Deref => {
1395 ExprKind::Deref { arg: self.thir.exprs.push(captured_place_expr) }
1396 }
1397 HirProjectionKind::Field(field, variant_index) => ExprKind::Field {
1398 lhs: self.thir.exprs.push(captured_place_expr),
1399 variant_index,
1400 name: field,
1401 },
1402 HirProjectionKind::OpaqueCast => {
1403 ExprKind::Use { source: self.thir.exprs.push(captured_place_expr) }
1404 }
1405 HirProjectionKind::UnwrapUnsafeBinder => ExprKind::PlaceUnwrapUnsafeBinder {
1406 source: self.thir.exprs.push(captured_place_expr),
1407 },
1408 HirProjectionKind::Index | HirProjectionKind::Subslice => {
1409 continue;
1411 }
1412 };
1413
1414 captured_place_expr =
1415 Expr { temp_scope_id, ty: proj.ty, span: closure_expr.span, kind };
1416 }
1417
1418 captured_place_expr
1419 }
1420
1421 fn capture_upvar(
1422 &mut self,
1423 closure_expr: &'tcx hir::Expr<'tcx>,
1424 captured_place: &'tcx ty::CapturedPlace<'tcx>,
1425 upvar_ty: Ty<'tcx>,
1426 ) -> Expr<'tcx> {
1427 let upvar_capture = captured_place.info.capture_kind;
1428 let captured_place_expr =
1429 self.convert_captured_hir_place(closure_expr, captured_place.place.clone());
1430 let temp_scope_id = closure_expr.hir_id.local_id;
1431
1432 match upvar_capture {
1433 ty::UpvarCapture::ByValue => captured_place_expr,
1434 ty::UpvarCapture::ByUse => {
1435 let span = captured_place_expr.span;
1436 let expr_id = self.thir.exprs.push(captured_place_expr);
1437
1438 Expr {
1439 temp_scope_id,
1440 ty: upvar_ty,
1441 span: closure_expr.span,
1442 kind: ExprKind::ByUse { expr: expr_id, span },
1443 }
1444 }
1445 ty::UpvarCapture::ByRef(upvar_borrow) => {
1446 let borrow_kind = match upvar_borrow {
1447 ty::BorrowKind::Immutable => BorrowKind::Shared,
1448 ty::BorrowKind::UniqueImmutable => {
1449 BorrowKind::Mut { kind: mir::MutBorrowKind::ClosureCapture }
1450 }
1451 ty::BorrowKind::Mutable => {
1452 BorrowKind::Mut { kind: mir::MutBorrowKind::Default }
1453 }
1454 };
1455 Expr {
1456 temp_scope_id,
1457 ty: upvar_ty,
1458 span: closure_expr.span,
1459 kind: ExprKind::Borrow {
1460 borrow_kind,
1461 arg: self.thir.exprs.push(captured_place_expr),
1462 },
1463 }
1464 }
1465 }
1466 }
1467
1468 fn is_upvar(&mut self, var_hir_id: hir::HirId) -> bool {
1469 self.tcx
1470 .upvars_mentioned(self.body_owner)
1471 .is_some_and(|upvars| upvars.contains_key(&var_hir_id))
1472 }
1473
1474 fn field_refs(&mut self, fields: &'tcx [hir::ExprField<'tcx>]) -> Box<[FieldExpr]> {
1476 fields
1477 .iter()
1478 .map(|field| FieldExpr {
1479 name: self.typeck_results.field_index(field.hir_id),
1480 expr: self.mirror_expr(field.expr),
1481 })
1482 .collect()
1483 }
1484}
1485
1486trait ToBorrowKind {
1487 fn to_borrow_kind(&self) -> BorrowKind;
1488}
1489
1490impl ToBorrowKind for AutoBorrowMutability {
1491 fn to_borrow_kind(&self) -> BorrowKind {
1492 use rustc_middle::ty::adjustment::AllowTwoPhase;
1493 match *self {
1494 AutoBorrowMutability::Mut { allow_two_phase_borrow } => BorrowKind::Mut {
1495 kind: match allow_two_phase_borrow {
1496 AllowTwoPhase::Yes => mir::MutBorrowKind::TwoPhaseBorrow,
1497 AllowTwoPhase::No => mir::MutBorrowKind::Default,
1498 },
1499 },
1500 AutoBorrowMutability::Not => BorrowKind::Shared,
1501 }
1502 }
1503}
1504
1505impl ToBorrowKind for hir::Mutability {
1506 fn to_borrow_kind(&self) -> BorrowKind {
1507 match *self {
1508 hir::Mutability::Mut => BorrowKind::Mut { kind: mir::MutBorrowKind::Default },
1509 hir::Mutability::Not => BorrowKind::Shared,
1510 }
1511 }
1512}
1513
1514fn bin_op(op: hir::BinOpKind) -> BinOp {
1515 match op {
1516 hir::BinOpKind::Add => BinOp::Add,
1517 hir::BinOpKind::Sub => BinOp::Sub,
1518 hir::BinOpKind::Mul => BinOp::Mul,
1519 hir::BinOpKind::Div => BinOp::Div,
1520 hir::BinOpKind::Rem => BinOp::Rem,
1521 hir::BinOpKind::BitXor => BinOp::BitXor,
1522 hir::BinOpKind::BitAnd => BinOp::BitAnd,
1523 hir::BinOpKind::BitOr => BinOp::BitOr,
1524 hir::BinOpKind::Shl => BinOp::Shl,
1525 hir::BinOpKind::Shr => BinOp::Shr,
1526 hir::BinOpKind::Eq => BinOp::Eq,
1527 hir::BinOpKind::Lt => BinOp::Lt,
1528 hir::BinOpKind::Le => BinOp::Le,
1529 hir::BinOpKind::Ne => BinOp::Ne,
1530 hir::BinOpKind::Ge => BinOp::Ge,
1531 hir::BinOpKind::Gt => BinOp::Gt,
1532 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("no equivalent for ast binop {0:?}",
op))bug!("no equivalent for ast binop {:?}", op),
1533 }
1534}
1535
1536fn assign_op(op: hir::AssignOpKind) -> AssignOp {
1537 match op {
1538 hir::AssignOpKind::AddAssign => AssignOp::AddAssign,
1539 hir::AssignOpKind::SubAssign => AssignOp::SubAssign,
1540 hir::AssignOpKind::MulAssign => AssignOp::MulAssign,
1541 hir::AssignOpKind::DivAssign => AssignOp::DivAssign,
1542 hir::AssignOpKind::RemAssign => AssignOp::RemAssign,
1543 hir::AssignOpKind::BitXorAssign => AssignOp::BitXorAssign,
1544 hir::AssignOpKind::BitAndAssign => AssignOp::BitAndAssign,
1545 hir::AssignOpKind::BitOrAssign => AssignOp::BitOrAssign,
1546 hir::AssignOpKind::ShlAssign => AssignOp::ShlAssign,
1547 hir::AssignOpKind::ShrAssign => AssignOp::ShrAssign,
1548 }
1549}