1use itertools::Itertools;
2use rustc_abi::{FIRST_VARIANT, FieldIdx, Size, VariantIdx};
3use rustc_ast::UnsafeBinderCastKind;
4use rustc_data_structures::thin_vec::ThinVec;
5use rustc_hir as hir;
6use rustc_hir::attrs::lang_items::LangItem;
7use rustc_hir::attrs::{AttributeKind, HasAttrs};
8use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
9use rustc_hir::{HirId, 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, SplattedDef, Ty,
22 TyCtxt, UpvarArgs,
23};
24use rustc_middle::{bug, span_bug};
25use rustc_span::{DesugaringKind, Span};
26use tracing::{debug, info, instrument, trace};
27
28use crate::diagnostics::*;
29use crate::thir::cx::ThirBuildCx;
30
31#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for SplattedFunc<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for SplattedFunc<'tcx> {
#[inline]
fn clone(&self) -> SplattedFunc<'tcx> {
let _: ::core::clone::AssertParamIsClone<&'tcx hir::Expr<'tcx>>;
let _: ::core::clone::AssertParamIsClone<&'tcx hir::Expr<'tcx>>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for SplattedFunc<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
SplattedFunc::FnDefReceiver(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"FnDefReceiver", &__self_0),
SplattedFunc::FnExpression(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"FnExpression", &__self_0),
}
}
}Debug)]
33enum SplattedFunc<'tcx> {
34 FnDefReceiver(&'tcx hir::Expr<'tcx>),
36 FnExpression(&'tcx hir::Expr<'tcx>),
39}
40
41impl<'tcx> SplattedFunc<'tcx> {
42 fn has_receiver(&self) -> bool {
43 #[allow(non_exhaustive_omitted_patterns)] match self {
SplattedFunc::FnDefReceiver(_) => true,
_ => false,
}matches!(self, SplattedFunc::FnDefReceiver(_))
44 }
45
46 fn receiver(&self) -> Option<&'tcx hir::Expr<'tcx>> {
47 match self {
48 SplattedFunc::FnDefReceiver(receiver) => Some(receiver),
49 SplattedFunc::FnExpression(_fn_expression) => None,
50 }
51 }
52
53 fn fn_expression(&self) -> Option<&'tcx hir::Expr<'tcx>> {
54 match self {
55 SplattedFunc::FnDefReceiver(_receiver) => None,
56 SplattedFunc::FnExpression(fn_expression) => Some(fn_expression),
57 }
58 }
59}
60
61fn parsed_attrs(id: HirId, tcx: TyCtxt<'_>) -> ThinVec<AttributeKind> {
62 HasAttrs::get_attrs(id, &tcx)
63 .into_iter()
64 .filter_map(|attr| match attr {
65 hir::Attribute::Parsed(attrkind) => Some(attrkind.clone()),
66 hir::Attribute::Unparsed(_) => None,
67 })
68 .collect()
69}
70
71impl<'tcx> ThirBuildCx<'tcx> {
72 pub(crate) fn mirror_exprs(&mut self, exprs: &'tcx [hir::Expr<'tcx>]) -> Box<[ExprId]> {
73 exprs.iter().map(|expr| self.mirror_expr(expr)).collect()
74 }
75
76 #[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",
"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(84u32),
::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_all(&[]) })
} 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:89",
"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(89u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("hir_expr.hir_id")
}> =
::tracing::__macro_support::FieldName::new("hir_expr.hir_id");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("hir_expr.span")
}> =
::tracing::__macro_support::FieldName::new("hir_expr.span");
NAME.as_str()
}], ::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&hir_expr.hir_id)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&hir_expr.span)
as &dyn ::tracing::field::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: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(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("expr.ty")
}> =
::tracing::__macro_support::FieldName::new("expr.ty");
NAME.as_str()
}], ::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&expr.ty)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let mut attrs = ThinVec::new();
if let hir::ExprKind::Loop(_, _, _, span) = hir_expr.kind {
match span.desugaring_kind() {
Some(DesugaringKind::ForLoop) => {
let arm =
self.tcx.parent_hir_node(hir_expr.hir_id).expect_arm();
let expr =
self.tcx.parent_hir_node(arm.hir_id).expect_expr();
{
match expr.kind {
hir::ExprKind::Match(..) => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"hir::ExprKind::Match(..)", ::core::option::Option::None);
}
}
};
if let hir::Node::Expr(expr) =
self.tcx.parent_hir_node(expr.hir_id) {
{
match expr.kind {
hir::ExprKind::DropTemps(..) => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"hir::ExprKind::DropTemps(..)",
::core::option::Option::None);
}
}
};
attrs = parsed_attrs(expr.hir_id, self.tcx)
}
}
Some(DesugaringKind::WhileLoop) | None => {
attrs = parsed_attrs(hir_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:121",
"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(121u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("expr")
}> =
::tracing::__macro_support::FieldName::new("expr");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("adjustment")
}> =
::tracing::__macro_support::FieldName::new("adjustment");
NAME.as_str()
}], ::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&expr)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&adjustment)
as &dyn ::tracing::field::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:127",
"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(127u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("expr.ty")
}> =
::tracing::__macro_support::FieldName::new("expr.ty");
NAME.as_str()
}], ::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("after adjustments")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&expr.ty)
as &dyn ::tracing::field::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))]
85 pub(crate) fn mirror_expr(&mut self, hir_expr: &'tcx hir::Expr<'tcx>) -> ExprId {
86 let expr_scope =
87 region::Scope { local_id: hir_expr.hir_id.local_id, data: region::ScopeData::Node };
88
89 trace!(?hir_expr.hir_id, ?hir_expr.span);
90
91 let mut expr = self.make_mirror_unadjusted(hir_expr);
92
93 trace!(?expr.ty);
94
95 let mut attrs = ThinVec::new();
96
97 if let hir::ExprKind::Loop(_, _, _, span) = hir_expr.kind {
98 match span.desugaring_kind() {
99 Some(DesugaringKind::ForLoop) => {
101 let arm = self.tcx.parent_hir_node(hir_expr.hir_id).expect_arm();
102 let expr = self.tcx.parent_hir_node(arm.hir_id).expect_expr();
103 std::assert_matches!(expr.kind, hir::ExprKind::Match(..));
104 if let hir::Node::Expr(expr) = self.tcx.parent_hir_node(expr.hir_id) {
106 std::assert_matches!(expr.kind, hir::ExprKind::DropTemps(..));
107 attrs = parsed_attrs(expr.hir_id, self.tcx)
108 }
109 }
110 Some(DesugaringKind::WhileLoop) | None => {
112 attrs = parsed_attrs(hir_expr.hir_id, self.tcx);
113 }
114 _ => (),
115 }
116 }
117
118 if self.apply_adjustments {
120 for adjustment in self.typeck_results.expr_adjustments(hir_expr) {
121 trace!(?expr, ?adjustment);
122 let span = expr.span;
123 expr = self.apply_adjustment(hir_expr, expr, adjustment, span);
124 }
125 }
126
127 trace!(?expr.ty, "after adjustments");
128
129 let ty = expr.ty;
130 let value = self.thir.exprs.push(expr);
131
132 if !attrs.is_empty() {
133 self.thir.attributes.insert(value, attrs);
134 }
135
136 expr = Expr {
138 temp_scope_id: expr_scope.local_id,
139 ty,
140 span: hir_expr.span,
141 kind: ExprKind::Scope { region_scope: expr_scope, value, hir_id: hir_expr.hir_id },
142 };
143
144 self.thir.exprs.push(expr)
146 }
147
148 #[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(148u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("hir_expr")
}> =
::tracing::__macro_support::FieldName::new("hir_expr");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("adjustment")
}> =
::tracing::__macro_support::FieldName::new("adjustment");
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::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&hir_expr)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&adjustment)
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: 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 =
self.tcx.type_of(call_def_id).instantiate(self.tcx,
self.tcx.mk_args(&[expr.ty.into()])).skip_norm_wip();
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(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:285",
"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(285u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("kind")
}> =
::tracing::__macro_support::FieldName::new("kind");
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(&kind)
as &dyn ::tracing::field::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))]
149 fn apply_adjustment(
150 &mut self,
151 hir_expr: &'tcx hir::Expr<'tcx>,
152 mut expr: Expr<'tcx>,
153 adjustment: &Adjustment<'tcx>,
154 mut span: Span,
155 ) -> Expr<'tcx> {
156 let Expr { temp_scope_id, .. } = expr;
157
158 let mut adjust_span = |expr: &mut Expr<'tcx>| {
169 if let ExprKind::Block { block } = expr.kind
170 && let Some(last_expr) = self.thir[block].expr
171 {
172 span = self.thir[last_expr].span;
173 expr.span = span;
174 }
175 };
176
177 let kind = match adjustment.kind {
178 Adjust::Pointer(cast) => {
179 if cast == PointerCoercion::Unsize {
180 adjust_span(&mut expr);
181 }
182
183 let is_from_as_cast = if let hir::Node::Expr(hir::Expr {
184 kind: hir::ExprKind::Cast(..),
185 span: cast_span,
186 ..
187 }) = self.tcx.parent_hir_node(hir_expr.hir_id)
188 {
189 span = *cast_span;
191 true
192 } else {
193 false
194 };
195 ExprKind::PointerCoercion {
196 cast,
197 source: self.thir.exprs.push(expr),
198 is_from_as_cast,
199 }
200 }
201 Adjust::NeverToAny if adjustment.target.is_never() => return expr,
202 Adjust::NeverToAny => ExprKind::NeverToAny { source: self.thir.exprs.push(expr) },
203 Adjust::Deref(DerefAdjustKind::Builtin) => {
204 adjust_span(&mut expr);
205 ExprKind::Deref { arg: self.thir.exprs.push(expr) }
206 }
207 Adjust::Deref(DerefAdjustKind::Pin) => {
208 adjust_span(&mut expr);
209 let pin_ty = expr.ty.pinned_ty().expect("Deref(Pin) with non-Pin type");
211 let pointer_target = ExprKind::Field {
212 lhs: self.thir.exprs.push(expr),
213 variant_index: FIRST_VARIANT,
214 name: FieldIdx::ZERO,
215 };
216 let expr = Expr { temp_scope_id, ty: pin_ty, span, kind: pointer_target };
217 ExprKind::Deref { arg: self.thir.exprs.push(expr) }
219 }
220 Adjust::Deref(DerefAdjustKind::Overloaded(deref)) => {
221 let call_def_id = deref.method_call(self.tcx);
224 let overloaded_callee = self
225 .tcx
226 .type_of(call_def_id)
227 .instantiate(self.tcx, self.tcx.mk_args(&[expr.ty.into()]))
228 .skip_norm_wip();
229
230 expr = Expr {
231 temp_scope_id,
232 ty: Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased, expr.ty, deref.mutbl),
233 span,
234 kind: ExprKind::Borrow {
235 borrow_kind: deref.mutbl.to_borrow_kind(),
236 arg: self.thir.exprs.push(expr),
237 },
238 };
239
240 let expr = Box::new([self.thir.exprs.push(expr)]);
241
242 self.overloaded_place(
243 hir_expr,
244 adjustment.target,
245 Some(overloaded_callee),
246 expr,
247 deref.span,
248 )
249 }
250 Adjust::Borrow(AutoBorrow::Ref(m)) => ExprKind::Borrow {
251 borrow_kind: m.to_borrow_kind(),
252 arg: self.thir.exprs.push(expr),
253 },
254 Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => {
255 ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) }
256 }
257 Adjust::Borrow(AutoBorrow::Pin(mutbl)) => {
258 let borrow_kind = match mutbl {
260 hir::Mutability::Mut => BorrowKind::Mut { kind: mir::MutBorrowKind::Default },
261 hir::Mutability::Not => BorrowKind::Shared,
262 };
263 let new_pin_target =
264 Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased, expr.ty, mutbl);
265 let arg = self.thir.exprs.push(expr);
266 let expr = self.thir.exprs.push(Expr {
267 temp_scope_id,
268 ty: new_pin_target,
269 span,
270 kind: ExprKind::Borrow { borrow_kind, arg },
271 });
272
273 let pin_did = self.tcx.require_lang_item(LangItem::Pin, span);
275 let args = self.tcx.mk_args(&[new_pin_target.into()]);
276 let kind = ExprKind::Adt(Box::new(AdtExpr {
277 adt_def: self.tcx.adt_def(pin_did),
278 variant_index: FIRST_VARIANT,
279 args,
280 fields: Box::new([FieldExpr { name: FieldIdx::ZERO, expr }]),
281 user_ty: None,
282 base: AdtExprBase::None,
283 }));
284
285 debug!(?kind);
286 kind
287 }
288 Adjust::GenericReborrow(mutability) => {
289 let expr = self.thir.exprs.push(expr);
290 let kind =
291 ExprKind::Reborrow { source: expr, mutability, target: adjustment.target };
292
293 kind
294 }
295 };
296
297 Expr { temp_scope_id, ty: adjustment.target, span, kind }
298 }
299
300 fn mirror_expr_cast(
304 &mut self,
305 source: &'tcx hir::Expr<'tcx>,
306 temp_scope_id: hir::ItemLocalId,
307 span: Span,
308 ) -> ExprKind<'tcx> {
309 let tcx = self.tcx;
310
311 if self.typeck_results.is_coercion_cast(source.hir_id) {
314 ExprKind::Use { source: self.mirror_expr(source) }
316 } else if self.typeck_results.expr_ty(source).is_ref() {
317 ExprKind::PointerCoercion {
321 source: self.mirror_expr(source),
322 cast: PointerCoercion::ArrayToPointer,
323 is_from_as_cast: true,
324 }
325 } else if let hir::ExprKind::Path(ref qpath) = source.kind
326 && let res = self.typeck_results.qpath_res(qpath, source.hir_id)
327 && let ty = self.typeck_results.node_type(source.hir_id)
328 && let ty::Adt(adt_def, args) = ty.kind()
329 && let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), variant_ctor_id) = res
330 {
331 let idx = adt_def.variant_index_with_ctor_id(variant_ctor_id);
344 let (discr_did, discr_offset) = adt_def.discriminant_def_for_variant(idx);
345
346 use rustc_middle::ty::util::IntTypeExt;
347 let ty = adt_def.repr().discr_type();
348 let discr_ty = ty.to_ty(tcx);
349
350 let size = tcx
351 .layout_of(self.typing_env.as_query_input(discr_ty))
352 .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:?}"))
353 .size;
354
355 let (lit, overflowing) = ScalarInt::truncate_from_uint(discr_offset as u128, size);
356 if overflowing {
357 self.tcx.dcx().span_delayed_bug(
359 source.span,
360 "overflowing enum wasn't rejected by hir analysis",
361 );
362 }
363 let kind = ExprKind::NonHirLiteral { lit, user_ty: None };
364 let offset = self.thir.exprs.push(Expr { temp_scope_id, ty: discr_ty, span, kind });
365
366 let source = match discr_did {
367 Some(did) => {
370 let kind = ExprKind::NamedConst { def_id: did, args, user_ty: None };
371 let lhs =
372 self.thir.exprs.push(Expr { temp_scope_id, ty: discr_ty, span, kind });
373 let bin = ExprKind::Binary { op: BinOp::Add, lhs, rhs: offset };
374 self.thir.exprs.push(Expr { temp_scope_id, ty: discr_ty, span, kind: bin })
375 }
376 None => offset,
377 };
378
379 ExprKind::Cast { source }
380 } else {
381 ExprKind::Cast { source: self.mirror_expr(source) }
384 }
385 }
386
387 x;#[instrument(level = "debug", skip(self), ret)]
388 fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> {
389 let tcx = self.tcx;
390 let expr_ty = self.typeck_results.expr_ty(expr);
391 let mk_expr =
392 |kind, ty| Expr { temp_scope_id: expr.hir_id.local_id, span: expr.span, ty, kind };
393
394 let kind = match expr.kind {
395 hir::ExprKind::MethodCall(segment, receiver, args, fn_span) => {
397 if self.typeck_results.is_splatted_call(expr) {
398 self.convert_splatted_callee(
401 expr,
402 fn_span,
403 args,
404 SplattedFunc::FnDefReceiver(receiver),
405 )
406 } else {
407 let expr = self.method_callee(expr, segment.ident.span, None);
409 info!("Using method span: {:?}", expr.span);
410
411 let args = std::iter::once(receiver)
412 .chain(args.iter())
413 .map(|expr| self.mirror_expr(expr))
414 .collect();
415 ExprKind::Call {
416 ty: expr.ty,
417 fun: self.thir.exprs.push(expr),
418 args,
419 from_hir_call: true,
420 fn_span,
421 }
422 }
423 }
424
425 hir::ExprKind::Call(fun, ref args) => {
426 if self.typeck_results.is_method_call(expr) {
427 let method = self.method_callee(expr, fun.span, None);
435
436 let arg_tys = args.iter().map(|e| self.typeck_results.expr_ty_adjusted(e));
437 let tupled_args = Expr {
438 ty: Ty::new_tup_from_iter(tcx, arg_tys),
439 temp_scope_id: expr.hir_id.local_id,
440 span: expr.span,
441 kind: ExprKind::Tuple { fields: self.mirror_exprs(args) },
442 };
443 let tupled_args = self.thir.exprs.push(tupled_args);
444
445 ExprKind::Call {
446 ty: method.ty,
447 fun: self.thir.exprs.push(method),
448 args: Box::new([self.mirror_expr(fun), tupled_args]),
449 from_hir_call: true,
450 fn_span: expr.span,
451 }
452 } else if self.typeck_results.is_splatted_call(expr) {
453 self.convert_splatted_callee(
456 expr,
457 fun.span,
458 args,
459 SplattedFunc::FnExpression(fun),
460 )
461 } else {
462 let adt_data = if let hir::ExprKind::Path(ref qpath) = fun.kind
464 && let Some(adt_def) = expr_ty.ty_adt_def()
465 {
466 match qpath {
467 hir::QPath::Resolved(_, path) => match path.res {
468 Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_id) => {
469 Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
470 }
471 Res::SelfCtor(..) => Some((adt_def, FIRST_VARIANT)),
472 _ => None,
473 },
474 hir::QPath::TypeRelative(_ty, _) => {
475 if let Some((DefKind::Ctor(_, CtorKind::Fn), ctor_id)) =
476 self.typeck_results.type_dependent_def(fun.hir_id)
477 {
478 Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
479 } else {
480 None
481 }
482 }
483 }
484 } else {
485 None
486 };
487 if let Some((adt_def, index)) = adt_data {
488 let node_args = self.typeck_results.node_args(fun.hir_id);
489 let user_provided_types = self.typeck_results.user_provided_types();
490 let user_ty =
491 user_provided_types.get(fun.hir_id).copied().map(|mut u_ty| {
492 if let ty::UserTypeKind::TypeOf(did, _) = &mut u_ty.value.kind {
493 *did = adt_def.did();
494 }
495 Box::new(u_ty)
496 });
497 debug!("make_mirror_unadjusted: (call) user_ty={:?}", user_ty);
498
499 let field_refs = args
500 .iter()
501 .enumerate()
502 .map(|(idx, e)| FieldExpr {
503 name: FieldIdx::new(idx),
504 expr: self.mirror_expr(e),
505 })
506 .collect();
507 ExprKind::Adt(Box::new(AdtExpr {
508 adt_def,
509 args: node_args,
510 variant_index: index,
511 fields: field_refs,
512 user_ty,
513 base: AdtExprBase::None,
514 }))
515 } else {
516 ExprKind::Call {
517 ty: self.typeck_results.node_type(fun.hir_id),
518 fun: self.mirror_expr(fun),
519 args: self.mirror_exprs(args),
520 from_hir_call: true,
521 fn_span: expr.span,
522 }
523 }
524 }
525 }
526
527 hir::ExprKind::Use(expr, span) => {
528 ExprKind::ByUse { expr: self.mirror_expr(expr), span }
529 }
530
531 hir::ExprKind::AddrOf(hir::BorrowKind::Ref, mutbl, arg) => {
532 ExprKind::Borrow { borrow_kind: mutbl.to_borrow_kind(), arg: self.mirror_expr(arg) }
533 }
534
535 hir::ExprKind::AddrOf(hir::BorrowKind::Raw, mutability, arg) => {
536 ExprKind::RawBorrow { mutability, arg: self.mirror_expr(arg) }
537 }
538
539 hir::ExprKind::AddrOf(hir::BorrowKind::Pin, mutbl, arg_expr) => match expr_ty.kind() {
542 &ty::Adt(adt_def, args) if tcx.is_lang_item(adt_def.did(), LangItem::Pin) => {
543 let ty = args.type_at(0);
544 let arg_ty = self.typeck_results.expr_ty(arg_expr);
545 let mut arg = self.mirror_expr(arg_expr);
546 if mutbl.is_mut() && !arg_ty.is_unpin(self.tcx, self.typing_env) {
549 let block = self.thir.blocks.push(Block {
550 targeted_by_break: false,
551 region_scope: region::Scope {
552 local_id: arg_expr.hir_id.local_id,
553 data: region::ScopeData::Node,
554 },
555 span: arg_expr.span,
556 stmts: Box::new([]),
557 expr: Some(arg),
558 safety_mode: BlockSafety::Safe,
559 });
560 arg = self.thir.exprs.push(Expr {
561 temp_scope_id: arg_expr.hir_id.local_id,
562 ty: arg_ty,
563 span: arg_expr.span,
564 kind: ExprKind::Block { block },
565 });
566 }
567 let expr = self.thir.exprs.push(Expr {
568 temp_scope_id: expr.hir_id.local_id,
569 ty,
570 span: expr.span,
571 kind: ExprKind::Borrow { borrow_kind: mutbl.to_borrow_kind(), arg },
572 });
573 ExprKind::Adt(Box::new(AdtExpr {
574 adt_def,
575 variant_index: FIRST_VARIANT,
576 args,
577 fields: Box::new([FieldExpr { name: FieldIdx::from(0u32), expr }]),
578 user_ty: None,
579 base: AdtExprBase::None,
580 }))
581 }
582 _ => span_bug!(expr.span, "unexpected type for pinned borrow: {:?}", expr_ty),
583 },
584
585 hir::ExprKind::Block(blk, _) => ExprKind::Block { block: self.mirror_block(blk) },
586
587 hir::ExprKind::Assign(lhs, rhs, _) => {
588 ExprKind::Assign { lhs: self.mirror_expr(lhs), rhs: self.mirror_expr(rhs) }
589 }
590
591 hir::ExprKind::AssignOp(op, lhs, rhs) => {
592 if self.typeck_results.is_method_call(expr) {
593 let lhs = self.mirror_expr(lhs);
594 let rhs = self.mirror_expr(rhs);
595 self.overloaded_operator(expr, Box::new([lhs, rhs]))
596 } else {
597 ExprKind::AssignOp {
598 op: assign_op(op.node),
599 lhs: self.mirror_expr(lhs),
600 rhs: self.mirror_expr(rhs),
601 }
602 }
603 }
604
605 hir::ExprKind::Lit(lit) => ExprKind::Literal { lit, neg: false },
606
607 hir::ExprKind::Binary(op, lhs, rhs) => {
608 if self.typeck_results.is_method_call(expr) {
609 let lhs = self.mirror_expr(lhs);
610 let rhs = self.mirror_expr(rhs);
611 self.overloaded_operator(expr, Box::new([lhs, rhs]))
612 } else {
613 match op.node {
614 hir::BinOpKind::And => ExprKind::LogicalOp {
615 op: LogicalOp::And,
616 lhs: self.mirror_expr(lhs),
617 rhs: self.mirror_expr(rhs),
618 },
619 hir::BinOpKind::Or => ExprKind::LogicalOp {
620 op: LogicalOp::Or,
621 lhs: self.mirror_expr(lhs),
622 rhs: self.mirror_expr(rhs),
623 },
624 _ => {
625 let op = bin_op(op.node);
626 ExprKind::Binary {
627 op,
628 lhs: self.mirror_expr(lhs),
629 rhs: self.mirror_expr(rhs),
630 }
631 }
632 }
633 }
634 }
635
636 hir::ExprKind::Index(lhs, index, brackets_span) => {
637 if self.typeck_results.is_method_call(expr) {
638 let lhs = self.mirror_expr(lhs);
639 let index = self.mirror_expr(index);
640 self.overloaded_place(
641 expr,
642 expr_ty,
643 None,
644 Box::new([lhs, index]),
645 brackets_span,
646 )
647 } else {
648 ExprKind::Index { lhs: self.mirror_expr(lhs), index: self.mirror_expr(index) }
649 }
650 }
651
652 hir::ExprKind::Unary(hir::UnOp::Deref, arg) => {
653 if self.typeck_results.is_method_call(expr) {
654 let arg = self.mirror_expr(arg);
655 self.overloaded_place(expr, expr_ty, None, Box::new([arg]), expr.span)
656 } else {
657 ExprKind::Deref { arg: self.mirror_expr(arg) }
658 }
659 }
660
661 hir::ExprKind::Unary(hir::UnOp::Not, arg) => {
662 if self.typeck_results.is_method_call(expr) {
663 let arg = self.mirror_expr(arg);
664 self.overloaded_operator(expr, Box::new([arg]))
665 } else {
666 ExprKind::Unary { op: UnOp::Not, arg: self.mirror_expr(arg) }
667 }
668 }
669
670 hir::ExprKind::Unary(hir::UnOp::Neg, arg) => {
671 if self.typeck_results.is_method_call(expr) {
672 let arg = self.mirror_expr(arg);
673 self.overloaded_operator(expr, Box::new([arg]))
674 } else if let hir::ExprKind::Lit(lit) = arg.kind {
675 ExprKind::Literal { lit, neg: true }
676 } else {
677 ExprKind::Unary { op: UnOp::Neg, arg: self.mirror_expr(arg) }
678 }
679 }
680
681 hir::ExprKind::Struct(qpath, fields, ref base) => match expr_ty.kind() {
682 ty::Adt(adt, args) => match adt.adt_kind() {
683 AdtKind::Struct | AdtKind::Union => {
684 let user_provided_types = self.typeck_results.user_provided_types();
685 let user_ty = user_provided_types.get(expr.hir_id).copied().map(Box::new);
686 debug!("make_mirror_unadjusted: (struct/union) user_ty={:?}", user_ty);
687 ExprKind::Adt(Box::new(AdtExpr {
688 adt_def: *adt,
689 variant_index: FIRST_VARIANT,
690 args,
691 user_ty,
692 fields: self.field_refs(fields),
693 base: match base {
694 hir::StructTailExpr::Base(base) => AdtExprBase::Base(FruInfo {
695 base: self.mirror_expr(base),
696 field_types: self.typeck_results.fru_field_types()[expr.hir_id]
697 .iter()
698 .copied()
699 .collect(),
700 }),
701 hir::StructTailExpr::DefaultFields(_) => {
702 AdtExprBase::DefaultFields(
703 self.typeck_results.fru_field_types()[expr.hir_id]
704 .iter()
705 .copied()
706 .collect(),
707 )
708 }
709 hir::StructTailExpr::None
710 | hir::StructTailExpr::NoneWithError(_) => AdtExprBase::None,
711 },
712 }))
713 }
714 AdtKind::Enum => {
715 let res = self.typeck_results.qpath_res(qpath, expr.hir_id);
716 match res {
717 Res::Def(DefKind::Variant, variant_id) => {
718 assert!(matches!(
719 base,
720 hir::StructTailExpr::None
721 | hir::StructTailExpr::DefaultFields(_)
722 | hir::StructTailExpr::NoneWithError(_)
723 ));
724
725 let index = adt.variant_index_with_id(variant_id);
726 let user_provided_types = self.typeck_results.user_provided_types();
727 let user_ty =
728 user_provided_types.get(expr.hir_id).copied().map(Box::new);
729 debug!("make_mirror_unadjusted: (variant) user_ty={:?}", user_ty);
730 ExprKind::Adt(Box::new(AdtExpr {
731 adt_def: *adt,
732 variant_index: index,
733 args,
734 user_ty,
735 fields: self.field_refs(fields),
736 base: match base {
737 hir::StructTailExpr::DefaultFields(_) => {
738 AdtExprBase::DefaultFields(
739 self.typeck_results.fru_field_types()[expr.hir_id]
740 .iter()
741 .copied()
742 .collect(),
743 )
744 }
745 hir::StructTailExpr::Base(base) => {
746 span_bug!(base.span, "unexpected res: {:?}", res);
747 }
748 hir::StructTailExpr::None
749 | hir::StructTailExpr::NoneWithError(_) => {
750 AdtExprBase::None
751 }
752 },
753 }))
754 }
755 _ => {
756 span_bug!(expr.span, "unexpected res: {:?}", res);
757 }
758 }
759 }
760 },
761 _ => {
762 span_bug!(expr.span, "unexpected type for struct literal: {:?}", expr_ty);
763 }
764 },
765
766 hir::ExprKind::Closure(hir::Closure { .. }) => {
767 let closure_ty = self.typeck_results.expr_ty(expr);
768 let (def_id, args, movability) = match *closure_ty.kind() {
769 ty::Closure(def_id, args) => (def_id, UpvarArgs::Closure(args), None),
770 ty::Coroutine(def_id, args) => {
771 (def_id, UpvarArgs::Coroutine(args), Some(tcx.coroutine_movability(def_id)))
772 }
773 ty::CoroutineClosure(def_id, args) => {
774 (def_id, UpvarArgs::CoroutineClosure(args), None)
775 }
776 _ => {
777 span_bug!(expr.span, "closure expr w/o closure type: {:?}", closure_ty);
778 }
779 };
780 let def_id = def_id.expect_local();
781
782 let upvars = self
783 .tcx
784 .closure_captures(def_id)
785 .iter()
786 .zip_eq(args.upvar_tys())
787 .map(|(captured_place, ty)| {
788 let upvars = self.capture_upvar(expr, captured_place, ty);
789 self.thir.exprs.push(upvars)
790 })
791 .collect();
792
793 let fake_reads = match self.typeck_results.closure_fake_reads.get(&def_id) {
795 Some(fake_reads) => fake_reads
796 .iter()
797 .map(|(place, cause, hir_id)| {
798 let expr = self.convert_captured_hir_place(expr, place.clone());
799 (self.thir.exprs.push(expr), *cause, *hir_id)
800 })
801 .collect(),
802 None => Vec::new(),
803 };
804
805 ExprKind::Closure(Box::new(ClosureExpr {
806 closure_id: def_id,
807 args,
808 upvars,
809 movability,
810 fake_reads,
811 }))
812 }
813
814 hir::ExprKind::Path(ref qpath) => {
815 let res = self.typeck_results.qpath_res(qpath, expr.hir_id);
816 self.convert_path_expr(expr, res)
817 }
818
819 hir::ExprKind::InlineAsm(asm) => ExprKind::InlineAsm(Box::new(InlineAsmExpr {
820 asm_macro: asm.asm_macro,
821 template: asm.template,
822 operands: asm
823 .operands
824 .iter()
825 .map(|(op, _op_sp)| match *op {
826 hir::InlineAsmOperand::In { reg, expr } => {
827 InlineAsmOperand::In { reg, expr: self.mirror_expr(expr) }
828 }
829 hir::InlineAsmOperand::Out { reg, late, ref expr } => {
830 InlineAsmOperand::Out {
831 reg,
832 late,
833 expr: expr.map(|expr| self.mirror_expr(expr)),
834 }
835 }
836 hir::InlineAsmOperand::InOut { reg, late, expr } => {
837 InlineAsmOperand::InOut { reg, late, expr: self.mirror_expr(expr) }
838 }
839 hir::InlineAsmOperand::SplitInOut { reg, late, in_expr, ref out_expr } => {
840 InlineAsmOperand::SplitInOut {
841 reg,
842 late,
843 in_expr: self.mirror_expr(in_expr),
844 out_expr: out_expr.map(|expr| self.mirror_expr(expr)),
845 }
846 }
847 hir::InlineAsmOperand::Const { ref anon_const } => {
848 let ty = self.typeck_results.node_type(anon_const.hir_id);
849 let did = anon_const.def_id;
850 let typeck_root_def_id = tcx.typeck_root_def_id_local(did);
851 let parent_args = tcx.erase_and_anonymize_regions(
852 GenericArgs::identity_for_item(tcx, typeck_root_def_id),
853 );
854 let args =
855 InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty })
856 .args;
857
858 let uneval = mir::UnevaluatedConst::new(did.to_def_id(), args);
859 let value = mir::Const::Unevaluated(uneval, ty);
860 InlineAsmOperand::Const { value, span: tcx.def_span(did) }
861 }
862 hir::InlineAsmOperand::SymFn { expr } => {
863 InlineAsmOperand::SymFn { value: self.mirror_expr(expr) }
864 }
865 hir::InlineAsmOperand::SymStatic { path: _, def_id } => {
866 InlineAsmOperand::SymStatic { def_id }
867 }
868 hir::InlineAsmOperand::Label { block } => {
869 InlineAsmOperand::Label { block: self.mirror_block(block) }
870 }
871 })
872 .collect(),
873 options: asm.options,
874 line_spans: asm.line_spans,
875 })),
876
877 hir::ExprKind::OffsetOf(_, _) => {
878 let offset_of_intrinsic = tcx.require_lang_item(LangItem::OffsetOf, expr.span);
879 let mk_u32_kind = |val: u32| ExprKind::NonHirLiteral {
880 lit: ScalarInt::try_from_uint(val, Size::from_bits(32)).unwrap(),
881 user_ty: None,
882 };
883 let mk_usize_kind = |val: u64| ExprKind::NonHirLiteral {
884 lit: ScalarInt::try_from_target_usize(val, tcx).unwrap(),
885 user_ty: None,
886 };
887 let mk_call =
888 |thir: &mut Thir<'tcx>, ty: Ty<'tcx>, variant: VariantIdx, field: FieldIdx| {
889 let fun_ty = tcx
890 .type_of(offset_of_intrinsic)
891 .instantiate(tcx, &[ty.into()])
892 .skip_norm_wip();
893 let fun = thir
894 .exprs
895 .push(mk_expr(ExprKind::ZstLiteral { user_ty: None }, fun_ty));
896 let variant =
897 thir.exprs.push(mk_expr(mk_u32_kind(variant.as_u32()), tcx.types.u32));
898 let field =
899 thir.exprs.push(mk_expr(mk_u32_kind(field.as_u32()), tcx.types.u32));
900 let args = Box::new([variant, field]);
901 ExprKind::Call {
902 ty: fun_ty,
903 fun,
904 args,
905 from_hir_call: false,
906 fn_span: expr.span,
907 }
908 };
909
910 let indices = self.typeck_results.offset_of_data().get(expr.hir_id).unwrap();
911 let mut expr = None::<ExprKind<'_>>;
912
913 for &(container, variant, field) in indices.iter() {
914 let next = mk_call(&mut self.thir, container, variant, field);
915 expr = Some(match expr.take() {
916 None => next,
917 Some(last) => {
918 let last = self.thir.exprs.push(mk_expr(last, tcx.types.usize));
919 let next = self.thir.exprs.push(mk_expr(next, tcx.types.usize));
920 ExprKind::Binary { op: BinOp::Add, lhs: last, rhs: next }
921 }
922 });
923 }
924
925 expr.unwrap_or_else(|| mk_usize_kind(0))
926 }
927
928 hir::ExprKind::ConstBlock(ref anon_const) => {
929 let ty = self.typeck_results.node_type(anon_const.hir_id);
930 let did = anon_const.def_id;
931 let typeck_root_def_id = tcx.typeck_root_def_id_local(did);
932 let parent_args = tcx.erase_and_anonymize_regions(GenericArgs::identity_for_item(
933 tcx,
934 typeck_root_def_id,
935 ));
936 let args = InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty }).args;
937
938 ExprKind::ConstBlock { did: did.to_def_id(), args }
939 }
940 hir::ExprKind::Repeat(v, _) => {
942 let ty = self.typeck_results.expr_ty(expr);
943 let ty::Array(_, count) = ty.kind() else {
944 span_bug!(expr.span, "unexpected repeat expr ty: {:?}", ty);
945 };
946
947 ExprKind::Repeat { value: self.mirror_expr(v), count: *count }
948 }
949 hir::ExprKind::Ret(v) => ExprKind::Return { value: v.map(|v| self.mirror_expr(v)) },
950 hir::ExprKind::Become(call) => ExprKind::Become { value: self.mirror_expr(call) },
951 hir::ExprKind::Break(dest, ref value) => {
952 if find_attr!(self.tcx, expr.hir_id, ConstContinue(_)) {
953 match dest.target_id {
954 Ok(target_id) => {
955 let (Some(value), Some(_)) = (value, dest.label) else {
956 let span = expr.span;
957 self.tcx.dcx().emit_fatal(ConstContinueMissingLabelOrValue { span })
958 };
959
960 ExprKind::ConstContinue {
961 label: region::Scope {
962 local_id: target_id.local_id,
963 data: region::ScopeData::Node,
964 },
965 value: self.mirror_expr(value),
966 }
967 }
968 Err(err) => bug!("invalid loop id for break: {}", err),
969 }
970 } else {
971 match dest.target_id {
972 Ok(target_id) => ExprKind::Break {
973 label: region::Scope {
974 local_id: target_id.local_id,
975 data: region::ScopeData::Node,
976 },
977 value: value.map(|value| self.mirror_expr(value)),
978 },
979 Err(err) => bug!("invalid loop id for break: {}", err),
980 }
981 }
982 }
983 hir::ExprKind::Continue(dest) => match dest.target_id {
984 Ok(loop_id) => ExprKind::Continue {
985 label: region::Scope {
986 local_id: loop_id.local_id,
987 data: region::ScopeData::Node,
988 },
989 },
990 Err(err) => bug!("invalid loop id for continue: {}", err),
991 },
992 hir::ExprKind::Let(let_expr) => ExprKind::Let {
993 expr: self.mirror_expr(let_expr.init),
994 pat: self.pattern_from_hir(let_expr.pat),
995 },
996 hir::ExprKind::If(cond, then, else_opt) => ExprKind::If {
997 if_then_scope: region::Scope {
998 local_id: then.hir_id.local_id,
999 data: {
1000 if expr.span.at_least_rust_2024() {
1001 region::ScopeData::IfThenRescope
1002 } else {
1003 region::ScopeData::IfThen
1004 }
1005 },
1006 },
1007 cond: self.mirror_expr(cond),
1008 then: self.mirror_expr(then),
1009 else_opt: else_opt.map(|el| self.mirror_expr(el)),
1010 },
1011 hir::ExprKind::Match(discr, arms, match_source) => ExprKind::Match {
1012 scrutinee: self.mirror_expr(discr),
1013 arms: arms.iter().map(|a| self.convert_arm(a)).collect(),
1014 match_source,
1015 },
1016 hir::ExprKind::Loop(body, ..) => {
1017 if find_attr!(self.tcx, expr.hir_id, LoopMatch(_)) {
1018 let dcx = self.tcx.dcx();
1019
1020 let loop_body_expr = match body.stmts {
1022 [] => match body.expr {
1023 Some(expr) => expr,
1024 None => dcx.emit_fatal(LoopMatchMissingAssignment { span: body.span }),
1025 },
1026 [single] if body.expr.is_none() => match single.kind {
1027 hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr) => expr,
1028 _ => dcx.emit_fatal(LoopMatchMissingAssignment { span: body.span }),
1029 },
1030 [first @ last] | [first, .., last] => dcx
1031 .emit_fatal(LoopMatchBadStatements { span: first.span.to(last.span) }),
1032 };
1033
1034 let hir::ExprKind::Assign(state, rhs_expr, _) = loop_body_expr.kind else {
1035 dcx.emit_fatal(LoopMatchMissingAssignment { span: loop_body_expr.span })
1036 };
1037
1038 let hir::ExprKind::Block(block_body, _) = rhs_expr.kind else {
1039 dcx.emit_fatal(LoopMatchBadRhs { span: rhs_expr.span })
1040 };
1041
1042 for stmt in block_body.stmts {
1045 if !matches!(stmt.kind, rustc_hir::StmtKind::Item(_)) {
1046 dcx.emit_fatal(LoopMatchBadStatements { span: stmt.span })
1047 }
1048 }
1049
1050 let Some(block_body_expr) = block_body.expr else {
1051 dcx.emit_fatal(LoopMatchBadRhs { span: block_body.span })
1052 };
1053
1054 let hir::ExprKind::Match(scrutinee, arms, _match_source) = block_body_expr.kind
1055 else {
1056 dcx.emit_fatal(LoopMatchBadRhs { span: block_body_expr.span })
1057 };
1058
1059 fn local(
1060 cx: &mut ThirBuildCx<'_>,
1061 expr: &rustc_hir::Expr<'_>,
1062 ) -> Option<hir::HirId> {
1063 if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = expr.kind
1064 && let Res::Local(hir_id) = path.res
1065 && !cx.is_upvar(hir_id)
1066 {
1067 return Some(hir_id);
1068 }
1069
1070 None
1071 }
1072
1073 let Some(scrutinee_hir_id) = local(self, scrutinee) else {
1074 dcx.emit_fatal(LoopMatchInvalidMatch { span: scrutinee.span })
1075 };
1076
1077 if local(self, state) != Some(scrutinee_hir_id) {
1078 dcx.emit_fatal(LoopMatchInvalidUpdate {
1079 scrutinee: scrutinee.span,
1080 lhs: state.span,
1081 })
1082 }
1083
1084 ExprKind::LoopMatch {
1085 state: self.mirror_expr(state),
1086 region_scope: region::Scope {
1087 local_id: block_body.hir_id.local_id,
1088 data: region::ScopeData::Node,
1089 },
1090
1091 match_data: Box::new(LoopMatchMatchData {
1092 scrutinee: self.mirror_expr(scrutinee),
1093 arms: arms.iter().map(|a| self.convert_arm(a)).collect(),
1094 span: block_body_expr.span,
1095 }),
1096 }
1097 } else {
1098 let block_ty = self.typeck_results.node_type(body.hir_id);
1099 let block = self.mirror_block(body);
1100 let body = self.thir.exprs.push(Expr {
1101 ty: block_ty,
1102 temp_scope_id: body.hir_id.local_id,
1103 span: self.thir[block].span,
1104 kind: ExprKind::Block { block },
1105 });
1106 ExprKind::Loop { body }
1107 }
1108 }
1109 hir::ExprKind::Field(source, ..) => ExprKind::Field {
1110 lhs: self.mirror_expr(source),
1111 variant_index: FIRST_VARIANT,
1112 name: self.typeck_results.field_index(expr.hir_id),
1113 },
1114 hir::ExprKind::Cast(source, cast_ty) => {
1115 let user_provided_types = self.typeck_results.user_provided_types();
1117 let user_ty = user_provided_types.get(cast_ty.hir_id);
1118
1119 debug!(
1120 "cast({:?}) has ty w/ hir_id {:?} and user provided ty {:?}",
1121 expr, cast_ty.hir_id, user_ty,
1122 );
1123
1124 let cast = self.mirror_expr_cast(source, expr.hir_id.local_id, expr.span);
1125
1126 if let Some(user_ty) = user_ty {
1127 let cast_expr = self.thir.exprs.push(Expr {
1130 temp_scope_id: expr.hir_id.local_id,
1131 ty: expr_ty,
1132 span: expr.span,
1133 kind: cast,
1134 });
1135 debug!("make_mirror_unadjusted: (cast) user_ty={:?}", user_ty);
1136
1137 ExprKind::ValueTypeAscription {
1138 source: cast_expr,
1139 user_ty: Some(Box::new(*user_ty)),
1140 user_ty_span: cast_ty.span,
1141 }
1142 } else {
1143 cast
1144 }
1145 }
1146 hir::ExprKind::Type(source, ty) => {
1147 let user_provided_types = self.typeck_results.user_provided_types();
1148 let user_ty = user_provided_types.get(ty.hir_id).copied().map(Box::new);
1149 debug!("make_mirror_unadjusted: (type) user_ty={:?}", user_ty);
1150 let mirrored = self.mirror_expr(source);
1151 if source.is_syntactic_place_expr() {
1152 ExprKind::PlaceTypeAscription {
1153 source: mirrored,
1154 user_ty,
1155 user_ty_span: ty.span,
1156 }
1157 } else {
1158 ExprKind::ValueTypeAscription {
1159 source: mirrored,
1160 user_ty,
1161 user_ty_span: ty.span,
1162 }
1163 }
1164 }
1165
1166 hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Unwrap, source, _ty) => {
1167 let mirrored = self.mirror_expr(source);
1169 if source.is_syntactic_place_expr() {
1170 ExprKind::PlaceUnwrapUnsafeBinder { source: mirrored }
1171 } else {
1172 ExprKind::ValueUnwrapUnsafeBinder { source: mirrored }
1173 }
1174 }
1175 hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Wrap, source, _ty) => {
1176 let mirrored = self.mirror_expr(source);
1178 ExprKind::WrapUnsafeBinder { source: mirrored }
1179 }
1180
1181 hir::ExprKind::DropTemps(source) => ExprKind::Use { source: self.mirror_expr(source) },
1182 hir::ExprKind::Array(fields) => ExprKind::Array { fields: self.mirror_exprs(fields) },
1183 hir::ExprKind::Tup(fields) => ExprKind::Tuple { fields: self.mirror_exprs(fields) },
1184
1185 hir::ExprKind::Yield(v, _) => ExprKind::Yield { value: self.mirror_expr(v) },
1186 hir::ExprKind::Err(_) => unreachable!("cannot lower a `hir::ExprKind::Err` to THIR"),
1187 };
1188
1189 mk_expr(kind, expr_ty)
1190 }
1191
1192 fn user_args_applied_to_res(
1193 &mut self,
1194 hir_id: hir::HirId,
1195 res: Res,
1196 ) -> Option<Box<ty::CanonicalUserType<'tcx>>> {
1197 {
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:1197",
"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(1197u32),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("user_args_applied_to_res: res={0:?}",
res) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("user_args_applied_to_res: res={:?}", res);
1198 let user_provided_type = match res {
1199 Res::Def(DefKind::Fn, _)
1203 | Res::Def(DefKind::AssocFn, _)
1204 | Res::Def(DefKind::Ctor(_, CtorKind::Fn), _)
1205 | Res::Def(DefKind::Const { .. }, _)
1206 | Res::Def(DefKind::AssocConst { .. }, _) => {
1207 self.typeck_results.user_provided_types().get(hir_id).copied().map(Box::new)
1208 }
1209
1210 Res::Def(DefKind::Ctor(_, CtorKind::Const), _) => {
1215 self.user_args_applied_to_ty_of_hir_id(hir_id).map(Box::new)
1216 }
1217
1218 Res::SelfCtor(_) => self.user_args_applied_to_ty_of_hir_id(hir_id).map(Box::new),
1220
1221 _ => ::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),
1222 };
1223 {
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:1223",
"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(1223u32),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("user_args_applied_to_res: user_provided_type={0:?}",
user_provided_type) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("user_args_applied_to_res: user_provided_type={:?}", user_provided_type);
1224 user_provided_type
1225 }
1226
1227 fn method_callee(
1228 &mut self,
1229 expr: &hir::Expr<'_>,
1230 span: Span,
1231 overloaded_callee: Option<Ty<'tcx>>,
1232 ) -> Expr<'tcx> {
1233 let (ty, user_ty) = match overloaded_callee {
1234 Some(fn_def) => (fn_def, None),
1235 None => {
1236 let (kind, def_id) =
1237 self.typeck_results.type_dependent_def(expr.hir_id).unwrap_or_else(|| {
1238 ::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")
1239 });
1240 let user_ty = self.user_args_applied_to_res(expr.hir_id, Res::Def(kind, def_id));
1241 {
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:1241",
"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(1241u32),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("method_callee: user_ty={0:?}",
user_ty) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("method_callee: user_ty={:?}", user_ty);
1242 (
1243 self.tcx
1244 .type_of(def_id)
1245 .instantiate(self.tcx, self.typeck_results.node_args(expr.hir_id))
1246 .skip_norm_wip(),
1247 user_ty,
1248 )
1249 }
1250 };
1251 Expr {
1252 temp_scope_id: expr.hir_id.local_id,
1253 ty,
1254 span,
1255 kind: ExprKind::ZstLiteral { user_ty },
1256 }
1257 }
1258
1259 fn convert_splatted_callee(
1263 &mut self,
1264 call_expr: &'tcx hir::Expr<'_>,
1265 fn_span: Span,
1266 args: &'tcx [hir::Expr<'tcx>],
1267 receiver_or_func: SplattedFunc<'tcx>,
1268 ) -> ExprKind<'tcx> {
1269 let tcx = self.tcx;
1270
1271 let splatted_def =
1273 self.typeck_results.splatted_def(call_expr.hir_id).unwrap_or_else(|| {
1274 ::rustc_middle::util::bug::span_bug_fmt(call_expr.span,
format_args!("no splatted def for function or method callee"))span_bug!(call_expr.span, "no splatted def for function or method callee")
1275 });
1276
1277 let tupled_arg_index = usize::from(splatted_def.arg_index());
1278 let tupled_args_count = usize::from(splatted_def.arg_count());
1279
1280 if tupled_arg_index + tupled_args_count > args.len() {
1283 ::rustc_middle::util::bug::span_bug_fmt(call_expr.span,
format_args!("splatted arg index out of bounds of function args: {0:?} + {1:?} > {2:?} for function call: {3:?}, args {4:?}",
tupled_arg_index, tupled_args_count, args.len(), receiver_or_func,
args));span_bug!(
1284 call_expr.span,
1285 "splatted arg index out of bounds of function args: {:?} + {:?} > {:?} for function call: {:?}, args {:?}",
1286 tupled_arg_index,
1287 tupled_args_count,
1288 args.len(),
1289 receiver_or_func,
1290 args,
1291 );
1292 }
1293
1294 {
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:1294",
"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(1294u32),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("Using splatted function span: {0:?}",
fn_span) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("Using splatted function span: {:?}", fn_span);
1295
1296 let initial_non_tupled_args =
1298 args.iter().take(tupled_arg_index).map(|e| self.mirror_expr(e)).collect_vec();
1299 let tupled_args = if tupled_arg_index == args.len() || tupled_args_count == 0 {
1300 Default::default()
1302 } else {
1303 &args[tupled_arg_index..(tupled_arg_index + tupled_args_count)]
1304 };
1305 let final_non_tupled_args = args
1306 .iter()
1307 .skip(tupled_arg_index + tupled_args_count)
1308 .map(|e| self.mirror_expr(e))
1309 .collect_vec();
1310
1311 let tupled_arg_tys = tupled_args.iter().map(|e| self.typeck_results.expr_ty_adjusted(e));
1312
1313 let tupled_args = Expr {
1316 ty: Ty::new_tup_from_iter(tcx, tupled_arg_tys),
1317 temp_scope_id: call_expr.hir_id.local_id,
1318 span: call_expr.span,
1319 kind: ExprKind::Tuple { fields: self.mirror_exprs(tupled_args) },
1320 };
1321
1322 let tupled_args = self.thir.exprs.push(tupled_args);
1323
1324 let mut args = Vec::with_capacity(
1326 usize::from(receiver_or_func.has_receiver())
1327 + initial_non_tupled_args.len()
1328 + 1
1329 + final_non_tupled_args.len(),
1330 );
1331 if let Some(receiver) = receiver_or_func.receiver() {
1332 args.push(self.mirror_expr(receiver));
1333 }
1334 args.extend(initial_non_tupled_args);
1335 args.push(tupled_args);
1336 args.extend(final_non_tupled_args);
1337
1338 let fn_span = if receiver_or_func.has_receiver() { fn_span } else { call_expr.span };
1339
1340 let (fn_ty, fun_expr) = match (splatted_def, receiver_or_func.fn_expression()) {
1341 (SplattedDef::FnDef { def_id, arg_index, arg_count }, _) => {
1343 let def_kind = self.tcx.def_kind(def_id);
1347 let user_ty =
1348 self.user_args_applied_to_res(call_expr.hir_id, Res::Def(def_kind, def_id));
1349 {
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:1349",
"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(1349u32),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("splatted_callee FnDef: user_ty={0:?} def_kind={1:?} def_id={2:?} arg_index={3:?} arg_count={4:?}",
user_ty, def_kind, def_id, arg_index, arg_count) as
&dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(
1350 "splatted_callee FnDef: user_ty={:?} def_kind={:?} def_id={:?} arg_index={:?} arg_count={:?}",
1351 user_ty, def_kind, def_id, arg_index, arg_count,
1352 );
1353
1354 let callee_expr = Expr {
1356 temp_scope_id: call_expr.hir_id.local_id,
1357 ty: self
1358 .tcx
1359 .type_of(def_id)
1360 .instantiate(self.tcx, self.typeck_results.node_args(call_expr.hir_id))
1361 .skip_norm_wip(),
1362 span: fn_span,
1363 kind: ExprKind::ZstLiteral { user_ty },
1364 };
1365 (callee_expr.ty, self.thir.exprs.push(callee_expr))
1366 }
1367
1368 (SplattedDef::FnPtr { fn_ptr_type, arg_index, arg_count }, Some(fn_expression)) => {
1371 {
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:1371",
"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(1371u32),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("splatted_callee FnPtr: fn_ty={0:?} arg_index={1:?} arg_count={2:?}",
fn_ptr_type, arg_index, arg_count) as
&dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(
1372 "splatted_callee FnPtr: fn_ty={:?} arg_index={:?} arg_count={:?}",
1373 fn_ptr_type, arg_index, arg_count,
1374 );
1375
1376 if !fn_ptr_type.is_fn() {
1377 ::rustc_middle::util::bug::span_bug_fmt(call_expr.span,
format_args!("splatted FnPtr side-tables were not populated correctly, non-fn type received: {0:?}",
fn_ptr_type))span_bug!(
1378 call_expr.span,
1379 "splatted FnPtr side-tables were not populated correctly, non-fn type received: {:?}",
1380 fn_ptr_type
1381 )
1382 }
1383
1384 (fn_ptr_type, self.mirror_expr(fn_expression))
1386 }
1387 (SplattedDef::FnPtr { .. }, None) => {
1389 ::rustc_middle::util::bug::span_bug_fmt(call_expr.span,
format_args!("convert_splatted_callee: FnPtr without fn expression (or with receiver) is invalid: splatted_def={0:?}, receiver_or_func={1:?}",
splatted_def, receiver_or_func));span_bug!(
1390 call_expr.span,
1391 "convert_splatted_callee: FnPtr without fn expression (or with receiver) is invalid: splatted_def={:?}, receiver_or_func={:?}",
1392 splatted_def,
1393 receiver_or_func,
1394 );
1395 }
1396 };
1397
1398 ExprKind::Call {
1399 ty: fn_ty,
1400 fun: fun_expr,
1401 args: args.into_boxed_slice(),
1402 from_hir_call: true,
1403 fn_span,
1404 }
1405 }
1406
1407 fn convert_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) -> ArmId {
1408 let arm = Arm {
1409 pattern: self.pattern_from_hir(&arm.pat),
1410 guard: arm.guard.as_ref().map(|g| self.mirror_expr(g)),
1411 body: self.mirror_expr(arm.body),
1412 hir_id: arm.hir_id,
1413 scope: region::Scope { local_id: arm.hir_id.local_id, data: region::ScopeData::Node },
1414 span: arm.span,
1415 };
1416 self.thir.arms.push(arm)
1417 }
1418
1419 fn convert_path_expr(&mut self, expr: &'tcx hir::Expr<'tcx>, res: Res) -> ExprKind<'tcx> {
1420 let args = self.typeck_results.node_args(expr.hir_id);
1421 match res {
1422 Res::Def(DefKind::Fn, _)
1424 | Res::Def(DefKind::AssocFn, _)
1425 | Res::Def(DefKind::Ctor(_, CtorKind::Fn), _)
1426 | Res::SelfCtor(_) => {
1427 let user_ty = self.user_args_applied_to_res(expr.hir_id, res);
1428 ExprKind::ZstLiteral { user_ty }
1429 }
1430
1431 Res::Def(DefKind::ConstParam, def_id) => {
1432 let hir_id = self.tcx.local_def_id_to_hir_id(def_id.expect_local());
1433 let generics = self.tcx.generics_of(hir_id.owner);
1434 let Some(&index) = generics.param_def_id_to_index.get(&def_id) else {
1435 ::rustc_middle::util::bug::span_bug_fmt(expr.span,
format_args!("Should have already errored about late bound consts: {0:?}",
def_id));span_bug!(
1436 expr.span,
1437 "Should have already errored about late bound consts: {def_id:?}"
1438 );
1439 };
1440 let name = self.tcx.hir_name(hir_id);
1441 let param = ty::ParamConst::new(index, name);
1442
1443 ExprKind::ConstParam { param, def_id }
1444 }
1445
1446 Res::Def(DefKind::Const { .. }, def_id)
1447 | Res::Def(DefKind::AssocConst { .. }, def_id) => {
1448 let user_ty = self.user_args_applied_to_res(expr.hir_id, res);
1449 ExprKind::NamedConst { def_id, args, user_ty }
1450 }
1451
1452 Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id) => {
1453 let user_provided_types = self.typeck_results.user_provided_types();
1454 let user_ty = user_provided_types.get(expr.hir_id).copied().map(Box::new);
1455 {
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:1455",
"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(1455u32),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("convert_path_expr: user_ty={0:?}",
user_ty) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("convert_path_expr: user_ty={:?}", user_ty);
1456 let ty = self.typeck_results.node_type(expr.hir_id);
1457 match ty.kind() {
1458 ty::Adt(adt_def, args) => ExprKind::Adt(Box::new(AdtExpr {
1461 adt_def: *adt_def,
1462 variant_index: adt_def.variant_index_with_ctor_id(def_id),
1463 args,
1464 user_ty,
1465 fields: Box::new([]),
1466 base: AdtExprBase::None,
1467 })),
1468 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected ty: {0:?}", ty))bug!("unexpected ty: {:?}", ty),
1469 }
1470 }
1471
1472 Res::Def(DefKind::Static { .. }, id) => {
1476 let ty = self.tcx.static_ptr_ty(id, self.typing_env);
1478 let kind = if self.tcx.is_thread_local_static(id) {
1479 ExprKind::ThreadLocalRef(id)
1480 } else {
1481 let alloc_id = self.tcx.reserve_and_set_static_alloc(id);
1482 ExprKind::StaticRef { alloc_id, ty, def_id: id }
1483 };
1484 ExprKind::Deref {
1485 arg: self.thir.exprs.push(Expr {
1486 ty,
1487 temp_scope_id: expr.hir_id.local_id,
1488 span: expr.span,
1489 kind,
1490 }),
1491 }
1492 }
1493
1494 Res::Local(var_hir_id) => self.convert_var(var_hir_id),
1495
1496 _ => ::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),
1497 }
1498 }
1499
1500 fn convert_var(&mut self, var_hir_id: hir::HirId) -> ExprKind<'tcx> {
1501 let is_upvar = self.is_upvar(var_hir_id);
1504
1505 {
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:1505",
"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(1505u32),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::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 ::tracing::field::Value))])
});
} else { ; }
};debug!(
1506 "convert_var({:?}): is_upvar={}, body_owner={:?}",
1507 var_hir_id, is_upvar, self.body_owner
1508 );
1509
1510 if is_upvar {
1511 ExprKind::UpvarRef {
1512 closure_def_id: self.body_owner,
1513 var_hir_id: LocalVarId(var_hir_id),
1514 }
1515 } else {
1516 ExprKind::VarRef { id: LocalVarId(var_hir_id) }
1517 }
1518 }
1519
1520 fn overloaded_operator(
1521 &mut self,
1522 expr: &'tcx hir::Expr<'tcx>,
1523 args: Box<[ExprId]>,
1524 ) -> ExprKind<'tcx> {
1525 let fun = self.method_callee(expr, expr.span, None);
1526 let fun = self.thir.exprs.push(fun);
1527 ExprKind::Call {
1528 ty: self.thir[fun].ty,
1529 fun,
1530 args,
1531 from_hir_call: false,
1532 fn_span: expr.span,
1533 }
1534 }
1535
1536 fn overloaded_place(
1537 &mut self,
1538 expr: &'tcx hir::Expr<'tcx>,
1539 place_ty: Ty<'tcx>,
1540 overloaded_callee: Option<Ty<'tcx>>,
1541 args: Box<[ExprId]>,
1542 span: Span,
1543 ) -> ExprKind<'tcx> {
1544 let ty::Ref(region, _, mutbl) = *self.thir[args[0]].ty.kind() else {
1552 ::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");
1553 };
1554 let ref_ty = Ty::new_ref(self.tcx, region, place_ty, mutbl);
1555
1556 let fun = self.method_callee(expr, span, overloaded_callee);
1559 let fun = self.thir.exprs.push(fun);
1560 let fun_ty = self.thir[fun].ty;
1561 let ref_expr = self.thir.exprs.push(Expr {
1562 temp_scope_id: expr.hir_id.local_id,
1563 ty: ref_ty,
1564 span,
1565 kind: ExprKind::Call { ty: fun_ty, fun, args, from_hir_call: false, fn_span: span },
1566 });
1567
1568 ExprKind::Deref { arg: ref_expr }
1570 }
1571
1572 fn convert_captured_hir_place(
1573 &mut self,
1574 closure_expr: &'tcx hir::Expr<'tcx>,
1575 place: HirPlace<'tcx>,
1576 ) -> Expr<'tcx> {
1577 let temp_scope_id = closure_expr.hir_id.local_id;
1578 let var_ty = place.base_ty;
1579
1580 let var_hir_id = match place.base {
1586 HirPlaceBase::Upvar(upvar_id) => upvar_id.var_path.hir_id,
1587 base => ::rustc_middle::util::bug::bug_fmt(format_args!("Expected an upvar, found {0:?}",
base))bug!("Expected an upvar, found {:?}", base),
1588 };
1589
1590 let mut captured_place_expr = Expr {
1591 temp_scope_id,
1592 ty: var_ty,
1593 span: closure_expr.span,
1594 kind: self.convert_var(var_hir_id),
1595 };
1596
1597 for proj in place.projections.iter() {
1598 let kind = match proj.kind {
1599 HirProjectionKind::Deref => {
1600 ExprKind::Deref { arg: self.thir.exprs.push(captured_place_expr) }
1601 }
1602 HirProjectionKind::Field(field, variant_index) => ExprKind::Field {
1603 lhs: self.thir.exprs.push(captured_place_expr),
1604 variant_index,
1605 name: field,
1606 },
1607 HirProjectionKind::OpaqueCast => {
1608 ExprKind::Use { source: self.thir.exprs.push(captured_place_expr) }
1609 }
1610 HirProjectionKind::UnwrapUnsafeBinder => ExprKind::PlaceUnwrapUnsafeBinder {
1611 source: self.thir.exprs.push(captured_place_expr),
1612 },
1613 HirProjectionKind::Index | HirProjectionKind::Subslice => {
1614 continue;
1616 }
1617 };
1618
1619 captured_place_expr =
1620 Expr { temp_scope_id, ty: proj.ty, span: closure_expr.span, kind };
1621 }
1622
1623 captured_place_expr
1624 }
1625
1626 fn capture_upvar(
1627 &mut self,
1628 closure_expr: &'tcx hir::Expr<'tcx>,
1629 captured_place: &'tcx ty::CapturedPlace<'tcx>,
1630 upvar_ty: Ty<'tcx>,
1631 ) -> Expr<'tcx> {
1632 let upvar_capture = captured_place.info.capture_kind;
1633 let captured_place_expr =
1634 self.convert_captured_hir_place(closure_expr, captured_place.place.clone());
1635 let temp_scope_id = closure_expr.hir_id.local_id;
1636
1637 match upvar_capture {
1638 ty::UpvarCapture::ByValue => captured_place_expr,
1639 ty::UpvarCapture::ByUse => {
1640 let span = captured_place_expr.span;
1641 let expr_id = self.thir.exprs.push(captured_place_expr);
1642
1643 Expr {
1644 temp_scope_id,
1645 ty: upvar_ty,
1646 span: closure_expr.span,
1647 kind: ExprKind::ByUse { expr: expr_id, span },
1648 }
1649 }
1650 ty::UpvarCapture::ByRef(upvar_borrow) => {
1651 let borrow_kind = match upvar_borrow {
1652 ty::BorrowKind::Immutable => BorrowKind::Shared,
1653 ty::BorrowKind::UniqueImmutable => {
1654 BorrowKind::Mut { kind: mir::MutBorrowKind::ClosureCapture }
1655 }
1656 ty::BorrowKind::Mutable => {
1657 BorrowKind::Mut { kind: mir::MutBorrowKind::Default }
1658 }
1659 };
1660 Expr {
1661 temp_scope_id,
1662 ty: upvar_ty,
1663 span: closure_expr.span,
1664 kind: ExprKind::Borrow {
1665 borrow_kind,
1666 arg: self.thir.exprs.push(captured_place_expr),
1667 },
1668 }
1669 }
1670 }
1671 }
1672
1673 fn is_upvar(&mut self, var_hir_id: hir::HirId) -> bool {
1674 self.tcx
1675 .upvars_mentioned(self.body_owner)
1676 .is_some_and(|upvars| upvars.contains_key(&var_hir_id))
1677 }
1678
1679 fn field_refs(&mut self, fields: &'tcx [hir::ExprField<'tcx>]) -> Box<[FieldExpr]> {
1681 fields
1682 .iter()
1683 .map(|field| FieldExpr {
1684 name: self.typeck_results.field_index(field.hir_id),
1685 expr: self.mirror_expr(field.expr),
1686 })
1687 .collect()
1688 }
1689}
1690
1691trait ToBorrowKind {
1692 fn to_borrow_kind(&self) -> BorrowKind;
1693}
1694
1695impl ToBorrowKind for AutoBorrowMutability {
1696 fn to_borrow_kind(&self) -> BorrowKind {
1697 use rustc_middle::ty::adjustment::AllowTwoPhase;
1698 match *self {
1699 AutoBorrowMutability::Mut { allow_two_phase_borrow } => BorrowKind::Mut {
1700 kind: match allow_two_phase_borrow {
1701 AllowTwoPhase::Yes => mir::MutBorrowKind::TwoPhaseBorrow,
1702 AllowTwoPhase::No => mir::MutBorrowKind::Default,
1703 },
1704 },
1705 AutoBorrowMutability::Not => BorrowKind::Shared,
1706 }
1707 }
1708}
1709
1710impl ToBorrowKind for hir::Mutability {
1711 fn to_borrow_kind(&self) -> BorrowKind {
1712 match *self {
1713 hir::Mutability::Mut => BorrowKind::Mut { kind: mir::MutBorrowKind::Default },
1714 hir::Mutability::Not => BorrowKind::Shared,
1715 }
1716 }
1717}
1718
1719fn bin_op(op: hir::BinOpKind) -> BinOp {
1720 match op {
1721 hir::BinOpKind::Add => BinOp::Add,
1722 hir::BinOpKind::Sub => BinOp::Sub,
1723 hir::BinOpKind::Mul => BinOp::Mul,
1724 hir::BinOpKind::Div => BinOp::Div,
1725 hir::BinOpKind::Rem => BinOp::Rem,
1726 hir::BinOpKind::BitXor => BinOp::BitXor,
1727 hir::BinOpKind::BitAnd => BinOp::BitAnd,
1728 hir::BinOpKind::BitOr => BinOp::BitOr,
1729 hir::BinOpKind::Shl => BinOp::Shl,
1730 hir::BinOpKind::Shr => BinOp::Shr,
1731 hir::BinOpKind::Eq => BinOp::Eq,
1732 hir::BinOpKind::Lt => BinOp::Lt,
1733 hir::BinOpKind::Le => BinOp::Le,
1734 hir::BinOpKind::Ne => BinOp::Ne,
1735 hir::BinOpKind::Ge => BinOp::Ge,
1736 hir::BinOpKind::Gt => BinOp::Gt,
1737 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("no equivalent for ast binop {0:?}",
op))bug!("no equivalent for ast binop {:?}", op),
1738 }
1739}
1740
1741fn assign_op(op: hir::AssignOpKind) -> AssignOp {
1742 match op {
1743 hir::AssignOpKind::AddAssign => AssignOp::AddAssign,
1744 hir::AssignOpKind::SubAssign => AssignOp::SubAssign,
1745 hir::AssignOpKind::MulAssign => AssignOp::MulAssign,
1746 hir::AssignOpKind::DivAssign => AssignOp::DivAssign,
1747 hir::AssignOpKind::RemAssign => AssignOp::RemAssign,
1748 hir::AssignOpKind::BitXorAssign => AssignOp::BitXorAssign,
1749 hir::AssignOpKind::BitAndAssign => AssignOp::BitAndAssign,
1750 hir::AssignOpKind::BitOrAssign => AssignOp::BitOrAssign,
1751 hir::AssignOpKind::ShlAssign => AssignOp::ShlAssign,
1752 hir::AssignOpKind::ShrAssign => AssignOp::ShrAssign,
1753 }
1754}