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