1#![allow(internal_features)]
5#![feature(default_field_values)]
6#![feature(deref_patterns)]
7#![feature(file_buffered)]
8#![feature(negative_impls)]
9#![feature(never_type)]
10#![feature(rustc_attrs)]
11#![feature(stmt_expr_attributes)]
12#![feature(try_blocks)]
13use std::borrow::Cow;
16use std::cell::{OnceCell, RefCell};
17use std::marker::PhantomData;
18use std::ops::{ControlFlow, Deref};
19use std::rc::Rc;
20
21use borrow_set::LocalsStateAtExit;
22use polonius_engine::AllFacts;
23use root_cx::BorrowCheckRootCtxt;
24use rustc_abi::FieldIdx;
25use rustc_data_structures::frozen::Frozen;
26use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
27use rustc_data_structures::graph::dominators::Dominators;
28use rustc_hir as hir;
29use rustc_hir::CRATE_HIR_ID;
30use rustc_hir::def_id::LocalDefId;
31use rustc_index::bit_set::MixedBitSet;
32use rustc_index::{IndexSlice, IndexVec};
33use rustc_infer::infer::outlives::env::RegionBoundPairs;
34use rustc_infer::infer::{
35 InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt,
36};
37use rustc_middle::mir::*;
38use rustc_middle::query::Providers;
39use rustc_middle::ty::{
40 self, ParamEnv, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitable, TypingMode, fold_regions,
41};
42use rustc_middle::{bug, span_bug};
43use rustc_mir_dataflow::impls::{EverInitializedPlaces, MaybeUninitializedPlaces};
44use rustc_mir_dataflow::move_paths::{
45 InitIndex, InitLocation, LookupResult, MoveData, MovePathIndex,
46};
47use rustc_mir_dataflow::points::DenseLocationMap;
48use rustc_mir_dataflow::{Analysis, EntryStates, Results, ResultsVisitor, visit_results};
49use rustc_session::lint::builtin::{TAIL_EXPR_DROP_ORDER, UNUSED_MUT};
50use rustc_span::{ErrorGuaranteed, Span, Symbol};
51use rustc_trait_selection::traits::query::type_op::{QueryTypeOp, TypeOp, TypeOpOutput};
52use smallvec::SmallVec;
53use tracing::{debug, instrument};
54
55use crate::borrow_set::{BorrowData, BorrowSet};
56use crate::consumers::{BodyWithBorrowckFacts, RustcFacts};
57use crate::dataflow::{BorrowIndex, Borrowck, BorrowckDomain, Borrows};
58use crate::diagnostics::{
59 AccessKind, BorrowckDiagnosticsBuffer, IllegalMoveOriginKind, MoveError, RegionName,
60};
61use crate::path_utils::*;
62use crate::place_ext::PlaceExt;
63use crate::places_conflict::{PlaceConflictBias, places_conflict};
64use crate::polonius::PoloniusContext;
65use crate::polonius::legacy::{
66 PoloniusFacts, PoloniusFactsExt, PoloniusLocationTable, PoloniusOutput,
67};
68use crate::prefixes::PrefixSet;
69use crate::region_infer::RegionInferenceContext;
70use crate::region_infer::opaque_types::DeferredOpaqueTypeError;
71use crate::renumber::RegionCtxt;
72use crate::session_diagnostics::VarNeedNotMut;
73use crate::type_check::free_region_relations::UniversalRegionRelations;
74use crate::type_check::{Locations, MirTypeckRegionConstraints, MirTypeckResults};
75
76mod borrow_set;
77mod borrowck_errors;
78mod constraints;
79mod dataflow;
80mod def_use;
81mod diagnostics;
82mod handle_placeholders;
83mod nll;
84mod path_utils;
85mod place_ext;
86mod places_conflict;
87mod polonius;
88mod prefixes;
89mod region_infer;
90mod renumber;
91mod root_cx;
92mod session_diagnostics;
93mod type_check;
94mod universal_regions;
95mod used_muts;
96
97pub mod consumers;
99
100struct TyCtxtConsts<'tcx>(PhantomData<&'tcx ()>);
102
103impl<'tcx> TyCtxtConsts<'tcx> {
104 const DEREF_PROJECTION: &'tcx [PlaceElem<'tcx>; 1] = &[ProjectionElem::Deref];
105}
106
107pub fn provide(providers: &mut Providers) {
108 *providers = Providers { mir_borrowck, ..*providers };
109}
110
111fn mir_borrowck(
115 tcx: TyCtxt<'_>,
116 def: LocalDefId,
117) -> Result<&FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'_>>, ErrorGuaranteed> {
118 if !!tcx.is_typeck_child(def.to_def_id()) {
::core::panicking::panic("assertion failed: !tcx.is_typeck_child(def.to_def_id())")
};assert!(!tcx.is_typeck_child(def.to_def_id()));
119 if tcx.is_trivial_const(def) {
120 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:120",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(120u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("Skipping borrowck because of trivial const")
as &dyn Value))])
});
} else { ; }
};debug!("Skipping borrowck because of trivial const");
121 let opaque_types = Default::default();
122 return Ok(tcx.arena.alloc(opaque_types));
123 }
124 let (input_body, _) = tcx.mir_promoted(def);
125 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:125",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(125u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("run query mir_borrowck: {0}",
tcx.def_path_str(def)) as &dyn Value))])
});
} else { ; }
};debug!("run query mir_borrowck: {}", tcx.def_path_str(def));
126
127 tcx.ensure_result().check_coroutine_obligations(def)?;
131
132 let input_body: &Body<'_> = &input_body.borrow();
133 if let Some(guar) = input_body.tainted_by_errors {
134 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:134",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(134u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("Skipping borrowck because of tainted body")
as &dyn Value))])
});
} else { ; }
};debug!("Skipping borrowck because of tainted body");
135 Err(guar)
136 } else if input_body.should_skip() {
137 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:137",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(137u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("Skipping borrowck because of injected body")
as &dyn Value))])
});
} else { ; }
};debug!("Skipping borrowck because of injected body");
138 let opaque_types = Default::default();
139 Ok(tcx.arena.alloc(opaque_types))
140 } else {
141 let mut root_cx = BorrowCheckRootCtxt::new(tcx, def, None);
142 root_cx.do_mir_borrowck();
143 root_cx.finalize()
144 }
145}
146
147#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for PropagatedBorrowCheckResults<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"PropagatedBorrowCheckResults", "closure_requirements",
&self.closure_requirements, "used_mut_upvars",
&&self.used_mut_upvars)
}
}Debug)]
150struct PropagatedBorrowCheckResults<'tcx> {
151 closure_requirements: Option<ClosureRegionRequirements<'tcx>>,
152 used_mut_upvars: SmallVec<[FieldIdx; 8]>,
153}
154
155type DeferredClosureRequirements<'tcx> = Vec<(LocalDefId, ty::GenericArgsRef<'tcx>, Locations)>;
156
157#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for ClosureRegionRequirements<'tcx> {
#[inline]
fn clone(&self) -> ClosureRegionRequirements<'tcx> {
ClosureRegionRequirements {
num_external_vids: ::core::clone::Clone::clone(&self.num_external_vids),
outlives_requirements: ::core::clone::Clone::clone(&self.outlives_requirements),
}
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for ClosureRegionRequirements<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"ClosureRegionRequirements", "num_external_vids",
&self.num_external_vids, "outlives_requirements",
&&self.outlives_requirements)
}
}Debug)]
200pub struct ClosureRegionRequirements<'tcx> {
201 pub num_external_vids: usize,
207
208 pub outlives_requirements: Vec<ClosureOutlivesRequirement<'tcx>>,
211}
212
213#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for ClosureOutlivesRequirement<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for ClosureOutlivesRequirement<'tcx> {
#[inline]
fn clone(&self) -> ClosureOutlivesRequirement<'tcx> {
let _:
::core::clone::AssertParamIsClone<ClosureOutlivesSubject<'tcx>>;
let _: ::core::clone::AssertParamIsClone<ty::RegionVid>;
let _: ::core::clone::AssertParamIsClone<Span>;
let _: ::core::clone::AssertParamIsClone<ConstraintCategory<'tcx>>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for ClosureOutlivesRequirement<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field4_finish(f,
"ClosureOutlivesRequirement", "subject", &self.subject,
"outlived_free_region", &self.outlived_free_region, "blame_span",
&self.blame_span, "category", &&self.category)
}
}Debug)]
216pub struct ClosureOutlivesRequirement<'tcx> {
217 pub subject: ClosureOutlivesSubject<'tcx>,
219
220 pub outlived_free_region: ty::RegionVid,
222
223 pub blame_span: Span,
225
226 pub category: ConstraintCategory<'tcx>,
228}
229
230#[cfg(target_pointer_width = "64")]
232const _: [(); 16] = [(); ::std::mem::size_of::<ConstraintCategory<'_>>()];rustc_data_structures::static_assert_size!(ConstraintCategory<'_>, 16);
233
234#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for ClosureOutlivesSubject<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for ClosureOutlivesSubject<'tcx> {
#[inline]
fn clone(&self) -> ClosureOutlivesSubject<'tcx> {
let _:
::core::clone::AssertParamIsClone<ClosureOutlivesSubjectTy<'tcx>>;
let _: ::core::clone::AssertParamIsClone<ty::RegionVid>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for ClosureOutlivesSubject<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ClosureOutlivesSubject::Ty(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Ty",
&__self_0),
ClosureOutlivesSubject::Region(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Region",
&__self_0),
}
}
}Debug)]
237pub enum ClosureOutlivesSubject<'tcx> {
238 Ty(ClosureOutlivesSubjectTy<'tcx>),
242
243 Region(ty::RegionVid),
246}
247
248#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for ClosureOutlivesSubjectTy<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for ClosureOutlivesSubjectTy<'tcx> {
#[inline]
fn clone(&self) -> ClosureOutlivesSubjectTy<'tcx> {
let _: ::core::clone::AssertParamIsClone<Ty<'tcx>>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for ClosureOutlivesSubjectTy<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"ClosureOutlivesSubjectTy", "inner", &&self.inner)
}
}Debug)]
254pub struct ClosureOutlivesSubjectTy<'tcx> {
255 inner: Ty<'tcx>,
256}
257impl<'tcx, I> !TypeVisitable<I> for ClosureOutlivesSubjectTy<'tcx> {}
260impl<'tcx, I> !TypeFoldable<I> for ClosureOutlivesSubjectTy<'tcx> {}
261
262impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
263 pub fn bind(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self {
266 let inner = fold_regions(tcx, ty, |r, depth| match r.kind() {
267 ty::ReVar(vid) => {
268 let br = ty::BoundRegion {
269 var: ty::BoundVar::from_usize(vid.index()),
270 kind: ty::BoundRegionKind::Anon,
271 };
272 ty::Region::new_bound(tcx, depth, br)
273 }
274 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected region in ClosureOutlivesSubjectTy: {0:?}",
r))bug!("unexpected region in ClosureOutlivesSubjectTy: {r:?}"),
275 });
276
277 Self { inner }
278 }
279
280 pub fn instantiate(
281 self,
282 tcx: TyCtxt<'tcx>,
283 mut map: impl FnMut(ty::RegionVid) -> ty::Region<'tcx>,
284 ) -> Ty<'tcx> {
285 fold_regions(tcx, self.inner, |r, depth| match r.kind() {
286 ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), br) => {
287 if true {
{
match (&debruijn, &depth) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};
};debug_assert_eq!(debruijn, depth);
288 map(ty::RegionVid::from_usize(br.var.index()))
289 }
290 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected region {0:?}", r))bug!("unexpected region {r:?}"),
291 })
292 }
293}
294
295struct CollectRegionConstraintsResult<'tcx> {
296 infcx: BorrowckInferCtxt<'tcx>,
297 body_owned: Body<'tcx>,
298 promoted: IndexVec<Promoted, Body<'tcx>>,
299 move_data: MoveData<'tcx>,
300 borrow_set: BorrowSet<'tcx>,
301 location_table: PoloniusLocationTable,
302 location_map: Rc<DenseLocationMap>,
303 universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
304 region_bound_pairs: Frozen<RegionBoundPairs<'tcx>>,
305 known_type_outlives_obligations: Frozen<Vec<ty::PolyTypeOutlivesPredicate<'tcx>>>,
306 constraints: MirTypeckRegionConstraints<'tcx>,
307 deferred_closure_requirements: DeferredClosureRequirements<'tcx>,
308 deferred_opaque_type_errors: Vec<DeferredOpaqueTypeError<'tcx>>,
309 polonius_facts: Option<AllFacts<RustcFacts>>,
310 polonius_context: Option<PoloniusContext>,
311}
312
313fn borrowck_collect_region_constraints<'tcx>(
317 root_cx: &mut BorrowCheckRootCtxt<'tcx>,
318 def: LocalDefId,
319) -> CollectRegionConstraintsResult<'tcx> {
320 let tcx = root_cx.tcx;
321 let infcx = BorrowckInferCtxt::new(tcx, def, root_cx.root_def_id());
322 let (input_body, promoted) = tcx.mir_promoted(def);
323 let input_body: &Body<'_> = &input_body.borrow();
324 let input_promoted: &IndexSlice<_, _> = &promoted.borrow();
325 if let Some(e) = input_body.tainted_by_errors {
326 infcx.set_tainted_by_errors(e);
327 }
328
329 let mut body_owned = input_body.clone();
334 let mut promoted = input_promoted.to_owned();
335 let universal_regions = nll::replace_regions_in_mir(&infcx, &mut body_owned, &mut promoted);
336 let body = &body_owned; let location_table = PoloniusLocationTable::new(body);
339
340 let move_data = MoveData::gather_moves(body, tcx, |_| true);
341
342 let locals_are_invalidated_at_exit = tcx.hir_body_owner_kind(def).is_fn_or_closure();
343 let borrow_set = BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &move_data);
344
345 let location_map = Rc::new(DenseLocationMap::new(body));
346
347 let polonius_input = root_cx.consumer.as_ref().map_or(false, |c| c.polonius_input())
348 || infcx.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled();
349 let mut polonius_facts =
350 (polonius_input || PoloniusFacts::enabled(infcx.tcx)).then_some(PoloniusFacts::default());
351
352 let MirTypeckResults {
354 constraints,
355 universal_region_relations,
356 region_bound_pairs,
357 known_type_outlives_obligations,
358 deferred_closure_requirements,
359 polonius_context,
360 } = type_check::type_check(
361 root_cx,
362 &infcx,
363 body,
364 &promoted,
365 universal_regions,
366 &location_table,
367 &borrow_set,
368 &mut polonius_facts,
369 &move_data,
370 Rc::clone(&location_map),
371 );
372
373 CollectRegionConstraintsResult {
374 infcx,
375 body_owned,
376 promoted,
377 move_data,
378 borrow_set,
379 location_table,
380 location_map,
381 universal_region_relations,
382 region_bound_pairs,
383 known_type_outlives_obligations,
384 constraints,
385 deferred_closure_requirements,
386 deferred_opaque_type_errors: Default::default(),
387 polonius_facts,
388 polonius_context,
389 }
390}
391
392fn borrowck_check_region_constraints<'tcx>(
396 root_cx: &mut BorrowCheckRootCtxt<'tcx>,
397 CollectRegionConstraintsResult {
398 infcx,
399 body_owned,
400 promoted,
401 move_data,
402 borrow_set,
403 location_table,
404 location_map,
405 universal_region_relations,
406 region_bound_pairs: _,
407 known_type_outlives_obligations: _,
408 constraints,
409 deferred_closure_requirements,
410 deferred_opaque_type_errors,
411 polonius_facts,
412 polonius_context,
413 }: CollectRegionConstraintsResult<'tcx>,
414) -> PropagatedBorrowCheckResults<'tcx> {
415 if !!infcx.has_opaque_types_in_storage() {
::core::panicking::panic("assertion failed: !infcx.has_opaque_types_in_storage()")
};assert!(!infcx.has_opaque_types_in_storage());
416 if !deferred_closure_requirements.is_empty() {
::core::panicking::panic("assertion failed: deferred_closure_requirements.is_empty()")
};assert!(deferred_closure_requirements.is_empty());
417 let tcx = root_cx.tcx;
418 let body = &body_owned;
419 let def = body.source.def_id().expect_local();
420
421 let nll::NllOutput {
424 regioncx,
425 polonius_input,
426 polonius_output,
427 opt_closure_req,
428 nll_errors,
429 polonius_context,
430 } = nll::compute_regions(
431 root_cx,
432 &infcx,
433 body,
434 &location_table,
435 &move_data,
436 &borrow_set,
437 location_map,
438 universal_region_relations,
439 constraints,
440 polonius_facts,
441 polonius_context,
442 );
443
444 nll::dump_nll_mir(&infcx, body, ®ioncx, &opt_closure_req, &borrow_set);
447 polonius::dump_polonius_mir(
448 &infcx,
449 body,
450 ®ioncx,
451 &opt_closure_req,
452 &borrow_set,
453 polonius_context.as_ref(),
454 );
455
456 nll::dump_annotation(&infcx, body, ®ioncx, &opt_closure_req);
459
460 let movable_coroutine = body.coroutine.is_some()
461 && tcx.coroutine_movability(def.to_def_id()) == hir::Movability::Movable;
462
463 let diags_buffer = &mut BorrowckDiagnosticsBuffer::default();
464 for promoted_body in &promoted {
467 use rustc_middle::mir::visit::Visitor;
468 let move_data = MoveData::gather_moves(promoted_body, tcx, |_| true);
472 let mut promoted_mbcx = MirBorrowckCtxt {
473 root_cx,
474 infcx: &infcx,
475 body: promoted_body,
476 move_data: &move_data,
477 location_table: &location_table,
479 movable_coroutine,
480 fn_self_span_reported: Default::default(),
481 access_place_error_reported: Default::default(),
482 reservation_error_reported: Default::default(),
483 uninitialized_error_reported: Default::default(),
484 regioncx: ®ioncx,
485 used_mut: Default::default(),
486 used_mut_upvars: SmallVec::new(),
487 borrow_set: &borrow_set,
488 upvars: &[],
489 local_names: OnceCell::from(IndexVec::from_elem(None, &promoted_body.local_decls)),
490 region_names: RefCell::default(),
491 next_region_name: RefCell::new(1),
492 polonius_output: None,
493 move_errors: Vec::new(),
494 diags_buffer,
495 polonius_context: polonius_context.as_ref(),
496 };
497 struct MoveVisitor<'a, 'b, 'infcx, 'tcx> {
498 ctxt: &'a mut MirBorrowckCtxt<'b, 'infcx, 'tcx>,
499 }
500
501 impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, '_, 'tcx> {
502 fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
503 if let Operand::Move(place) = operand {
504 self.ctxt.check_movable_place(location, *place);
505 }
506 }
507 }
508 MoveVisitor { ctxt: &mut promoted_mbcx }.visit_body(promoted_body);
509 promoted_mbcx.report_move_errors();
510 }
511
512 let mut mbcx = MirBorrowckCtxt {
513 root_cx,
514 infcx: &infcx,
515 body,
516 move_data: &move_data,
517 location_table: &location_table,
518 movable_coroutine,
519 fn_self_span_reported: Default::default(),
520 access_place_error_reported: Default::default(),
521 reservation_error_reported: Default::default(),
522 uninitialized_error_reported: Default::default(),
523 regioncx: ®ioncx,
524 used_mut: Default::default(),
525 used_mut_upvars: SmallVec::new(),
526 borrow_set: &borrow_set,
527 upvars: tcx.closure_captures(def),
528 local_names: OnceCell::new(),
529 region_names: RefCell::default(),
530 next_region_name: RefCell::new(1),
531 move_errors: Vec::new(),
532 diags_buffer,
533 polonius_output: polonius_output.as_deref(),
534 polonius_context: polonius_context.as_ref(),
535 };
536
537 if nll_errors.is_empty() {
539 mbcx.report_opaque_type_errors(deferred_opaque_type_errors);
540 } else {
541 mbcx.report_region_errors(nll_errors);
542 }
543
544 let flow_results = get_flow_results(tcx, body, &move_data, &borrow_set, ®ioncx);
545 visit_results(
546 body,
547 traversal::reverse_postorder(body).map(|(bb, _)| bb),
548 &flow_results,
549 &mut mbcx,
550 );
551
552 mbcx.report_move_errors();
553
554 let temporary_used_locals: FxIndexSet<Local> = mbcx
560 .used_mut
561 .iter()
562 .filter(|&local| !mbcx.body.local_decls[*local].is_user_variable())
563 .cloned()
564 .collect();
565 let unused_mut_locals =
569 mbcx.body.mut_vars_iter().filter(|local| !mbcx.used_mut.contains(local)).collect();
570 mbcx.gather_used_muts(temporary_used_locals, unused_mut_locals);
571
572 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:572",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(572u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("mbcx.used_mut: {0:?}",
mbcx.used_mut) as &dyn Value))])
});
} else { ; }
};debug!("mbcx.used_mut: {:?}", mbcx.used_mut);
573 mbcx.lint_unused_mut();
574
575 let result = PropagatedBorrowCheckResults {
576 closure_requirements: opt_closure_req,
577 used_mut_upvars: mbcx.used_mut_upvars,
578 };
579
580 if let Some(guar) = mbcx.diags_buffer.emit_errors().or(infcx.tainted_by_errors()) {
581 root_cx.set_tainted_by_errors(guar);
582 }
583
584 if let Some(consumer) = &mut root_cx.consumer {
585 consumer.insert_body(
586 def,
587 BodyWithBorrowckFacts {
588 body: body_owned,
589 promoted,
590 borrow_set,
591 region_inference_context: regioncx,
592 location_table: polonius_input.as_ref().map(|_| location_table),
593 input_facts: polonius_input,
594 output_facts: polonius_output,
595 },
596 );
597 }
598
599 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:599",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(599u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("do_mir_borrowck: result = {0:#?}",
result) as &dyn Value))])
});
} else { ; }
};debug!("do_mir_borrowck: result = {:#?}", result);
600
601 result
602}
603
604fn get_flow_results<'a, 'tcx>(
605 tcx: TyCtxt<'tcx>,
606 body: &'a Body<'tcx>,
607 move_data: &'a MoveData<'tcx>,
608 borrow_set: &'a BorrowSet<'tcx>,
609 regioncx: &RegionInferenceContext<'tcx>,
610) -> Results<'tcx, Borrowck<'a, 'tcx>> {
611 let borrows = Borrows::new(tcx, body, regioncx, borrow_set).iterate_to_fixpoint(
614 tcx,
615 body,
616 Some("borrowck"),
617 );
618 let uninits = MaybeUninitializedPlaces::new(tcx, body, move_data).iterate_to_fixpoint(
619 tcx,
620 body,
621 Some("borrowck"),
622 );
623 let ever_inits = EverInitializedPlaces::new(body, move_data).iterate_to_fixpoint(
624 tcx,
625 body,
626 Some("borrowck"),
627 );
628
629 let analysis = Borrowck {
630 borrows: borrows.analysis,
631 uninits: uninits.analysis,
632 ever_inits: ever_inits.analysis,
633 };
634
635 {
match (&borrows.entry_states.len(), &uninits.entry_states.len()) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};assert_eq!(borrows.entry_states.len(), uninits.entry_states.len());
636 {
match (&borrows.entry_states.len(), &ever_inits.entry_states.len()) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};assert_eq!(borrows.entry_states.len(), ever_inits.entry_states.len());
637 let entry_states: EntryStates<_> =
638 ::itertools::__std_iter::Iterator::map(::itertools::__std_iter::Iterator::zip(::itertools::__std_iter::IntoIterator::into_iter(borrows.entry_states),
::itertools::__std_iter::Iterator::zip(::itertools::__std_iter::IntoIterator::into_iter(uninits.entry_states),
::itertools::__std_iter::IntoIterator::into_iter(ever_inits.entry_states))),
|(b, (b, a))| (b, b, a))itertools::izip!(borrows.entry_states, uninits.entry_states, ever_inits.entry_states)
639 .map(|(borrows, uninits, ever_inits)| BorrowckDomain { borrows, uninits, ever_inits })
640 .collect();
641
642 Results { analysis, entry_states }
643}
644
645pub(crate) struct BorrowckInferCtxt<'tcx> {
646 pub(crate) infcx: InferCtxt<'tcx>,
647 pub(crate) root_def_id: LocalDefId,
648 pub(crate) param_env: ParamEnv<'tcx>,
649 pub(crate) reg_var_to_origin: RefCell<FxIndexMap<ty::RegionVid, RegionCtxt>>,
650}
651
652impl<'tcx> BorrowckInferCtxt<'tcx> {
653 pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId, root_def_id: LocalDefId) -> Self {
654 let typing_mode = if tcx.use_typing_mode_post_typeck_until_borrowck() {
655 TypingMode::borrowck(tcx, def_id)
656 } else {
657 TypingMode::analysis_in_body(tcx, def_id)
658 };
659 let infcx = tcx.infer_ctxt().build(typing_mode);
660 let param_env = tcx.param_env(def_id);
661 BorrowckInferCtxt {
662 infcx,
663 root_def_id,
664 reg_var_to_origin: RefCell::new(Default::default()),
665 param_env,
666 }
667 }
668
669 pub(crate) fn next_region_var<F>(
670 &self,
671 origin: RegionVariableOrigin<'tcx>,
672 get_ctxt_fn: F,
673 ) -> ty::Region<'tcx>
674 where
675 F: Fn() -> RegionCtxt,
676 {
677 let next_region = self.infcx.next_region_var(origin);
678 let vid = next_region.as_var();
679
680 if truecfg!(debug_assertions) {
681 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:681",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(681u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("inserting vid {0:?} with origin {1:?} into var_to_origin",
vid, origin) as &dyn Value))])
});
} else { ; }
};debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin);
682 let ctxt = get_ctxt_fn();
683 let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
684 {
match (&var_to_origin.insert(vid, ctxt), &None) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};assert_eq!(var_to_origin.insert(vid, ctxt), None);
685 }
686
687 next_region
688 }
689
690 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::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("next_nll_region_var",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(690u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::tracing_core::field::FieldSet::new(&["origin"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::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(&origin)
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: ty::Region<'tcx> = loop {};
return __tracing_attr_fake_return;
}
{
let next_region = self.infcx.next_nll_region_var(origin);
let vid = next_region.as_var();
if true {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:703",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(703u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("inserting vid {0:?} with origin {1:?} into var_to_origin",
vid, origin) as &dyn Value))])
});
} else { ; }
};
let ctxt = get_ctxt_fn();
let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
{
match (&var_to_origin.insert(vid, ctxt), &None) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};
}
next_region
}
}
}#[instrument(skip(self, get_ctxt_fn), level = "debug")]
691 pub(crate) fn next_nll_region_var<F>(
692 &self,
693 origin: NllRegionVariableOrigin<'tcx>,
694 get_ctxt_fn: F,
695 ) -> ty::Region<'tcx>
696 where
697 F: Fn() -> RegionCtxt,
698 {
699 let next_region = self.infcx.next_nll_region_var(origin);
700 let vid = next_region.as_var();
701
702 if cfg!(debug_assertions) {
703 debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin);
704 let ctxt = get_ctxt_fn();
705 let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
706 assert_eq!(var_to_origin.insert(vid, ctxt), None);
707 }
708
709 next_region
710 }
711
712 fn fully_perform<Q: QueryTypeOp<'tcx> + TypeVisitable<TyCtxt<'tcx>>>(
713 &self,
714 q: Q,
715 span: Span,
716 ) -> Result<TypeOpOutput<'tcx, ty::ParamEnvAnd<'tcx, Q>>, ErrorGuaranteed> {
717 self.param_env.and(q).fully_perform(&self.infcx, self.root_def_id, span)
718 }
719}
720
721impl<'tcx> Deref for BorrowckInferCtxt<'tcx> {
722 type Target = InferCtxt<'tcx>;
723
724 fn deref(&self) -> &Self::Target {
725 &self.infcx
726 }
727}
728
729pub(crate) struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
730 root_cx: &'a BorrowCheckRootCtxt<'tcx>,
731 infcx: &'infcx BorrowckInferCtxt<'tcx>,
732 body: &'a Body<'tcx>,
733 move_data: &'a MoveData<'tcx>,
734
735 location_table: &'a PoloniusLocationTable,
738
739 movable_coroutine: bool,
740 access_place_error_reported: FxIndexSet<(Place<'tcx>, Span)>,
746 reservation_error_reported: FxIndexSet<Place<'tcx>>,
754 fn_self_span_reported: FxIndexSet<Span>,
758 uninitialized_error_reported: FxIndexSet<Local>,
761 used_mut: FxIndexSet<Local>,
764 used_mut_upvars: SmallVec<[FieldIdx; 8]>,
767 regioncx: &'a RegionInferenceContext<'tcx>,
770
771 borrow_set: &'a BorrowSet<'tcx>,
773
774 upvars: &'tcx [&'tcx ty::CapturedPlace<'tcx>],
776
777 local_names: OnceCell<IndexVec<Local, Option<Symbol>>>,
779
780 region_names: RefCell<FxIndexMap<RegionVid, RegionName>>,
783
784 next_region_name: RefCell<usize>,
786
787 diags_buffer: &'a mut BorrowckDiagnosticsBuffer<'infcx, 'tcx>,
788 move_errors: Vec<MoveError<'tcx>>,
789
790 polonius_output: Option<&'a PoloniusOutput>,
792 polonius_context: Option<&'a PoloniusContext>,
794}
795
796impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a, '_, 'tcx> {
802 fn visit_after_early_statement_effect(
803 &mut self,
804 _analysis: &Borrowck<'a, 'tcx>,
805 state: &BorrowckDomain,
806 stmt: &Statement<'tcx>,
807 location: Location,
808 ) {
809 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:809",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(809u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("MirBorrowckCtxt::process_statement({0:?}, {1:?}): {2:?}",
location, stmt, state) as &dyn Value))])
});
} else { ; }
};debug!("MirBorrowckCtxt::process_statement({:?}, {:?}): {:?}", location, stmt, state);
810 let span = stmt.source_info.span;
811
812 self.check_activations(location, span, state);
813
814 match &stmt.kind {
815 StatementKind::Assign((lhs, rhs)) => {
816 self.consume_rvalue(location, (rhs, span), state);
817
818 self.mutate_place(location, (*lhs, span), Shallow(None), state);
819 }
820 StatementKind::FakeRead((_, place)) => {
821 self.check_if_path_or_subpath_is_moved(
832 location,
833 InitializationRequiringAction::Use,
834 (place.as_ref(), span),
835 state,
836 );
837 }
838 StatementKind::Intrinsic(kind) => match kind {
839 NonDivergingIntrinsic::Assume(op) => {
840 self.consume_operand(location, (op, span), state);
841 }
842 NonDivergingIntrinsic::CopyNonOverlapping(..) => ::rustc_middle::util::bug::span_bug_fmt(span,
format_args!("Unexpected CopyNonOverlapping, should only appear after lower_intrinsics"))span_bug!(
843 span,
844 "Unexpected CopyNonOverlapping, should only appear after lower_intrinsics",
845 ),
846 },
847 StatementKind::AscribeUserType(..) => {}
849 StatementKind::PlaceMention(..) => {}
851 StatementKind::Coverage(..) => {}
853 StatementKind::ConstEvalCounter | StatementKind::StorageLive(..) => {}
855 StatementKind::BackwardIncompatibleDropHint {
857 place,
858 reason: BackwardIncompatibleDropReason::Edition2024,
859 } => {
860 self.check_backward_incompatible_drop(location, **place, state);
861 }
862 StatementKind::StorageDead(local) => {
863 self.access_place(
864 location,
865 (Place::from(*local), span),
866 (Shallow(None), Write(WriteKind::StorageDeadOrDrop)),
867 LocalMutationIsAllowed::Yes,
868 state,
869 );
870 }
871 StatementKind::Nop | StatementKind::SetDiscriminant { .. } => {
872 ::rustc_middle::util::bug::bug_fmt(format_args!("Statement not allowed in this MIR phase"))bug!("Statement not allowed in this MIR phase")
873 }
874 }
875 }
876
877 fn visit_after_early_terminator_effect(
878 &mut self,
879 _analysis: &Borrowck<'a, 'tcx>,
880 state: &BorrowckDomain,
881 term: &Terminator<'tcx>,
882 loc: Location,
883 ) {
884 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:884",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(884u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("MirBorrowckCtxt::process_terminator({0:?}, {1:?}): {2:?}",
loc, term, state) as &dyn Value))])
});
} else { ; }
};debug!("MirBorrowckCtxt::process_terminator({:?}, {:?}): {:?}", loc, term, state);
885 let span = term.source_info.span;
886
887 self.check_activations(loc, span, state);
888
889 match &term.kind {
890 TerminatorKind::SwitchInt { discr, targets: _ } => {
891 self.consume_operand(loc, (discr, span), state);
892 }
893 TerminatorKind::Drop { place, target: _, unwind: _, replace, drop: _ } => {
894 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:894",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(894u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("visit_terminator_drop loc: {0:?} term: {1:?} place: {2:?} span: {3:?}",
loc, term, place, span) as &dyn Value))])
});
} else { ; }
};debug!(
895 "visit_terminator_drop \
896 loc: {:?} term: {:?} place: {:?} span: {:?}",
897 loc, term, place, span
898 );
899
900 let write_kind =
901 if *replace { WriteKind::Replace } else { WriteKind::StorageDeadOrDrop };
902 self.access_place(
903 loc,
904 (*place, span),
905 (AccessDepth::Drop, Write(write_kind)),
906 LocalMutationIsAllowed::Yes,
907 state,
908 );
909 }
910 TerminatorKind::Call {
911 func,
912 args,
913 destination,
914 target: _,
915 unwind: _,
916 call_source: _,
917 fn_span: _,
918 } => {
919 self.consume_operand(loc, (func, span), state);
920 for arg in args {
921 self.consume_operand(loc, (&arg.node, arg.span), state);
922 }
923 self.mutate_place(loc, (*destination, span), Deep, state);
924 }
925 TerminatorKind::TailCall { func, args, fn_span: _ } => {
926 self.consume_operand(loc, (func, span), state);
927 for arg in args {
928 self.consume_operand(loc, (&arg.node, arg.span), state);
929 }
930 }
931 TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => {
932 self.consume_operand(loc, (cond, span), state);
933 if let AssertKind::BoundsCheck { len, index } = &**msg {
934 self.consume_operand(loc, (len, span), state);
935 self.consume_operand(loc, (index, span), state);
936 }
937 }
938
939 TerminatorKind::Yield { value, resume: _, resume_arg, drop: _ } => {
940 self.consume_operand(loc, (value, span), state);
941 self.mutate_place(loc, (*resume_arg, span), Deep, state);
942 }
943
944 TerminatorKind::InlineAsm {
945 asm_macro: _,
946 template: _,
947 operands,
948 options: _,
949 line_spans: _,
950 targets: _,
951 unwind: _,
952 } => {
953 for op in operands {
954 match op {
955 InlineAsmOperand::In { reg: _, value } => {
956 self.consume_operand(loc, (value, span), state);
957 }
958 InlineAsmOperand::Out { reg: _, late: _, place, .. } => {
959 if let Some(place) = place {
960 self.mutate_place(loc, (*place, span), Shallow(None), state);
961 }
962 }
963 InlineAsmOperand::InOut { reg: _, late: _, in_value, out_place } => {
964 self.consume_operand(loc, (in_value, span), state);
965 if let &Some(out_place) = out_place {
966 self.mutate_place(loc, (out_place, span), Shallow(None), state);
967 }
968 }
969 InlineAsmOperand::Const { value: _ }
970 | InlineAsmOperand::SymFn { value: _ }
971 | InlineAsmOperand::SymStatic { def_id: _ }
972 | InlineAsmOperand::Label { target_index: _ } => {}
973 }
974 }
975 }
976
977 TerminatorKind::Goto { target: _ }
978 | TerminatorKind::UnwindTerminate(_)
979 | TerminatorKind::Unreachable
980 | TerminatorKind::UnwindResume
981 | TerminatorKind::Return
982 | TerminatorKind::CoroutineDrop
983 | TerminatorKind::FalseEdge { real_target: _, imaginary_target: _ }
984 | TerminatorKind::FalseUnwind { real_target: _, unwind: _ } => {
985 }
987 }
988 }
989
990 fn visit_after_primary_terminator_effect(
991 &mut self,
992 _analysis: &Borrowck<'a, 'tcx>,
993 state: &BorrowckDomain,
994 term: &Terminator<'tcx>,
995 loc: Location,
996 ) {
997 let span = term.source_info.span;
998
999 match term.kind {
1000 TerminatorKind::Yield { value: _, resume: _, resume_arg: _, drop: _ } => {
1001 if self.movable_coroutine {
1002 for i in state.borrows.iter() {
1004 let borrow = &self.borrow_set[i];
1005 self.check_for_local_borrow(borrow, span);
1006 }
1007 }
1008 }
1009
1010 TerminatorKind::UnwindResume
1011 | TerminatorKind::Return
1012 | TerminatorKind::TailCall { .. }
1013 | TerminatorKind::CoroutineDrop => {
1014 match self.borrow_set.locals_state_at_exit() {
1015 LocalsStateAtExit::AllAreInvalidated => {
1016 for i in state.borrows.iter() {
1021 let borrow = &self.borrow_set[i];
1022 self.check_for_invalidation_at_exit(loc, borrow, span);
1023 }
1024 }
1025 LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved: _ } => {}
1028 }
1029 }
1030
1031 TerminatorKind::UnwindTerminate(_)
1032 | TerminatorKind::Assert { .. }
1033 | TerminatorKind::Call { .. }
1034 | TerminatorKind::Drop { .. }
1035 | TerminatorKind::FalseEdge { real_target: _, imaginary_target: _ }
1036 | TerminatorKind::FalseUnwind { real_target: _, unwind: _ }
1037 | TerminatorKind::Goto { .. }
1038 | TerminatorKind::SwitchInt { .. }
1039 | TerminatorKind::Unreachable
1040 | TerminatorKind::InlineAsm { .. } => {}
1041 }
1042 }
1043}
1044
1045use self::AccessDepth::{Deep, Shallow};
1046use self::ReadOrWrite::{Activation, Read, Reservation, Write};
1047
1048#[derive(#[automatically_derived]
impl ::core::marker::Copy for ArtificialField { }Copy, #[automatically_derived]
impl ::core::clone::Clone for ArtificialField {
#[inline]
fn clone(&self) -> ArtificialField { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for ArtificialField {
#[inline]
fn eq(&self, other: &ArtificialField) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for ArtificialField {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for ArtificialField {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
ArtificialField::ArrayLength => "ArrayLength",
ArtificialField::FakeBorrow => "FakeBorrow",
})
}
}Debug)]
1049enum ArtificialField {
1050 ArrayLength,
1051 FakeBorrow,
1052}
1053
1054#[derive(#[automatically_derived]
impl ::core::marker::Copy for AccessDepth { }Copy, #[automatically_derived]
impl ::core::clone::Clone for AccessDepth {
#[inline]
fn clone(&self) -> AccessDepth {
let _: ::core::clone::AssertParamIsClone<Option<ArtificialField>>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for AccessDepth {
#[inline]
fn eq(&self, other: &AccessDepth) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(AccessDepth::Shallow(__self_0),
AccessDepth::Shallow(__arg1_0)) => __self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for AccessDepth {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Option<ArtificialField>>;
}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for AccessDepth {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
AccessDepth::Shallow(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Shallow", &__self_0),
AccessDepth::Deep => ::core::fmt::Formatter::write_str(f, "Deep"),
AccessDepth::Drop => ::core::fmt::Formatter::write_str(f, "Drop"),
}
}
}Debug)]
1055enum AccessDepth {
1056 Shallow(Option<ArtificialField>),
1062
1063 Deep,
1067
1068 Drop,
1071}
1072
1073#[derive(#[automatically_derived]
impl ::core::marker::Copy for ReadOrWrite { }Copy, #[automatically_derived]
impl ::core::clone::Clone for ReadOrWrite {
#[inline]
fn clone(&self) -> ReadOrWrite {
let _: ::core::clone::AssertParamIsClone<ReadKind>;
let _: ::core::clone::AssertParamIsClone<WriteKind>;
let _: ::core::clone::AssertParamIsClone<BorrowIndex>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for ReadOrWrite {
#[inline]
fn eq(&self, other: &ReadOrWrite) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(ReadOrWrite::Read(__self_0), ReadOrWrite::Read(__arg1_0)) =>
__self_0 == __arg1_0,
(ReadOrWrite::Write(__self_0), ReadOrWrite::Write(__arg1_0))
=> __self_0 == __arg1_0,
(ReadOrWrite::Reservation(__self_0),
ReadOrWrite::Reservation(__arg1_0)) => __self_0 == __arg1_0,
(ReadOrWrite::Activation(__self_0, __self_1),
ReadOrWrite::Activation(__arg1_0, __arg1_1)) =>
__self_0 == __arg1_0 && __self_1 == __arg1_1,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for ReadOrWrite {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<ReadKind>;
let _: ::core::cmp::AssertParamIsEq<WriteKind>;
let _: ::core::cmp::AssertParamIsEq<BorrowIndex>;
}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for ReadOrWrite {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ReadOrWrite::Read(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Read",
&__self_0),
ReadOrWrite::Write(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Write",
&__self_0),
ReadOrWrite::Reservation(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Reservation", &__self_0),
ReadOrWrite::Activation(__self_0, __self_1) =>
::core::fmt::Formatter::debug_tuple_field2_finish(f,
"Activation", __self_0, &__self_1),
}
}
}Debug)]
1076enum ReadOrWrite {
1077 Read(ReadKind),
1080
1081 Write(WriteKind),
1085
1086 Reservation(WriteKind),
1090 Activation(WriteKind, BorrowIndex),
1091}
1092
1093#[derive(#[automatically_derived]
impl ::core::marker::Copy for ReadKind { }Copy, #[automatically_derived]
impl ::core::clone::Clone for ReadKind {
#[inline]
fn clone(&self) -> ReadKind {
let _: ::core::clone::AssertParamIsClone<BorrowKind>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for ReadKind {
#[inline]
fn eq(&self, other: &ReadKind) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(ReadKind::Borrow(__self_0), ReadKind::Borrow(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for ReadKind {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<BorrowKind>;
}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for ReadKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ReadKind::Borrow(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Borrow",
&__self_0),
ReadKind::Copy => ::core::fmt::Formatter::write_str(f, "Copy"),
}
}
}Debug)]
1096enum ReadKind {
1097 Borrow(BorrowKind),
1098 Copy,
1099}
1100
1101#[derive(#[automatically_derived]
impl ::core::marker::Copy for WriteKind { }Copy, #[automatically_derived]
impl ::core::clone::Clone for WriteKind {
#[inline]
fn clone(&self) -> WriteKind {
let _: ::core::clone::AssertParamIsClone<BorrowKind>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for WriteKind {
#[inline]
fn eq(&self, other: &WriteKind) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(WriteKind::MutableBorrow(__self_0),
WriteKind::MutableBorrow(__arg1_0)) => __self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for WriteKind {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<BorrowKind>;
}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for WriteKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
WriteKind::StorageDeadOrDrop =>
::core::fmt::Formatter::write_str(f, "StorageDeadOrDrop"),
WriteKind::Replace =>
::core::fmt::Formatter::write_str(f, "Replace"),
WriteKind::MutableBorrow(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"MutableBorrow", &__self_0),
WriteKind::Mutate =>
::core::fmt::Formatter::write_str(f, "Mutate"),
WriteKind::Move => ::core::fmt::Formatter::write_str(f, "Move"),
}
}
}Debug)]
1104enum WriteKind {
1105 StorageDeadOrDrop,
1106 Replace,
1107 MutableBorrow(BorrowKind),
1108 Mutate,
1109 Move,
1110}
1111
1112#[derive(#[automatically_derived]
impl ::core::marker::Copy for LocalMutationIsAllowed { }Copy, #[automatically_derived]
impl ::core::clone::Clone for LocalMutationIsAllowed {
#[inline]
fn clone(&self) -> LocalMutationIsAllowed { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for LocalMutationIsAllowed {
#[inline]
fn eq(&self, other: &LocalMutationIsAllowed) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for LocalMutationIsAllowed {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for LocalMutationIsAllowed {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
LocalMutationIsAllowed::Yes => "Yes",
LocalMutationIsAllowed::ExceptUpvars => "ExceptUpvars",
LocalMutationIsAllowed::No => "No",
})
}
}Debug)]
1120enum LocalMutationIsAllowed {
1121 Yes,
1122 ExceptUpvars,
1125 No,
1126}
1127
1128#[derive(#[automatically_derived]
impl ::core::marker::Copy for InitializationRequiringAction { }Copy, #[automatically_derived]
impl ::core::clone::Clone for InitializationRequiringAction {
#[inline]
fn clone(&self) -> InitializationRequiringAction { *self }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for InitializationRequiringAction {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
InitializationRequiringAction::Borrow => "Borrow",
InitializationRequiringAction::MatchOn => "MatchOn",
InitializationRequiringAction::Use => "Use",
InitializationRequiringAction::Assignment => "Assignment",
InitializationRequiringAction::PartialAssignment =>
"PartialAssignment",
})
}
}Debug)]
1129enum InitializationRequiringAction {
1130 Borrow,
1131 MatchOn,
1132 Use,
1133 Assignment,
1134 PartialAssignment,
1135}
1136
1137#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for RootPlace<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f, "RootPlace",
"place_local", &self.place_local, "place_projection",
&self.place_projection, "is_local_mutation_allowed",
&&self.is_local_mutation_allowed)
}
}Debug)]
1138struct RootPlace<'tcx> {
1139 place_local: Local,
1140 place_projection: &'tcx [PlaceElem<'tcx>],
1141 is_local_mutation_allowed: LocalMutationIsAllowed,
1142}
1143
1144impl InitializationRequiringAction {
1145 fn as_noun(self) -> &'static str {
1146 match self {
1147 InitializationRequiringAction::Borrow => "borrow",
1148 InitializationRequiringAction::MatchOn => "use", InitializationRequiringAction::Use => "use",
1150 InitializationRequiringAction::Assignment => "assign",
1151 InitializationRequiringAction::PartialAssignment => "assign to part",
1152 }
1153 }
1154
1155 fn as_verb_in_past_tense(self) -> &'static str {
1156 match self {
1157 InitializationRequiringAction::Borrow => "borrowed",
1158 InitializationRequiringAction::MatchOn => "matched on",
1159 InitializationRequiringAction::Use => "used",
1160 InitializationRequiringAction::Assignment => "assigned",
1161 InitializationRequiringAction::PartialAssignment => "partially assigned",
1162 }
1163 }
1164
1165 fn as_general_verb_in_past_tense(self) -> &'static str {
1166 match self {
1167 InitializationRequiringAction::Borrow
1168 | InitializationRequiringAction::MatchOn
1169 | InitializationRequiringAction::Use => "used",
1170 InitializationRequiringAction::Assignment => "assigned",
1171 InitializationRequiringAction::PartialAssignment => "partially assigned",
1172 }
1173 }
1174}
1175
1176impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
1177 fn body(&self) -> &'a Body<'tcx> {
1178 self.body
1179 }
1180
1181 fn access_place(
1188 &mut self,
1189 location: Location,
1190 place_span: (Place<'tcx>, Span),
1191 kind: (AccessDepth, ReadOrWrite),
1192 is_local_mutation_allowed: LocalMutationIsAllowed,
1193 state: &BorrowckDomain,
1194 ) {
1195 let (sd, rw) = kind;
1196
1197 if let Activation(_, borrow_index) = rw {
1198 if self.reservation_error_reported.contains(&place_span.0) {
1199 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:1199",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1199u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("skipping access_place for activation of invalid reservation place: {0:?} borrow_index: {1:?}",
place_span.0, borrow_index) as &dyn Value))])
});
} else { ; }
};debug!(
1200 "skipping access_place for activation of invalid reservation \
1201 place: {:?} borrow_index: {:?}",
1202 place_span.0, borrow_index
1203 );
1204 return;
1205 }
1206 }
1207
1208 if !self.access_place_error_reported.is_empty()
1211 && self.access_place_error_reported.contains(&(place_span.0, place_span.1))
1212 {
1213 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:1213",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1213u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("access_place: suppressing error place_span=`{0:?}` kind=`{1:?}`",
place_span, kind) as &dyn Value))])
});
} else { ; }
};debug!(
1214 "access_place: suppressing error place_span=`{:?}` kind=`{:?}`",
1215 place_span, kind
1216 );
1217
1218 if rw == ReadOrWrite::Write(WriteKind::Mutate)
1222 && let Ok(root_place) =
1223 self.is_mutable(place_span.0.as_ref(), is_local_mutation_allowed)
1224 {
1225 self.add_used_mut(root_place, state);
1226 }
1227
1228 return;
1229 }
1230
1231 let mutability_error = self.check_access_permissions(
1232 place_span,
1233 rw,
1234 is_local_mutation_allowed,
1235 state,
1236 location,
1237 );
1238 let conflict_error = self.check_access_for_conflict(location, place_span, sd, rw, state);
1239
1240 if conflict_error || mutability_error {
1241 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:1241",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1241u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("access_place: logging error place_span=`{0:?}` kind=`{1:?}`",
place_span, kind) as &dyn Value))])
});
} else { ; }
};debug!("access_place: logging error place_span=`{:?}` kind=`{:?}`", place_span, kind);
1242 self.access_place_error_reported.insert((place_span.0, place_span.1));
1243 }
1244 }
1245
1246 fn borrows_in_scope<'s>(
1247 &self,
1248 location: Location,
1249 state: &'s BorrowckDomain,
1250 ) -> Cow<'s, MixedBitSet<BorrowIndex>> {
1251 if let Some(polonius) = &self.polonius_output {
1252 let location = self.location_table.start_index(location);
1254 let mut polonius_output = MixedBitSet::new_empty(self.borrow_set.len());
1255 for &idx in polonius.errors_at(location) {
1256 polonius_output.insert(idx);
1257 }
1258 Cow::Owned(polonius_output)
1259 } else {
1260 Cow::Borrowed(&state.borrows)
1261 }
1262 }
1263
1264 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::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("check_access_for_conflict",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1264u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::tracing_core::field::FieldSet::new(&["location",
"place_span", "sd", "rw"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::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(&location)
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(&place_span)
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(&sd)
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(&rw)
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: bool = loop {};
return __tracing_attr_fake_return;
}
{
let mut error_reported = false;
let borrows_in_scope = self.borrows_in_scope(location, state);
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:1276",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1276u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::tracing_core::field::FieldSet::new(&["borrows_in_scope",
"location"],
::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(&borrows_in_scope)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&location)
as &dyn Value))])
});
} else { ; }
};
each_borrow_involving_path(self, self.infcx.tcx, self.body,
(sd, place_span.0), self.borrow_set,
|borrow_index| borrows_in_scope.contains(borrow_index),
|this, borrow_index, borrow|
match (rw, borrow.kind) {
(Activation(_, activating), _) if activating == borrow_index
=> {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:1293",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1293u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("check_access_for_conflict place_span: {0:?} sd: {1:?} rw: {2:?} skipping {3:?} b/c activation of same borrow_index",
place_span, sd, rw, (borrow_index, borrow)) as
&dyn Value))])
});
} else { ; }
};
ControlFlow::Continue(())
}
(Read(_), BorrowKind::Shared | BorrowKind::Fake(_)) |
(Read(ReadKind::Borrow(BorrowKind::Fake(FakeBorrowKind::Shallow))),
BorrowKind::Mut { .. }) => ControlFlow::Continue(()),
(Reservation(_), BorrowKind::Fake(_) | BorrowKind::Shared)
=> {
ControlFlow::Continue(())
}
(Write(WriteKind::Move),
BorrowKind::Fake(FakeBorrowKind::Shallow)) => {
ControlFlow::Continue(())
}
(Read(kind), BorrowKind::Mut { .. }) => {
if !is_active(this.dominators(), borrow, location) {
if !borrow.kind.is_two_phase_borrow() {
::core::panicking::panic("assertion failed: borrow.kind.is_two_phase_borrow()")
};
return ControlFlow::Continue(());
}
error_reported = true;
match kind {
ReadKind::Copy => {
let err =
this.report_use_while_mutably_borrowed(location, place_span,
borrow);
this.buffer_error(err);
}
ReadKind::Borrow(bk) => {
let err =
this.report_conflicting_borrow(location, place_span, bk,
borrow);
this.buffer_error(err);
}
}
ControlFlow::Break(())
}
(Reservation(kind) | Activation(kind, _) | Write(kind), _)
=> {
match rw {
Reservation(..) => {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:1347",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1347u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("recording invalid reservation of place: {0:?}",
place_span.0) as &dyn Value))])
});
} else { ; }
};
this.reservation_error_reported.insert(place_span.0);
}
Activation(_, activating) => {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:1355",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1355u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("observing check_place for activation of borrow_index: {0:?}",
activating) as &dyn Value))])
});
} else { ; }
};
}
Read(..) | Write(..) => {}
}
error_reported = true;
match kind {
WriteKind::MutableBorrow(bk) => {
let err =
this.report_conflicting_borrow(location, place_span, bk,
borrow);
this.buffer_error(err);
}
WriteKind::StorageDeadOrDrop =>
this.report_borrowed_value_does_not_live_long_enough(location,
borrow, place_span, Some(WriteKind::StorageDeadOrDrop)),
WriteKind::Mutate => {
this.report_illegal_mutation_of_borrowed(location,
place_span, borrow)
}
WriteKind::Move => {
this.report_move_out_while_borrowed(location, place_span,
borrow)
}
WriteKind::Replace => {
this.report_illegal_mutation_of_borrowed(location,
place_span, borrow)
}
}
ControlFlow::Break(())
}
});
error_reported
}
}
}#[instrument(level = "debug", skip(self, state))]
1265 fn check_access_for_conflict(
1266 &mut self,
1267 location: Location,
1268 place_span: (Place<'tcx>, Span),
1269 sd: AccessDepth,
1270 rw: ReadOrWrite,
1271 state: &BorrowckDomain,
1272 ) -> bool {
1273 let mut error_reported = false;
1274
1275 let borrows_in_scope = self.borrows_in_scope(location, state);
1276 debug!(?borrows_in_scope, ?location);
1277
1278 each_borrow_involving_path(
1279 self,
1280 self.infcx.tcx,
1281 self.body,
1282 (sd, place_span.0),
1283 self.borrow_set,
1284 |borrow_index| borrows_in_scope.contains(borrow_index),
1285 |this, borrow_index, borrow| match (rw, borrow.kind) {
1286 (Activation(_, activating), _) if activating == borrow_index => {
1293 debug!(
1294 "check_access_for_conflict place_span: {:?} sd: {:?} rw: {:?} \
1295 skipping {:?} b/c activation of same borrow_index",
1296 place_span,
1297 sd,
1298 rw,
1299 (borrow_index, borrow),
1300 );
1301 ControlFlow::Continue(())
1302 }
1303
1304 (Read(_), BorrowKind::Shared | BorrowKind::Fake(_))
1305 | (
1306 Read(ReadKind::Borrow(BorrowKind::Fake(FakeBorrowKind::Shallow))),
1307 BorrowKind::Mut { .. },
1308 ) => ControlFlow::Continue(()),
1309
1310 (Reservation(_), BorrowKind::Fake(_) | BorrowKind::Shared) => {
1311 ControlFlow::Continue(())
1314 }
1315
1316 (Write(WriteKind::Move), BorrowKind::Fake(FakeBorrowKind::Shallow)) => {
1317 ControlFlow::Continue(())
1319 }
1320
1321 (Read(kind), BorrowKind::Mut { .. }) => {
1322 if !is_active(this.dominators(), borrow, location) {
1324 assert!(borrow.kind.is_two_phase_borrow());
1325 return ControlFlow::Continue(());
1326 }
1327
1328 error_reported = true;
1329 match kind {
1330 ReadKind::Copy => {
1331 let err = this
1332 .report_use_while_mutably_borrowed(location, place_span, borrow);
1333 this.buffer_error(err);
1334 }
1335 ReadKind::Borrow(bk) => {
1336 let err =
1337 this.report_conflicting_borrow(location, place_span, bk, borrow);
1338 this.buffer_error(err);
1339 }
1340 }
1341 ControlFlow::Break(())
1342 }
1343
1344 (Reservation(kind) | Activation(kind, _) | Write(kind), _) => {
1345 match rw {
1346 Reservation(..) => {
1347 debug!(
1348 "recording invalid reservation of \
1349 place: {:?}",
1350 place_span.0
1351 );
1352 this.reservation_error_reported.insert(place_span.0);
1353 }
1354 Activation(_, activating) => {
1355 debug!(
1356 "observing check_place for activation of \
1357 borrow_index: {:?}",
1358 activating
1359 );
1360 }
1361 Read(..) | Write(..) => {}
1362 }
1363
1364 error_reported = true;
1365 match kind {
1366 WriteKind::MutableBorrow(bk) => {
1367 let err =
1368 this.report_conflicting_borrow(location, place_span, bk, borrow);
1369 this.buffer_error(err);
1370 }
1371 WriteKind::StorageDeadOrDrop => this
1372 .report_borrowed_value_does_not_live_long_enough(
1373 location,
1374 borrow,
1375 place_span,
1376 Some(WriteKind::StorageDeadOrDrop),
1377 ),
1378 WriteKind::Mutate => {
1379 this.report_illegal_mutation_of_borrowed(location, place_span, borrow)
1380 }
1381 WriteKind::Move => {
1382 this.report_move_out_while_borrowed(location, place_span, borrow)
1383 }
1384 WriteKind::Replace => {
1385 this.report_illegal_mutation_of_borrowed(location, place_span, borrow)
1386 }
1387 }
1388 ControlFlow::Break(())
1389 }
1390 },
1391 );
1392
1393 error_reported
1394 }
1395
1396 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::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("check_backward_incompatible_drop",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1398u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::tracing_core::field::FieldSet::new(&["location", "place"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::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(&location)
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(&place)
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: () = loop {};
return __tracing_attr_fake_return;
}
{
let tcx = self.infcx.tcx;
let sd =
if place.ty(self.body,
tcx).ty.needs_drop(tcx, self.body.typing_env(tcx)) {
AccessDepth::Drop
} else { AccessDepth::Shallow(None) };
let borrows_in_scope = self.borrows_in_scope(location, state);
each_borrow_involving_path(self, self.infcx.tcx, self.body,
(sd, place), self.borrow_set,
|borrow_index| borrows_in_scope.contains(borrow_index),
|this, _borrow_index, borrow|
{
if #[allow(non_exhaustive_omitted_patterns)] match borrow.kind
{
BorrowKind::Fake(_) => true,
_ => false,
} {
return ControlFlow::Continue(());
}
let borrowed =
this.retrieve_borrow_spans(borrow).var_or_use_path_span();
let explain =
this.explain_why_borrow_contains_point(location, borrow,
Some((WriteKind::StorageDeadOrDrop, place)));
this.infcx.tcx.emit_node_span_lint(TAIL_EXPR_DROP_ORDER,
CRATE_HIR_ID, borrowed,
session_diagnostics::TailExprDropOrder {
borrowed,
callback: |diag|
{
explain.add_explanation_to_diagnostic(&this, diag, "", None,
None);
},
});
ControlFlow::Break(())
});
}
}
}#[instrument(level = "debug", skip(self, state))]
1399 fn check_backward_incompatible_drop(
1400 &mut self,
1401 location: Location,
1402 place: Place<'tcx>,
1403 state: &BorrowckDomain,
1404 ) {
1405 let tcx = self.infcx.tcx;
1406 let sd = if place.ty(self.body, tcx).ty.needs_drop(tcx, self.body.typing_env(tcx)) {
1410 AccessDepth::Drop
1411 } else {
1412 AccessDepth::Shallow(None)
1413 };
1414
1415 let borrows_in_scope = self.borrows_in_scope(location, state);
1416
1417 each_borrow_involving_path(
1420 self,
1421 self.infcx.tcx,
1422 self.body,
1423 (sd, place),
1424 self.borrow_set,
1425 |borrow_index| borrows_in_scope.contains(borrow_index),
1426 |this, _borrow_index, borrow| {
1427 if matches!(borrow.kind, BorrowKind::Fake(_)) {
1428 return ControlFlow::Continue(());
1429 }
1430 let borrowed = this.retrieve_borrow_spans(borrow).var_or_use_path_span();
1431 let explain = this.explain_why_borrow_contains_point(
1432 location,
1433 borrow,
1434 Some((WriteKind::StorageDeadOrDrop, place)),
1435 );
1436 this.infcx.tcx.emit_node_span_lint(
1437 TAIL_EXPR_DROP_ORDER,
1438 CRATE_HIR_ID,
1439 borrowed,
1440 session_diagnostics::TailExprDropOrder {
1441 borrowed,
1442 callback: |diag| {
1443 explain.add_explanation_to_diagnostic(&this, diag, "", None, None);
1444 },
1445 },
1446 );
1447 ControlFlow::Break(())
1449 },
1450 );
1451 }
1452
1453 fn mutate_place(
1454 &mut self,
1455 location: Location,
1456 place_span: (Place<'tcx>, Span),
1457 kind: AccessDepth,
1458 state: &BorrowckDomain,
1459 ) {
1460 self.check_if_assigned_path_is_moved(location, place_span, state);
1462
1463 self.access_place(
1464 location,
1465 place_span,
1466 (kind, Write(WriteKind::Mutate)),
1467 LocalMutationIsAllowed::No,
1468 state,
1469 );
1470 }
1471
1472 fn consume_rvalue(
1473 &mut self,
1474 location: Location,
1475 (rvalue, span): (&Rvalue<'tcx>, Span),
1476 state: &BorrowckDomain,
1477 ) {
1478 match rvalue {
1479 &Rvalue::Ref(_ , bk, place) => {
1480 let access_kind = match bk {
1481 BorrowKind::Fake(FakeBorrowKind::Shallow) => {
1482 (Shallow(Some(ArtificialField::FakeBorrow)), Read(ReadKind::Borrow(bk)))
1483 }
1484 BorrowKind::Shared | BorrowKind::Fake(FakeBorrowKind::Deep) => {
1485 (Deep, Read(ReadKind::Borrow(bk)))
1486 }
1487 BorrowKind::Mut { .. } => {
1488 let wk = WriteKind::MutableBorrow(bk);
1489 if bk.is_two_phase_borrow() {
1490 (Deep, Reservation(wk))
1491 } else {
1492 (Deep, Write(wk))
1493 }
1494 }
1495 };
1496
1497 self.access_place(
1498 location,
1499 (place, span),
1500 access_kind,
1501 LocalMutationIsAllowed::No,
1502 state,
1503 );
1504
1505 let action = if bk == BorrowKind::Fake(FakeBorrowKind::Shallow) {
1506 InitializationRequiringAction::MatchOn
1507 } else {
1508 InitializationRequiringAction::Borrow
1509 };
1510
1511 self.check_if_path_or_subpath_is_moved(
1512 location,
1513 action,
1514 (place.as_ref(), span),
1515 state,
1516 );
1517 }
1518
1519 &Rvalue::Reborrow(_target, mutability, place) => {
1520 let access_kind = (
1521 Deep,
1522 if mutability == Mutability::Mut {
1523 Write(WriteKind::MutableBorrow(BorrowKind::Mut {
1524 kind: MutBorrowKind::Default,
1525 }))
1526 } else {
1527 Read(ReadKind::Borrow(BorrowKind::Shared))
1528 },
1529 );
1530
1531 self.access_place(
1532 location,
1533 (place, span),
1534 access_kind,
1535 LocalMutationIsAllowed::Yes,
1536 state,
1537 );
1538
1539 let action = InitializationRequiringAction::Borrow;
1540
1541 self.check_if_path_or_subpath_is_moved(
1542 location,
1543 action,
1544 (place.as_ref(), span),
1545 state,
1546 );
1547 }
1548
1549 &Rvalue::RawPtr(kind, place) => {
1550 let access_kind = match kind {
1551 RawPtrKind::Mut => (
1552 Deep,
1553 Write(WriteKind::MutableBorrow(BorrowKind::Mut {
1554 kind: MutBorrowKind::Default,
1555 })),
1556 ),
1557 RawPtrKind::Const => (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))),
1558 RawPtrKind::FakeForPtrMetadata => {
1559 (Shallow(Some(ArtificialField::ArrayLength)), Read(ReadKind::Copy))
1560 }
1561 };
1562
1563 self.access_place(
1564 location,
1565 (place, span),
1566 access_kind,
1567 LocalMutationIsAllowed::No,
1568 state,
1569 );
1570
1571 self.check_if_path_or_subpath_is_moved(
1572 location,
1573 InitializationRequiringAction::Borrow,
1574 (place.as_ref(), span),
1575 state,
1576 );
1577 }
1578
1579 Rvalue::ThreadLocalRef(_) => {}
1580
1581 Rvalue::Use(operand, _)
1582 | Rvalue::Repeat(operand, _)
1583 | Rvalue::UnaryOp(_ , operand)
1584 | Rvalue::Cast(_ , operand, _ ) => {
1585 self.consume_operand(location, (operand, span), state)
1586 }
1587
1588 &Rvalue::Discriminant(place) => {
1589 let af = match *rvalue {
1590 Rvalue::Discriminant(..) => None,
1591 _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1592 };
1593 self.access_place(
1594 location,
1595 (place, span),
1596 (Shallow(af), Read(ReadKind::Copy)),
1597 LocalMutationIsAllowed::No,
1598 state,
1599 );
1600 self.check_if_path_or_subpath_is_moved(
1601 location,
1602 InitializationRequiringAction::Use,
1603 (place.as_ref(), span),
1604 state,
1605 );
1606 }
1607
1608 Rvalue::BinaryOp(_bin_op, (operand1, operand2)) => {
1609 self.consume_operand(location, (operand1, span), state);
1610 self.consume_operand(location, (operand2, span), state);
1611 }
1612
1613 Rvalue::Aggregate(aggregate_kind, operands) => {
1614 match **aggregate_kind {
1618 AggregateKind::Closure(def_id, _)
1619 | AggregateKind::CoroutineClosure(def_id, _)
1620 | AggregateKind::Coroutine(def_id, _) => {
1621 let def_id = def_id.expect_local();
1622 let used_mut_upvars = self.root_cx.used_mut_upvars(def_id);
1623 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:1623",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1623u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("{0:?} used_mut_upvars={1:?}",
def_id, used_mut_upvars) as &dyn Value))])
});
} else { ; }
};debug!("{:?} used_mut_upvars={:?}", def_id, used_mut_upvars);
1624 for field in used_mut_upvars.clone() {
1628 self.propagate_closure_used_mut_upvar(&operands[field]);
1629 }
1630 }
1631 AggregateKind::Adt(..)
1632 | AggregateKind::Array(..)
1633 | AggregateKind::Tuple { .. }
1634 | AggregateKind::RawPtr(..) => (),
1635 }
1636
1637 for operand in operands {
1638 self.consume_operand(location, (operand, span), state);
1639 }
1640 }
1641
1642 Rvalue::WrapUnsafeBinder(op, _) => {
1643 self.consume_operand(location, (op, span), state);
1644 }
1645
1646 Rvalue::CopyForDeref(_) => ::rustc_middle::util::bug::bug_fmt(format_args!("`CopyForDeref` in borrowck"))bug!("`CopyForDeref` in borrowck"),
1647 }
1648 }
1649
1650 fn propagate_closure_used_mut_upvar(&mut self, operand: &Operand<'tcx>) {
1651 let propagate_closure_used_mut_place = |this: &mut Self, place: Place<'tcx>| {
1652 if let Some(field) = this.is_upvar_field_projection(place.as_ref()) {
1660 this.used_mut_upvars.push(field);
1661 return;
1662 }
1663
1664 for (place_ref, proj) in place.iter_projections().rev() {
1665 if proj == ProjectionElem::Deref {
1667 match place_ref.ty(this.body(), this.infcx.tcx).ty.kind() {
1668 ty::Ref(_, _, hir::Mutability::Mut) => return,
1670
1671 _ => {}
1672 }
1673 }
1674
1675 if let Some(field) = this.is_upvar_field_projection(place_ref) {
1677 this.used_mut_upvars.push(field);
1678 return;
1679 }
1680 }
1681
1682 this.used_mut.insert(place.local);
1684 };
1685
1686 match *operand {
1690 Operand::Move(place) | Operand::Copy(place) => {
1691 match place.as_local() {
1692 Some(local) if !self.body.local_decls[local].is_user_variable() => {
1693 if self.body.local_decls[local].ty.is_mutable_ptr() {
1694 return;
1696 }
1697 let Some(temp_mpi) = self.move_data.rev_lookup.find_local(local) else {
1713 ::rustc_middle::util::bug::bug_fmt(format_args!("temporary should be tracked"));bug!("temporary should be tracked");
1714 };
1715 let init = if let [init_index] = *self.move_data.init_path_map[temp_mpi] {
1716 &self.move_data.inits[init_index]
1717 } else {
1718 ::rustc_middle::util::bug::bug_fmt(format_args!("temporary should be initialized exactly once"))bug!("temporary should be initialized exactly once")
1719 };
1720
1721 let InitLocation::Statement(loc) = init.location else {
1722 ::rustc_middle::util::bug::bug_fmt(format_args!("temporary initialized in arguments"))bug!("temporary initialized in arguments")
1723 };
1724
1725 let body = self.body;
1726 let bbd = &body[loc.block];
1727 let stmt = &bbd.statements[loc.statement_index];
1728 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:1728",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1728u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("temporary assigned in: stmt={0:?}",
stmt) as &dyn Value))])
});
} else { ; }
};debug!("temporary assigned in: stmt={:?}", stmt);
1729
1730 match stmt.kind {
1731 StatementKind::Assign((
1732 _,
1733 Rvalue::Ref(_, _, source)
1734 | Rvalue::Use(Operand::Copy(source) | Operand::Move(source), _),
1735 )) => {
1736 propagate_closure_used_mut_place(self, source);
1737 }
1738 _ => {
1739 ::rustc_middle::util::bug::bug_fmt(format_args!("closures should only capture user variables or references to user variables"));bug!(
1740 "closures should only capture user variables \
1741 or references to user variables"
1742 );
1743 }
1744 }
1745 }
1746 _ => propagate_closure_used_mut_place(self, place),
1747 }
1748 }
1749 Operand::Constant(..) | Operand::RuntimeChecks(_) => {}
1750 }
1751 }
1752
1753 fn consume_operand(
1754 &mut self,
1755 location: Location,
1756 (operand, span): (&Operand<'tcx>, Span),
1757 state: &BorrowckDomain,
1758 ) {
1759 match *operand {
1760 Operand::Copy(place) => {
1761 self.access_place(
1764 location,
1765 (place, span),
1766 (Deep, Read(ReadKind::Copy)),
1767 LocalMutationIsAllowed::No,
1768 state,
1769 );
1770
1771 self.check_if_path_or_subpath_is_moved(
1773 location,
1774 InitializationRequiringAction::Use,
1775 (place.as_ref(), span),
1776 state,
1777 );
1778 }
1779 Operand::Move(place) => {
1780 self.check_movable_place(location, place);
1782
1783 self.access_place(
1785 location,
1786 (place, span),
1787 (Deep, Write(WriteKind::Move)),
1788 LocalMutationIsAllowed::Yes,
1789 state,
1790 );
1791
1792 self.check_if_path_or_subpath_is_moved(
1794 location,
1795 InitializationRequiringAction::Use,
1796 (place.as_ref(), span),
1797 state,
1798 );
1799 }
1800 Operand::Constant(_) | Operand::RuntimeChecks(_) => {}
1801 }
1802 }
1803
1804 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::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("check_for_invalidation_at_exit",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1806u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::tracing_core::field::FieldSet::new(&["location", "borrow",
"span"], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::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(&location)
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(&borrow)
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(&span)
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: () = loop {};
return __tracing_attr_fake_return;
}
{
let place = borrow.borrowed_place;
let mut root_place =
PlaceRef { local: place.local, projection: &[] };
let might_be_alive =
if self.body.local_decls[root_place.local].is_ref_to_thread_local()
{
root_place.projection = TyCtxtConsts::DEREF_PROJECTION;
true
} else { false };
let sd = if might_be_alive { Deep } else { Shallow(None) };
if places_conflict::borrow_conflicts_with_place(self.infcx.tcx,
self.body, place, borrow.kind, root_place, sd,
places_conflict::PlaceConflictBias::Overlap) {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:1842",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1842u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("check_for_invalidation_at_exit({0:?}): INVALID",
place) as &dyn Value))])
});
} else { ; }
};
let span = self.infcx.tcx.sess.source_map().end_point(span);
self.report_borrowed_value_does_not_live_long_enough(location,
borrow, (place, span), None)
}
}
}
}#[instrument(level = "debug", skip(self))]
1807 fn check_for_invalidation_at_exit(
1808 &mut self,
1809 location: Location,
1810 borrow: &BorrowData<'tcx>,
1811 span: Span,
1812 ) {
1813 let place = borrow.borrowed_place;
1814 let mut root_place = PlaceRef { local: place.local, projection: &[] };
1815
1816 let might_be_alive = if self.body.local_decls[root_place.local].is_ref_to_thread_local() {
1822 root_place.projection = TyCtxtConsts::DEREF_PROJECTION;
1826 true
1827 } else {
1828 false
1829 };
1830
1831 let sd = if might_be_alive { Deep } else { Shallow(None) };
1832
1833 if places_conflict::borrow_conflicts_with_place(
1834 self.infcx.tcx,
1835 self.body,
1836 place,
1837 borrow.kind,
1838 root_place,
1839 sd,
1840 places_conflict::PlaceConflictBias::Overlap,
1841 ) {
1842 debug!("check_for_invalidation_at_exit({:?}): INVALID", place);
1843 let span = self.infcx.tcx.sess.source_map().end_point(span);
1846 self.report_borrowed_value_does_not_live_long_enough(
1847 location,
1848 borrow,
1849 (place, span),
1850 None,
1851 )
1852 }
1853 }
1854
1855 fn check_for_local_borrow(&mut self, borrow: &BorrowData<'tcx>, yield_span: Span) {
1858 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:1858",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1858u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("check_for_local_borrow({0:?})",
borrow) as &dyn Value))])
});
} else { ; }
};debug!("check_for_local_borrow({:?})", borrow);
1859
1860 if borrow_of_local_data(borrow.borrowed_place) {
1861 let err = self.cannot_borrow_across_coroutine_yield(
1862 self.retrieve_borrow_spans(borrow).var_or_use(),
1863 yield_span,
1864 );
1865
1866 self.buffer_error(err);
1867 }
1868 }
1869
1870 fn check_activations(&mut self, location: Location, span: Span, state: &BorrowckDomain) {
1871 for &borrow_index in self.borrow_set.activations_at_location(location) {
1875 let borrow = &self.borrow_set[borrow_index];
1876
1877 if !match borrow.kind {
BorrowKind::Shared | BorrowKind::Fake(_) => false,
BorrowKind::Mut { .. } => true,
} {
::core::panicking::panic("assertion failed: match borrow.kind {\n BorrowKind::Shared | BorrowKind::Fake(_) => false,\n BorrowKind::Mut { .. } => true,\n}")
};assert!(match borrow.kind {
1879 BorrowKind::Shared | BorrowKind::Fake(_) => false,
1880 BorrowKind::Mut { .. } => true,
1881 });
1882
1883 self.access_place(
1884 location,
1885 (borrow.borrowed_place, span),
1886 (Deep, Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index)),
1887 LocalMutationIsAllowed::No,
1888 state,
1889 );
1890 }
1894 }
1895
1896 fn check_movable_place(&mut self, location: Location, place: Place<'tcx>) {
1897 use IllegalMoveOriginKind::*;
1898
1899 let body = self.body;
1900 let tcx = self.infcx.tcx;
1901 let mut place_ty = PlaceTy::from_ty(body.local_decls[place.local].ty);
1902 for (place_ref, elem) in place.iter_projections() {
1903 match elem {
1904 ProjectionElem::Deref => match place_ty.ty.kind() {
1905 ty::Ref(..) | ty::RawPtr(..) => {
1906 self.move_errors.push(MoveError::new(
1907 place,
1908 location,
1909 BorrowedContent {
1910 target_place: place_ref.project_deeper(&[elem], tcx),
1911 },
1912 ));
1913 return;
1914 }
1915 ty::Adt(adt, _) => {
1916 if !adt.is_box() {
1917 ::rustc_middle::util::bug::bug_fmt(format_args!("Adt should be a box type when Place is deref"));bug!("Adt should be a box type when Place is deref");
1918 }
1919 }
1920 ty::Bool
1921 | ty::Char
1922 | ty::Int(_)
1923 | ty::Uint(_)
1924 | ty::Float(_)
1925 | ty::Foreign(_)
1926 | ty::Str
1927 | ty::Array(_, _)
1928 | ty::Pat(_, _)
1929 | ty::Slice(_)
1930 | ty::FnDef(_, _)
1931 | ty::FnPtr(..)
1932 | ty::Dynamic(_, _)
1933 | ty::Closure(_, _)
1934 | ty::CoroutineClosure(_, _)
1935 | ty::Coroutine(_, _)
1936 | ty::CoroutineWitness(..)
1937 | ty::Never
1938 | ty::Tuple(_)
1939 | ty::UnsafeBinder(_)
1940 | ty::Alias(_, _)
1941 | ty::Param(_)
1942 | ty::Bound(_, _)
1943 | ty::Infer(_)
1944 | ty::Error(_)
1945 | ty::Placeholder(_) => {
1946 ::rustc_middle::util::bug::bug_fmt(format_args!("When Place is Deref it\'s type shouldn\'t be {0:#?}",
place_ty))bug!("When Place is Deref it's type shouldn't be {place_ty:#?}")
1947 }
1948 },
1949 ProjectionElem::Field(_, _) => match place_ty.ty.kind() {
1950 ty::Adt(adt, _) => {
1951 if adt.has_dtor(tcx) {
1952 self.move_errors.push(MoveError::new(
1953 place,
1954 location,
1955 InteriorOfTypeWithDestructor { container_ty: place_ty.ty },
1956 ));
1957 return;
1958 }
1959 }
1960 ty::Closure(..)
1961 | ty::CoroutineClosure(..)
1962 | ty::Coroutine(_, _)
1963 | ty::Tuple(_) => (),
1964 ty::Bool
1965 | ty::Char
1966 | ty::Int(_)
1967 | ty::Uint(_)
1968 | ty::Float(_)
1969 | ty::Foreign(_)
1970 | ty::Str
1971 | ty::Array(_, _)
1972 | ty::Pat(_, _)
1973 | ty::Slice(_)
1974 | ty::RawPtr(_, _)
1975 | ty::Ref(_, _, _)
1976 | ty::FnDef(_, _)
1977 | ty::FnPtr(..)
1978 | ty::Dynamic(_, _)
1979 | ty::CoroutineWitness(..)
1980 | ty::Never
1981 | ty::UnsafeBinder(_)
1982 | ty::Alias(_, _)
1983 | ty::Param(_)
1984 | ty::Bound(_, _)
1985 | ty::Infer(_)
1986 | ty::Error(_)
1987 | ty::Placeholder(_) => ::rustc_middle::util::bug::bug_fmt(format_args!("When Place contains ProjectionElem::Field it\'s type shouldn\'t be {0:#?}",
place_ty))bug!(
1988 "When Place contains ProjectionElem::Field it's type shouldn't be {place_ty:#?}"
1989 ),
1990 },
1991 ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {
1992 match place_ty.ty.kind() {
1993 ty::Slice(_) => {
1994 self.move_errors.push(MoveError::new(
1995 place,
1996 location,
1997 InteriorOfSliceOrArray { ty: place_ty.ty, is_index: false },
1998 ));
1999 return;
2000 }
2001 ty::Array(_, _) => (),
2002 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("Unexpected type {0:#?}",
place_ty.ty))bug!("Unexpected type {:#?}", place_ty.ty),
2003 }
2004 }
2005 ProjectionElem::Index(_) => match place_ty.ty.kind() {
2006 ty::Array(..) | ty::Slice(..) => {
2007 self.move_errors.push(MoveError::new(
2008 place,
2009 location,
2010 InteriorOfSliceOrArray { ty: place_ty.ty, is_index: true },
2011 ));
2012 return;
2013 }
2014 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("Unexpected type {0:#?}",
place_ty))bug!("Unexpected type {place_ty:#?}"),
2015 },
2016 ProjectionElem::OpaqueCast(_)
2020 | ProjectionElem::Downcast(_, _)
2021 | ProjectionElem::UnwrapUnsafeBinder(_) => (),
2022 }
2023
2024 place_ty = place_ty.projection_ty(tcx, elem);
2025 }
2026 }
2027
2028 fn check_if_full_path_is_moved(
2029 &mut self,
2030 location: Location,
2031 desired_action: InitializationRequiringAction,
2032 place_span: (PlaceRef<'tcx>, Span),
2033 state: &BorrowckDomain,
2034 ) {
2035 let maybe_uninits = &state.uninits;
2036
2037 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:2072",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(2072u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("check_if_full_path_is_moved place: {0:?}",
place_span.0) as &dyn Value))])
});
} else { ; }
};debug!("check_if_full_path_is_moved place: {:?}", place_span.0);
2073 let (prefix, mpi) = self.move_path_closest_to(place_span.0);
2074 if maybe_uninits.contains(mpi) {
2075 self.report_use_of_moved_or_uninitialized(
2076 location,
2077 desired_action,
2078 (prefix, place_span.0, place_span.1),
2079 mpi,
2080 );
2081 } }
2088
2089 fn check_if_subslice_element_is_moved(
2095 &mut self,
2096 location: Location,
2097 desired_action: InitializationRequiringAction,
2098 place_span: (PlaceRef<'tcx>, Span),
2099 maybe_uninits: &MixedBitSet<MovePathIndex>,
2100 from: u64,
2101 to: u64,
2102 ) {
2103 if let Some(mpi) = self.move_path_for_place(place_span.0) {
2104 let move_paths = &self.move_data.move_paths;
2105
2106 let root_path = &move_paths[mpi];
2107 for (child_mpi, child_move_path) in root_path.children(move_paths) {
2108 let last_proj = child_move_path.place.projection.last().unwrap();
2109 if let ProjectionElem::ConstantIndex { offset, from_end, .. } = last_proj {
2110 if true {
if !!from_end {
{
::core::panicking::panic_fmt(format_args!("Array constant indexing shouldn\'t be `from_end`."));
}
};
};debug_assert!(!from_end, "Array constant indexing shouldn't be `from_end`.");
2111
2112 if (from..to).contains(offset) {
2113 let uninit_child =
2114 self.move_data.find_in_move_path_or_its_descendants(child_mpi, |mpi| {
2115 maybe_uninits.contains(mpi)
2116 });
2117
2118 if let Some(uninit_child) = uninit_child {
2119 self.report_use_of_moved_or_uninitialized(
2120 location,
2121 desired_action,
2122 (place_span.0, place_span.0, place_span.1),
2123 uninit_child,
2124 );
2125 return; }
2127 }
2128 }
2129 }
2130 }
2131 }
2132
2133 fn check_if_path_or_subpath_is_moved(
2134 &mut self,
2135 location: Location,
2136 desired_action: InitializationRequiringAction,
2137 place_span: (PlaceRef<'tcx>, Span),
2138 state: &BorrowckDomain,
2139 ) {
2140 let maybe_uninits = &state.uninits;
2141
2142 self.check_if_full_path_is_moved(location, desired_action, place_span, state);
2158
2159 if let Some((place_base, ProjectionElem::Subslice { from, to, from_end: false })) =
2160 place_span.0.last_projection()
2161 {
2162 let place_ty = place_base.ty(self.body(), self.infcx.tcx);
2163 if let ty::Array(..) = place_ty.ty.kind() {
2164 self.check_if_subslice_element_is_moved(
2165 location,
2166 desired_action,
2167 (place_base, place_span.1),
2168 maybe_uninits,
2169 from,
2170 to,
2171 );
2172 return;
2173 }
2174 }
2175
2176 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:2185",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(2185u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("check_if_path_or_subpath_is_moved place: {0:?}",
place_span.0) as &dyn Value))])
});
} else { ; }
};debug!("check_if_path_or_subpath_is_moved place: {:?}", place_span.0);
2186 if let Some(mpi) = self.move_path_for_place(place_span.0) {
2187 let uninit_mpi = self
2188 .move_data
2189 .find_in_move_path_or_its_descendants(mpi, |mpi| maybe_uninits.contains(mpi));
2190
2191 if let Some(uninit_mpi) = uninit_mpi {
2192 self.report_use_of_moved_or_uninitialized(
2193 location,
2194 desired_action,
2195 (place_span.0, place_span.0, place_span.1),
2196 uninit_mpi,
2197 );
2198 return; }
2200 }
2201 }
2202
2203 fn move_path_closest_to(&mut self, place: PlaceRef<'tcx>) -> (PlaceRef<'tcx>, MovePathIndex) {
2214 match self.move_data.rev_lookup.find(place) {
2215 LookupResult::Parent(Some(mpi)) | LookupResult::Exact(mpi) => {
2216 (self.move_data.move_paths[mpi].place.as_ref(), mpi)
2217 }
2218 LookupResult::Parent(None) => {
::core::panicking::panic_fmt(format_args!("should have move path for every Local"));
}panic!("should have move path for every Local"),
2219 }
2220 }
2221
2222 fn move_path_for_place(&mut self, place: PlaceRef<'tcx>) -> Option<MovePathIndex> {
2223 match self.move_data.rev_lookup.find(place) {
2228 LookupResult::Parent(_) => None,
2229 LookupResult::Exact(mpi) => Some(mpi),
2230 }
2231 }
2232
2233 fn check_if_assigned_path_is_moved(
2234 &mut self,
2235 location: Location,
2236 (place, span): (Place<'tcx>, Span),
2237 state: &BorrowckDomain,
2238 ) {
2239 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:2239",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(2239u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("check_if_assigned_path_is_moved place: {0:?}",
place) as &dyn Value))])
});
} else { ; }
};debug!("check_if_assigned_path_is_moved place: {:?}", place);
2240
2241 for (place_base, elem) in place.iter_projections().rev() {
2243 match elem {
2244 ProjectionElem::Index(_)
2245 | ProjectionElem::OpaqueCast(_)
2246 | ProjectionElem::ConstantIndex { .. }
2248 | ProjectionElem::Downcast(_, _) =>
2252 {}
2253
2254 ProjectionElem::UnwrapUnsafeBinder(_) => {
2255 check_parent_of_field(self, location, place_base, span, state);
2256 }
2257
2258 ProjectionElem::Deref => {
2260 self.check_if_full_path_is_moved(
2261 location,
2262 InitializationRequiringAction::Use,
2263 (place_base, span),
2264 state,
2265 );
2266 break;
2269 }
2270
2271 ProjectionElem::Subslice { .. } => {
2272 {
::core::panicking::panic_fmt(format_args!("we don\'t allow assignments to subslices, location: {0:?}",
location));
};panic!("we don't allow assignments to subslices, location: {location:?}");
2273 }
2274
2275 ProjectionElem::Field(..) => {
2276 let tcx = self.infcx.tcx;
2280 let base_ty = place_base.ty(self.body(), tcx).ty;
2281 match base_ty.kind() {
2282 ty::Adt(def, _) if def.has_dtor(tcx) => {
2283 self.check_if_path_or_subpath_is_moved(
2284 location,
2285 InitializationRequiringAction::Assignment,
2286 (place_base, span),
2287 state,
2288 );
2289
2290 break;
2293 }
2294
2295 ty::Adt(..) | ty::Tuple(..) => {
2298 check_parent_of_field(self, location, place_base, span, state);
2299 }
2300
2301 _ => {}
2302 }
2303 }
2304 }
2305 }
2306
2307 fn check_parent_of_field<'a, 'tcx>(
2308 this: &mut MirBorrowckCtxt<'a, '_, 'tcx>,
2309 location: Location,
2310 base: PlaceRef<'tcx>,
2311 span: Span,
2312 state: &BorrowckDomain,
2313 ) {
2314 let maybe_uninits = &state.uninits;
2346
2347 let mut shortest_uninit_seen = None;
2350 for prefix in this.prefixes(base, PrefixSet::Shallow) {
2351 let Some(mpi) = this.move_path_for_place(prefix) else { continue };
2352
2353 if maybe_uninits.contains(mpi) {
2354 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:2354",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(2354u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("check_parent_of_field updating shortest_uninit_seen from {0:?} to {1:?}",
shortest_uninit_seen, Some((prefix, mpi))) as &dyn Value))])
});
} else { ; }
};debug!(
2355 "check_parent_of_field updating shortest_uninit_seen from {:?} to {:?}",
2356 shortest_uninit_seen,
2357 Some((prefix, mpi))
2358 );
2359 shortest_uninit_seen = Some((prefix, mpi));
2360 } else {
2361 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:2361",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(2361u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("check_parent_of_field {0:?} is definitely initialized",
(prefix, mpi)) as &dyn Value))])
});
} else { ; }
};debug!("check_parent_of_field {:?} is definitely initialized", (prefix, mpi));
2362 }
2363 }
2364
2365 if let Some((prefix, mpi)) = shortest_uninit_seen {
2366 let tcx = this.infcx.tcx;
2372 if base.ty(this.body(), tcx).ty.is_union()
2373 && this.move_data.path_map[mpi].iter().any(|moi| {
2374 this.move_data.moves[*moi].source.is_predecessor_of(location, this.body)
2375 })
2376 {
2377 return;
2378 }
2379
2380 this.report_use_of_moved_or_uninitialized(
2381 location,
2382 InitializationRequiringAction::PartialAssignment,
2383 (prefix, base, span),
2384 mpi,
2385 );
2386
2387 this.used_mut.insert(base.local);
2391 }
2392 }
2393 }
2394
2395 fn check_access_permissions(
2399 &mut self,
2400 (place, span): (Place<'tcx>, Span),
2401 kind: ReadOrWrite,
2402 is_local_mutation_allowed: LocalMutationIsAllowed,
2403 state: &BorrowckDomain,
2404 location: Location,
2405 ) -> bool {
2406 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:2406",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(2406u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("check_access_permissions({0:?}, {1:?}, is_local_mutation_allowed: {2:?})",
place, kind, is_local_mutation_allowed) as &dyn Value))])
});
} else { ; }
};debug!(
2407 "check_access_permissions({:?}, {:?}, is_local_mutation_allowed: {:?})",
2408 place, kind, is_local_mutation_allowed
2409 );
2410
2411 let error_access;
2412 let the_place_err;
2413
2414 match kind {
2415 Reservation(WriteKind::MutableBorrow(BorrowKind::Mut { kind: mut_borrow_kind }))
2416 | Write(WriteKind::MutableBorrow(BorrowKind::Mut { kind: mut_borrow_kind })) => {
2417 let is_local_mutation_allowed = match mut_borrow_kind {
2418 MutBorrowKind::ClosureCapture => LocalMutationIsAllowed::Yes,
2422 MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow => {
2423 is_local_mutation_allowed
2424 }
2425 };
2426 match self.is_mutable(place.as_ref(), is_local_mutation_allowed) {
2427 Ok(root_place) => {
2428 self.add_used_mut(root_place, state);
2429 return false;
2430 }
2431 Err(place_err) => {
2432 error_access = AccessKind::MutableBorrow;
2433 the_place_err = place_err;
2434 }
2435 }
2436 }
2437 Reservation(WriteKind::Mutate) | Write(WriteKind::Mutate) => {
2438 match self.is_mutable(place.as_ref(), is_local_mutation_allowed) {
2439 Ok(root_place) => {
2440 self.add_used_mut(root_place, state);
2441 return false;
2442 }
2443 Err(place_err) => {
2444 error_access = AccessKind::Mutate;
2445 the_place_err = place_err;
2446 }
2447 }
2448 }
2449
2450 Reservation(
2451 WriteKind::Move
2452 | WriteKind::Replace
2453 | WriteKind::StorageDeadOrDrop
2454 | WriteKind::MutableBorrow(BorrowKind::Shared)
2455 | WriteKind::MutableBorrow(BorrowKind::Fake(_)),
2456 )
2457 | Write(
2458 WriteKind::Move
2459 | WriteKind::Replace
2460 | WriteKind::StorageDeadOrDrop
2461 | WriteKind::MutableBorrow(BorrowKind::Shared)
2462 | WriteKind::MutableBorrow(BorrowKind::Fake(_)),
2463 ) => {
2464 if self.is_mutable(place.as_ref(), is_local_mutation_allowed).is_err()
2465 && !self.has_buffered_diags()
2466 {
2467 self.dcx().span_delayed_bug(
2473 span,
2474 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Accessing `{0:?}` with the kind `{1:?}` shouldn\'t be possible",
place, kind))
})format!(
2475 "Accessing `{place:?}` with the kind `{kind:?}` shouldn't be possible",
2476 ),
2477 );
2478 }
2479 return false;
2480 }
2481 Activation(..) => {
2482 return false;
2484 }
2485 Read(
2486 ReadKind::Borrow(BorrowKind::Mut { .. } | BorrowKind::Shared | BorrowKind::Fake(_))
2487 | ReadKind::Copy,
2488 ) => {
2489 return false;
2491 }
2492 }
2493
2494 let previously_initialized = self.is_local_ever_initialized(place.local, state);
2499
2500 if let Some(init_index) = previously_initialized {
2502 if let (AccessKind::Mutate, Some(_)) = (error_access, place.as_local()) {
2503 let init = &self.move_data.inits[init_index];
2506 let assigned_span = init.span(self.body);
2507 self.report_illegal_reassignment((place, span), assigned_span, place);
2508 } else {
2509 self.report_mutability_error(place, span, the_place_err, error_access, location)
2510 }
2511 true
2512 } else {
2513 false
2514 }
2515 }
2516
2517 fn is_local_ever_initialized(&self, local: Local, state: &BorrowckDomain) -> Option<InitIndex> {
2518 let mpi = self.move_data.rev_lookup.find_local(local)?;
2519 let ii = &self.move_data.init_path_map[mpi];
2520 ii.into_iter().find(|&&index| state.ever_inits.contains(index)).copied()
2521 }
2522
2523 fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, state: &BorrowckDomain) {
2525 match root_place {
2526 RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => {
2527 if is_local_mutation_allowed != LocalMutationIsAllowed::Yes
2531 && self.is_local_ever_initialized(local, state).is_some()
2532 {
2533 self.used_mut.insert(local);
2534 }
2535 }
2536 RootPlace {
2537 place_local: _,
2538 place_projection: _,
2539 is_local_mutation_allowed: LocalMutationIsAllowed::Yes,
2540 } => {}
2541 RootPlace {
2542 place_local,
2543 place_projection: place_projection @ [.., _],
2544 is_local_mutation_allowed: _,
2545 } => {
2546 if let Some(field) = self.is_upvar_field_projection(PlaceRef {
2547 local: place_local,
2548 projection: place_projection,
2549 }) {
2550 self.used_mut_upvars.push(field);
2551 }
2552 }
2553 }
2554 }
2555
2556 fn is_mutable(
2559 &self,
2560 place: PlaceRef<'tcx>,
2561 is_local_mutation_allowed: LocalMutationIsAllowed,
2562 ) -> Result<RootPlace<'tcx>, PlaceRef<'tcx>> {
2563 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:2563",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(2563u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("is_mutable: place={0:?}, is_local...={1:?}",
place, is_local_mutation_allowed) as &dyn Value))])
});
} else { ; }
};debug!("is_mutable: place={:?}, is_local...={:?}", place, is_local_mutation_allowed);
2564 match place.last_projection() {
2565 None => {
2566 let local = &self.body.local_decls[place.local];
2567 match local.mutability {
2568 Mutability::Not => match is_local_mutation_allowed {
2569 LocalMutationIsAllowed::Yes => Ok(RootPlace {
2570 place_local: place.local,
2571 place_projection: place.projection,
2572 is_local_mutation_allowed: LocalMutationIsAllowed::Yes,
2573 }),
2574 LocalMutationIsAllowed::ExceptUpvars => Ok(RootPlace {
2575 place_local: place.local,
2576 place_projection: place.projection,
2577 is_local_mutation_allowed: LocalMutationIsAllowed::ExceptUpvars,
2578 }),
2579 LocalMutationIsAllowed::No => Err(place),
2580 },
2581 Mutability::Mut => Ok(RootPlace {
2582 place_local: place.local,
2583 place_projection: place.projection,
2584 is_local_mutation_allowed,
2585 }),
2586 }
2587 }
2588 Some((place_base, elem)) => {
2589 match elem {
2590 ProjectionElem::Deref => {
2591 let base_ty = place_base.ty(self.body(), self.infcx.tcx).ty;
2592
2593 match base_ty.kind() {
2595 ty::Ref(_, _, mutbl) => {
2596 match mutbl {
2597 hir::Mutability::Not => Err(place),
2599 hir::Mutability::Mut => {
2602 let mode = match self.is_upvar_field_projection(place) {
2603 Some(field)
2604 if self.upvars[field.index()].is_by_ref() =>
2605 {
2606 is_local_mutation_allowed
2607 }
2608 _ => LocalMutationIsAllowed::Yes,
2609 };
2610
2611 self.is_mutable(place_base, mode)
2612 }
2613 }
2614 }
2615 ty::RawPtr(_, mutbl) => {
2616 match mutbl {
2617 hir::Mutability::Not => Err(place),
2619 hir::Mutability::Mut => Ok(RootPlace {
2622 place_local: place.local,
2623 place_projection: place.projection,
2624 is_local_mutation_allowed,
2625 }),
2626 }
2627 }
2628 _ if base_ty.is_box() => {
2630 self.is_mutable(place_base, is_local_mutation_allowed)
2631 }
2632 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("Deref of unexpected type: {0:?}",
base_ty))bug!("Deref of unexpected type: {:?}", base_ty),
2634 }
2635 }
2636 ProjectionElem::Field(FieldIdx::ZERO, _)
2639 if let Some(adt) =
2640 place_base.ty(self.body(), self.infcx.tcx).ty.ty_adt_def()
2641 && adt.is_pin()
2642 && self.infcx.tcx.features().pin_ergonomics() =>
2643 {
2644 self.is_mutable(place_base, is_local_mutation_allowed)
2645 }
2646 ProjectionElem::Field(..)
2649 | ProjectionElem::Index(..)
2650 | ProjectionElem::ConstantIndex { .. }
2651 | ProjectionElem::Subslice { .. }
2652 | ProjectionElem::OpaqueCast { .. }
2653 | ProjectionElem::Downcast(..)
2654 | ProjectionElem::UnwrapUnsafeBinder(_) => {
2655 let upvar_field_projection = self.is_upvar_field_projection(place);
2656 if let Some(field) = upvar_field_projection {
2657 let upvar = &self.upvars[field.index()];
2658 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/lib.rs:2658",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(2658u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::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!("is_mutable: upvar.mutability={0:?} local_mutation_is_allowed={1:?} place={2:?}, place_base={3:?}",
upvar, is_local_mutation_allowed, place, place_base) as
&dyn Value))])
});
} else { ; }
};debug!(
2659 "is_mutable: upvar.mutability={:?} local_mutation_is_allowed={:?} \
2660 place={:?}, place_base={:?}",
2661 upvar, is_local_mutation_allowed, place, place_base
2662 );
2663 match (upvar.mutability, is_local_mutation_allowed) {
2664 (
2665 Mutability::Not,
2666 LocalMutationIsAllowed::No
2667 | LocalMutationIsAllowed::ExceptUpvars,
2668 ) => Err(place),
2669 (Mutability::Not, LocalMutationIsAllowed::Yes)
2670 | (Mutability::Mut, _) => {
2671 let _ =
2690 self.is_mutable(place_base, is_local_mutation_allowed)?;
2691 Ok(RootPlace {
2692 place_local: place.local,
2693 place_projection: place.projection,
2694 is_local_mutation_allowed,
2695 })
2696 }
2697 }
2698 } else {
2699 self.is_mutable(place_base, is_local_mutation_allowed)
2700 }
2701 }
2702 }
2703 }
2704 }
2705 }
2706
2707 fn is_upvar_field_projection(&self, place_ref: PlaceRef<'tcx>) -> Option<FieldIdx> {
2712 path_utils::is_upvar_field_projection(self.infcx.tcx, &self.upvars, place_ref, self.body())
2713 }
2714
2715 fn dominators(&self) -> &Dominators<BasicBlock> {
2716 self.body.basic_blocks.dominators()
2718 }
2719
2720 fn lint_unused_mut(&self) {
2721 let tcx = self.infcx.tcx;
2722 let body = self.body;
2723 for local in body.mut_vars_and_args_iter().filter(|local| !self.used_mut.contains(local)) {
2724 let local_decl = &body.local_decls[local];
2725 let ClearCrossCrate::Set(SourceScopeLocalData { lint_root, .. }) =
2726 body.source_scopes[local_decl.source_info.scope].local_data
2727 else {
2728 continue;
2729 };
2730
2731 if self.local_excluded_from_unused_mut_lint(local) {
2733 continue;
2734 }
2735
2736 let span = local_decl.source_info.span;
2737 if span.desugaring_kind().is_some() {
2738 continue;
2740 }
2741
2742 let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);
2743
2744 tcx.emit_node_span_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span: mut_span })
2745 }
2746 }
2747}
2748
2749enum Overlap {
2751 Arbitrary,
2757 EqualOrDisjoint,
2762 Disjoint,
2765}