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