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