1use rustc_ast as ast;
2use rustc_errors::Applicability;
3use rustc_hir as hir;
4use rustc_hir_analysis::autoderef::Autoderef;
5use rustc_infer::infer::InferOk;
6use rustc_infer::traits::{Obligation, ObligationCauseCode};
7use rustc_middle::span_bug;
8use rustc_middle::ty::adjustment::{
9 Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, DerefAdjustKind,
10 OverloadedDeref, PointerCoercion,
11};
12use rustc_middle::ty::{self, Ty};
13use rustc_span::{Span, sym};
14use tracing::debug;
15
16use crate::method::{MethodCallee, TreatNotYetDefinedOpaques};
17use crate::{FnCtxt, PlaceOp};
18
19impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20 pub(super) fn lookup_derefing(
22 &self,
23 expr: &hir::Expr<'_>,
24 oprnd_expr: &'tcx hir::Expr<'tcx>,
25 oprnd_ty: Ty<'tcx>,
26 ) -> Option<Ty<'tcx>> {
27 if let Some(ty) = oprnd_ty.builtin_deref(true) {
28 return Some(ty);
29 }
30
31 let ok = self.try_overloaded_deref(expr.span, oprnd_ty)?;
32 let method = self.register_infer_ok_obligations(ok);
33 if let ty::Ref(_, _, hir::Mutability::Not) = method.sig.inputs()[0].kind() {
34 self.apply_adjustments(
35 oprnd_expr,
36 ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[Adjustment {
kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)),
target: method.sig.inputs()[0],
}]))vec![Adjustment {
37 kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)),
38 target: method.sig.inputs()[0],
39 }],
40 );
41 } else {
42 ::rustc_middle::util::bug::span_bug_fmt(expr.span,
format_args!("input to deref is not a ref?"));span_bug!(expr.span, "input to deref is not a ref?");
43 }
44 let ty = self.make_overloaded_place_return_type(method);
45 self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method);
46 Some(ty)
47 }
48
49 pub(super) fn lookup_indexing(
51 &self,
52 expr: &hir::Expr<'_>,
53 base_expr: &'tcx hir::Expr<'tcx>,
54 base_ty: Ty<'tcx>,
55 index_expr: &'tcx hir::Expr<'tcx>,
56 idx_ty: Ty<'tcx>,
57 ) -> Option<(Ty<'tcx>, Ty<'tcx>)> {
58 let mut autoderef = self.autoderef(base_expr.span, base_ty);
63 let mut result = None;
64 while result.is_none() && autoderef.next().is_some() {
65 result = self.try_index_step(expr, base_expr, &autoderef, idx_ty, index_expr);
66 }
67 self.register_predicates(autoderef.into_obligations());
68 result
69 }
70
71 fn negative_index(
72 &self,
73 ty: Ty<'tcx>,
74 span: Span,
75 base_expr: &hir::Expr<'_>,
76 ) -> Option<(Ty<'tcx>, Ty<'tcx>)> {
77 let ty = self.resolve_vars_if_possible(ty);
78 let mut err = self.dcx().struct_span_err(
79 span,
80 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("negative integers cannot be used to index on a `{0}`",
ty))
})format!("negative integers cannot be used to index on a `{ty}`"),
81 );
82 err.span_label(span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("cannot use a negative integer for indexing on `{0}`",
ty))
})format!("cannot use a negative integer for indexing on `{ty}`"));
83 if let (hir::ExprKind::Path(..), Ok(snippet)) =
84 (&base_expr.kind, self.tcx.sess.source_map().span_to_snippet(base_expr.span))
85 {
86 err.span_suggestion_verbose(
88 span.shrink_to_lo(),
89 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("to access an element starting from the end of the `{0}`, compute the index",
ty))
})format!(
90 "to access an element starting from the end of the `{ty}`, compute the index",
91 ),
92 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}.len() ", snippet))
})format!("{snippet}.len() "),
93 Applicability::MachineApplicable,
94 );
95 }
96 let reported = err.emit();
97 Some((Ty::new_error(self.tcx, reported), Ty::new_error(self.tcx, reported)))
98 }
99
100 fn try_index_step(
106 &self,
107 expr: &hir::Expr<'_>,
108 base_expr: &hir::Expr<'_>,
109 autoderef: &Autoderef<'a, 'tcx>,
110 index_ty: Ty<'tcx>,
111 index_expr: &hir::Expr<'_>,
112 ) -> Option<(Ty<'tcx>, Ty<'tcx>)> {
113 let adjusted_ty = self.structurally_resolve_type(autoderef.span(), autoderef.final_ty());
114 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/place_op.rs:114",
"rustc_hir_typeck::place_op", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/place_op.rs"),
::tracing_core::__macro_support::Option::Some(114u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::place_op"),
::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!("try_index_step(expr={0:?}, base_expr={1:?}, adjusted_ty={2:?}, index_ty={3:?})",
expr, base_expr, adjusted_ty, index_ty) as &dyn Value))])
});
} else { ; }
};debug!(
115 "try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
116 index_ty={:?})",
117 expr, base_expr, adjusted_ty, index_ty
118 );
119
120 if let hir::ExprKind::Unary(
121 hir::UnOp::Neg,
122 hir::Expr {
123 kind: hir::ExprKind::Lit(hir::Lit { node: ast::LitKind::Int(..), .. }),
124 ..
125 },
126 ) = index_expr.kind
127 {
128 match adjusted_ty.kind() {
129 ty::Adt(def, _) if self.tcx.is_diagnostic_item(sym::Vec, def.did()) => {
130 return self.negative_index(adjusted_ty, index_expr.span, base_expr);
131 }
132 ty::Slice(_) | ty::Array(_, _) => {
133 return self.negative_index(adjusted_ty, index_expr.span, base_expr);
134 }
135 _ => {}
136 }
137 }
138
139 for unsize in [false, true] {
140 let mut self_ty = adjusted_ty;
141 if unsize {
142 if let ty::Array(element_ty, ct) = *adjusted_ty.kind() {
144 self.register_predicate(Obligation::new(
145 self.tcx,
146 self.cause(base_expr.span, ObligationCauseCode::ArrayLen(adjusted_ty)),
147 self.param_env,
148 ty::ClauseKind::ConstArgHasType(ct, self.tcx.types.usize),
149 ));
150 self_ty = Ty::new_slice(self.tcx, element_ty);
151 } else {
152 continue;
153 }
154 }
155
156 let input_ty = self.next_ty_var(base_expr.span);
160 let method =
161 self.try_overloaded_place_op(expr.span, self_ty, Some(input_ty), PlaceOp::Index);
162
163 if let Some(result) = method {
164 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/place_op.rs:164",
"rustc_hir_typeck::place_op", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/place_op.rs"),
::tracing_core::__macro_support::Option::Some(164u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::place_op"),
::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!("try_index_step: success, using overloaded indexing")
as &dyn Value))])
});
} else { ; }
};debug!("try_index_step: success, using overloaded indexing");
165 let method = self.register_infer_ok_obligations(result);
166
167 let mut adjustments = self.adjust_steps(autoderef);
168 if let ty::Ref(region, _, hir::Mutability::Not) = method.sig.inputs()[0].kind() {
169 adjustments.push(Adjustment {
170 kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)),
171 target: Ty::new_imm_ref(self.tcx, *region, adjusted_ty),
172 });
173 } else {
174 ::rustc_middle::util::bug::span_bug_fmt(expr.span,
format_args!("input to index is not a ref?"));span_bug!(expr.span, "input to index is not a ref?");
175 }
176 if unsize {
177 adjustments.push(Adjustment {
178 kind: Adjust::Pointer(PointerCoercion::Unsize),
179 target: method.sig.inputs()[0],
180 });
181 }
182 self.apply_adjustments(base_expr, adjustments);
183
184 self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method);
185
186 return Some((input_ty, self.make_overloaded_place_return_type(method)));
187 }
188 }
189
190 None
191 }
192
193 pub(super) fn try_overloaded_place_op(
198 &self,
199 span: Span,
200 base_ty: Ty<'tcx>,
201 opt_rhs_ty: Option<Ty<'tcx>>,
202 op: PlaceOp,
203 ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
204 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/place_op.rs:204",
"rustc_hir_typeck::place_op", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/place_op.rs"),
::tracing_core::__macro_support::Option::Some(204u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::place_op"),
::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!("try_overloaded_place_op({0:?},{1:?},{2:?})",
span, base_ty, op) as &dyn Value))])
});
} else { ; }
};debug!("try_overloaded_place_op({:?},{:?},{:?})", span, base_ty, op);
205
206 let (Some(imm_tr), imm_op) = (match op {
207 PlaceOp::Deref => (self.tcx.lang_items().deref_trait(), sym::deref),
208 PlaceOp::Index => (self.tcx.lang_items().index_trait(), sym::index),
209 }) else {
210 return None;
212 };
213
214 let treat_opaques = TreatNotYetDefinedOpaques::AsInfer;
217 self.lookup_method_for_operator(
218 self.misc(span),
219 imm_op,
220 imm_tr,
221 base_ty,
222 opt_rhs_ty,
223 treat_opaques,
224 )
225 }
226
227 fn try_mutable_overloaded_place_op(
228 &self,
229 span: Span,
230 base_ty: Ty<'tcx>,
231 opt_rhs_ty: Option<Ty<'tcx>>,
232 op: PlaceOp,
233 ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
234 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/place_op.rs:234",
"rustc_hir_typeck::place_op", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/place_op.rs"),
::tracing_core::__macro_support::Option::Some(234u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::place_op"),
::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!("try_mutable_overloaded_place_op({0:?},{1:?},{2:?})",
span, base_ty, op) as &dyn Value))])
});
} else { ; }
};debug!("try_mutable_overloaded_place_op({:?},{:?},{:?})", span, base_ty, op);
235
236 let (Some(mut_tr), mut_op) = (match op {
237 PlaceOp::Deref => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
238 PlaceOp::Index => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
239 }) else {
240 return None;
242 };
243
244 let treat_opaques = TreatNotYetDefinedOpaques::AsInfer;
249 self.lookup_method_for_operator(
250 self.misc(span),
251 mut_op,
252 mut_tr,
253 base_ty,
254 opt_rhs_ty,
255 treat_opaques,
256 )
257 }
258
259 pub(crate) fn convert_place_derefs_to_mutable(&self, expr: &hir::Expr<'_>) {
267 let mut exprs = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[expr]))vec![expr];
269
270 while let hir::ExprKind::Field(expr, _)
271 | hir::ExprKind::Index(expr, _, _)
272 | hir::ExprKind::Unary(hir::UnOp::Deref, expr) = exprs.last().unwrap().kind
273 {
274 exprs.push(expr);
275 }
276
277 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/place_op.rs:277",
"rustc_hir_typeck::place_op", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/place_op.rs"),
::tracing_core::__macro_support::Option::Some(277u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::place_op"),
::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_place_derefs_to_mutable: exprs={0:?}",
exprs) as &dyn Value))])
});
} else { ; }
};debug!("convert_place_derefs_to_mutable: exprs={:?}", exprs);
278
279 let mut inside_union = false;
281 for (i, &expr) in exprs.iter().rev().enumerate() {
282 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/place_op.rs:282",
"rustc_hir_typeck::place_op", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/place_op.rs"),
::tracing_core::__macro_support::Option::Some(282u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::place_op"),
::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_place_derefs_to_mutable: i={0} expr={1:?}",
i, expr) as &dyn Value))])
});
} else { ; }
};debug!("convert_place_derefs_to_mutable: i={} expr={:?}", i, expr);
283
284 let mut source = self.node_ty(expr.hir_id);
285 if #[allow(non_exhaustive_omitted_patterns)] match expr.kind {
hir::ExprKind::Unary(hir::UnOp::Deref, _) => true,
_ => false,
}matches!(expr.kind, hir::ExprKind::Unary(hir::UnOp::Deref, _)) {
286 inside_union = false;
288 }
289 if source.is_union() {
290 inside_union = true;
291 }
292 let previous_adjustments =
299 self.typeck_results.borrow_mut().adjustments_mut().remove(expr.hir_id);
300 if let Some(mut adjustments) = previous_adjustments {
301 for adjustment in &mut adjustments {
302 if let Adjust::Deref(DerefAdjustKind::Overloaded(ref mut deref)) =
303 adjustment.kind
304 && let Some(ok) = self.try_mutable_overloaded_place_op(
305 expr.span,
306 source,
307 None,
308 PlaceOp::Deref,
309 )
310 {
311 let method = self.register_infer_ok_obligations(ok);
312 let ty::Ref(_, _, mutbl) = *method.sig.output().kind() else {
313 ::rustc_middle::util::bug::span_bug_fmt(self.tcx.def_span(method.def_id),
format_args!("expected DerefMut to return a &mut"));span_bug!(
314 self.tcx.def_span(method.def_id),
315 "expected DerefMut to return a &mut"
316 );
317 };
318 *deref = OverloadedDeref { mutbl, span: deref.span };
319 self.enforce_context_effects(None, expr.span, method.def_id, method.args);
320 if inside_union
323 && source.ty_adt_def().is_some_and(|adt| adt.is_manually_drop())
324 {
325 self.dcx().struct_span_err(
326 expr.span,
327 "not automatically applying `DerefMut` on `ManuallyDrop` union field",
328 )
329 .with_help(
330 "writing to this reference calls the destructor for the old value",
331 )
332 .with_help("add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor")
333 .emit();
334 }
335 }
336 source = adjustment.target;
337 }
338 self.typeck_results.borrow_mut().adjustments_mut().insert(expr.hir_id, adjustments);
339 }
340
341 match expr.kind {
342 hir::ExprKind::Index(base_expr, ..) => {
343 self.convert_place_op_to_mutable(PlaceOp::Index, expr, base_expr);
344 }
345 hir::ExprKind::Unary(hir::UnOp::Deref, base_expr) => {
346 self.convert_place_op_to_mutable(PlaceOp::Deref, expr, base_expr);
347 }
348 _ => {}
349 }
350 }
351 }
352
353 fn convert_place_op_to_mutable(
354 &self,
355 op: PlaceOp,
356 expr: &hir::Expr<'_>,
357 base_expr: &hir::Expr<'_>,
358 ) {
359 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/place_op.rs:359",
"rustc_hir_typeck::place_op", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/place_op.rs"),
::tracing_core::__macro_support::Option::Some(359u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::place_op"),
::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_place_op_to_mutable({0:?}, {1:?}, {2:?})",
op, expr, base_expr) as &dyn Value))])
});
} else { ; }
};debug!("convert_place_op_to_mutable({:?}, {:?}, {:?})", op, expr, base_expr);
360 if !self.typeck_results.borrow().is_method_call(expr) {
361 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/place_op.rs:361",
"rustc_hir_typeck::place_op", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/place_op.rs"),
::tracing_core::__macro_support::Option::Some(361u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::place_op"),
::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_place_op_to_mutable - builtin, nothing to do")
as &dyn Value))])
});
} else { ; }
};debug!("convert_place_op_to_mutable - builtin, nothing to do");
362 return;
363 }
364
365 let base_ty = self
367 .typeck_results
368 .borrow()
369 .expr_ty_adjusted(base_expr)
370 .builtin_deref(false)
371 .expect("place op takes something that is not a ref");
372
373 let arg_ty = match op {
374 PlaceOp::Deref => None,
375 PlaceOp::Index => {
376 Some(self.typeck_results.borrow().node_args(expr.hir_id).type_at(1))
385 }
386 };
387 let method = self.try_mutable_overloaded_place_op(expr.span, base_ty, arg_ty, op);
388 let method = match method {
389 Some(ok) => self.register_infer_ok_obligations(ok),
390 None => return,
393 };
394 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/place_op.rs:394",
"rustc_hir_typeck::place_op", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/place_op.rs"),
::tracing_core::__macro_support::Option::Some(394u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::place_op"),
::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_place_op_to_mutable: method={0:?}",
method) as &dyn Value))])
});
} else { ; }
};debug!("convert_place_op_to_mutable: method={:?}", method);
395 self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method);
396
397 let ty::Ref(region, _, hir::Mutability::Mut) = method.sig.inputs()[0].kind() else {
398 ::rustc_middle::util::bug::span_bug_fmt(expr.span,
format_args!("input to mutable place op is not a mut ref?"));span_bug!(expr.span, "input to mutable place op is not a mut ref?");
399 };
400
401 let base_expr_ty = self.node_ty(base_expr.hir_id);
404 if let Some(adjustments) =
405 self.typeck_results.borrow_mut().adjustments_mut().get_mut(base_expr.hir_id)
406 {
407 let mut source = base_expr_ty;
408 for adjustment in &mut adjustments[..] {
409 if let Adjust::Borrow(AutoBorrow::Ref(..)) = adjustment.kind {
410 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/place_op.rs:410",
"rustc_hir_typeck::place_op", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/place_op.rs"),
::tracing_core::__macro_support::Option::Some(410u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::place_op"),
::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_place_op_to_mutable: converting autoref {0:?}",
adjustment) as &dyn Value))])
});
} else { ; }
};debug!("convert_place_op_to_mutable: converting autoref {:?}", adjustment);
411 let mutbl = AutoBorrowMutability::Mut {
412 allow_two_phase_borrow: AllowTwoPhase::No,
417 };
418 adjustment.kind = Adjust::Borrow(AutoBorrow::Ref(mutbl));
419 adjustment.target = Ty::new_ref(self.tcx, *region, source, mutbl.into());
420 }
421 source = adjustment.target;
422 }
423
424 if let [
426 ..,
427 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
428 Adjustment { kind: Adjust::Pointer(PointerCoercion::Unsize), ref mut target },
429 ] = adjustments[..]
430 {
431 *target = method.sig.inputs()[0];
432 }
433 }
434 }
435}