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