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