1#![allow(internal_features)]
5#![feature(box_patterns)]
6#![feature(default_field_values)]
7#![feature(file_buffered)]
8#![feature(negative_impls)]
9#![feature(never_type)]
10#![feature(rustc_attrs)]
11#![feature(stmt_expr_attributes)]
12#![feature(try_blocks)]
13use std::borrow::Cow;
16use std::cell::{OnceCell, RefCell};
17use std::marker::PhantomData;
18use std::ops::{ControlFlow, Deref};
19use std::rc::Rc;
20
21use borrow_set::LocalsStateAtExit;
22use polonius_engine::AllFacts;
23use root_cx::BorrowCheckRootCtxt;
24use rustc_abi::FieldIdx;
25use rustc_data_structures::frozen::Frozen;
26use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
27use rustc_data_structures::graph::dominators::Dominators;
28use rustc_hir as hir;
29use rustc_hir::CRATE_HIR_ID;
30use rustc_hir::def_id::LocalDefId;
31use rustc_index::bit_set::MixedBitSet;
32use rustc_index::{IndexSlice, IndexVec};
33use rustc_infer::infer::outlives::env::RegionBoundPairs;
34use rustc_infer::infer::{
35 InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt,
36};
37use rustc_middle::mir::*;
38use rustc_middle::query::Providers;
39use rustc_middle::ty::{
40 self, ParamEnv, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitable, TypingMode, fold_regions,
41};
42use rustc_middle::{bug, span_bug};
43use rustc_mir_dataflow::impls::{EverInitializedPlaces, MaybeUninitializedPlaces};
44use rustc_mir_dataflow::move_paths::{
45 InitIndex, InitLocation, LookupResult, MoveData, MovePathIndex,
46};
47use rustc_mir_dataflow::points::DenseLocationMap;
48use rustc_mir_dataflow::{Analysis, EntryStates, Results, ResultsVisitor, visit_results};
49use rustc_session::lint::builtin::{TAIL_EXPR_DROP_ORDER, UNUSED_MUT};
50use rustc_span::{ErrorGuaranteed, Span, Symbol};
51use smallvec::SmallVec;
52use tracing::{debug, instrument};
53
54use crate::borrow_set::{BorrowData, BorrowSet};
55use crate::consumers::{BodyWithBorrowckFacts, RustcFacts};
56use crate::dataflow::{BorrowIndex, Borrowck, BorrowckDomain, Borrows};
57use crate::diagnostics::{
58 AccessKind, BorrowckDiagnosticsBuffer, IllegalMoveOriginKind, MoveError, RegionName,
59};
60use crate::path_utils::*;
61use crate::place_ext::PlaceExt;
62use crate::places_conflict::{PlaceConflictBias, places_conflict};
63use crate::polonius::PoloniusContext;
64use crate::polonius::legacy::{
65 PoloniusFacts, PoloniusFactsExt, PoloniusLocationTable, PoloniusOutput,
66};
67use crate::prefixes::PrefixSet;
68use crate::region_infer::RegionInferenceContext;
69use crate::region_infer::opaque_types::DeferredOpaqueTypeError;
70use crate::renumber::RegionCtxt;
71use crate::session_diagnostics::VarNeedNotMut;
72use crate::type_check::free_region_relations::UniversalRegionRelations;
73use crate::type_check::{Locations, MirTypeckRegionConstraints, MirTypeckResults};
74
75mod borrow_set;
76mod borrowck_errors;
77mod constraints;
78mod dataflow;
79mod def_use;
80mod diagnostics;
81mod handle_placeholders;
82mod nll;
83mod path_utils;
84mod place_ext;
85mod places_conflict;
86mod polonius;
87mod prefixes;
88mod region_infer;
89mod renumber;
90mod root_cx;
91mod session_diagnostics;
92mod type_check;
93mod universal_regions;
94mod used_muts;
95
96pub mod consumers;
98
99struct TyCtxtConsts<'tcx>(PhantomData<&'tcx ()>);
101
102impl<'tcx> TyCtxtConsts<'tcx> {
103 const DEREF_PROJECTION: &'tcx [PlaceElem<'tcx>; 1] = &[ProjectionElem::Deref];
104}
105
106pub fn provide(providers: &mut Providers) {
107 *providers = Providers { mir_borrowck, ..*providers };
108}
109
110fn mir_borrowck(
114 tcx: TyCtxt<'_>,
115 def: LocalDefId,
116) -> Result<&FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'_>>, ErrorGuaranteed> {
117 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()));
118 let (input_body, _) = tcx.mir_promoted(def);
119 {
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:119",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(119u32),
::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));
120
121 tcx.ensure_result().check_coroutine_obligations(def)?;
125
126 let input_body: &Body<'_> = &input_body.borrow();
127 if let Some(guar) = input_body.tainted_by_errors {
128 {
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:128",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(128u32),
::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");
129 Err(guar)
130 } else if input_body.should_skip() {
131 {
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:131",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(131u32),
::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");
132 let opaque_types = Default::default();
133 Ok(tcx.arena.alloc(opaque_types))
134 } else {
135 let mut root_cx = BorrowCheckRootCtxt::new(tcx, def, None);
136 root_cx.do_mir_borrowck();
137 root_cx.finalize()
138 }
139}
140
141#[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)]
144struct PropagatedBorrowCheckResults<'tcx> {
145 closure_requirements: Option<ClosureRegionRequirements<'tcx>>,
146 used_mut_upvars: SmallVec<[FieldIdx; 8]>,
147}
148
149type DeferredClosureRequirements<'tcx> = Vec<(LocalDefId, ty::GenericArgsRef<'tcx>, Locations)>;
150
151#[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)]
194pub struct ClosureRegionRequirements<'tcx> {
195 pub num_external_vids: usize,
201
202 pub outlives_requirements: Vec<ClosureOutlivesRequirement<'tcx>>,
205}
206
207#[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)]
210pub struct ClosureOutlivesRequirement<'tcx> {
211 pub subject: ClosureOutlivesSubject<'tcx>,
213
214 pub outlived_free_region: ty::RegionVid,
216
217 pub blame_span: Span,
219
220 pub category: ConstraintCategory<'tcx>,
222}
223
224#[cfg(target_pointer_width = "64")]
226const _: [(); 16] = [(); ::std::mem::size_of::<ConstraintCategory<'_>>()];rustc_data_structures::static_assert_size!(ConstraintCategory<'_>, 16);
227
228#[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)]
231pub enum ClosureOutlivesSubject<'tcx> {
232 Ty(ClosureOutlivesSubjectTy<'tcx>),
236
237 Region(ty::RegionVid),
240}
241
242#[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)]
248pub struct ClosureOutlivesSubjectTy<'tcx> {
249 inner: Ty<'tcx>,
250}
251impl<'tcx, I> !TypeVisitable<I> for ClosureOutlivesSubjectTy<'tcx> {}
254impl<'tcx, I> !TypeFoldable<I> for ClosureOutlivesSubjectTy<'tcx> {}
255
256impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
257 pub fn bind(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self {
260 let inner = fold_regions(tcx, ty, |r, depth| match r.kind() {
261 ty::ReVar(vid) => {
262 let br = ty::BoundRegion {
263 var: ty::BoundVar::from_usize(vid.index()),
264 kind: ty::BoundRegionKind::Anon,
265 };
266 ty::Region::new_bound(tcx, depth, br)
267 }
268 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected region in ClosureOutlivesSubjectTy: {0:?}",
r))bug!("unexpected region in ClosureOutlivesSubjectTy: {r:?}"),
269 });
270
271 Self { inner }
272 }
273
274 pub fn instantiate(
275 self,
276 tcx: TyCtxt<'tcx>,
277 mut map: impl FnMut(ty::RegionVid) -> ty::Region<'tcx>,
278 ) -> Ty<'tcx> {
279 fold_regions(tcx, self.inner, |r, depth| match r.kind() {
280 ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), br) => {
281 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);
282 map(ty::RegionVid::from_usize(br.var.index()))
283 }
284 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected region {0:?}", r))bug!("unexpected region {r:?}"),
285 })
286 }
287}
288
289struct CollectRegionConstraintsResult<'tcx> {
290 infcx: BorrowckInferCtxt<'tcx>,
291 body_owned: Body<'tcx>,
292 promoted: IndexVec<Promoted, Body<'tcx>>,
293 move_data: MoveData<'tcx>,
294 borrow_set: BorrowSet<'tcx>,
295 location_table: PoloniusLocationTable,
296 location_map: Rc<DenseLocationMap>,
297 universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
298 region_bound_pairs: Frozen<RegionBoundPairs<'tcx>>,
299 known_type_outlives_obligations: Frozen<Vec<ty::PolyTypeOutlivesPredicate<'tcx>>>,
300 constraints: MirTypeckRegionConstraints<'tcx>,
301 deferred_closure_requirements: DeferredClosureRequirements<'tcx>,
302 deferred_opaque_type_errors: Vec<DeferredOpaqueTypeError<'tcx>>,
303 polonius_facts: Option<AllFacts<RustcFacts>>,
304 polonius_context: Option<PoloniusContext>,
305}
306
307fn borrowck_collect_region_constraints<'tcx>(
311 root_cx: &mut BorrowCheckRootCtxt<'tcx>,
312 def: LocalDefId,
313) -> CollectRegionConstraintsResult<'tcx> {
314 let tcx = root_cx.tcx;
315 let infcx = BorrowckInferCtxt::new(tcx, def, root_cx.root_def_id());
316 let (input_body, promoted) = tcx.mir_promoted(def);
317 let input_body: &Body<'_> = &input_body.borrow();
318 let input_promoted: &IndexSlice<_, _> = &promoted.borrow();
319 if let Some(e) = input_body.tainted_by_errors {
320 infcx.set_tainted_by_errors(e);
321 root_cx.set_tainted_by_errors(e);
322 }
323
324 let mut body_owned = input_body.clone();
329 let mut promoted = input_promoted.to_owned();
330 let universal_regions = nll::replace_regions_in_mir(&infcx, &mut body_owned, &mut promoted);
331 let body = &body_owned; let location_table = PoloniusLocationTable::new(body);
334
335 let move_data = MoveData::gather_moves(body, tcx, |_| true);
336
337 let locals_are_invalidated_at_exit = tcx.hir_body_owner_kind(def).is_fn_or_closure();
338 let borrow_set = BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &move_data);
339
340 let location_map = Rc::new(DenseLocationMap::new(body));
341
342 let polonius_input = root_cx.consumer.as_ref().map_or(false, |c| c.polonius_input())
343 || infcx.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled();
344 let mut polonius_facts =
345 (polonius_input || PoloniusFacts::enabled(infcx.tcx)).then_some(PoloniusFacts::default());
346
347 let MirTypeckResults {
349 constraints,
350 universal_region_relations,
351 region_bound_pairs,
352 known_type_outlives_obligations,
353 deferred_closure_requirements,
354 polonius_context,
355 } = type_check::type_check(
356 root_cx,
357 &infcx,
358 body,
359 &promoted,
360 universal_regions,
361 &location_table,
362 &borrow_set,
363 &mut polonius_facts,
364 &move_data,
365 Rc::clone(&location_map),
366 );
367
368 CollectRegionConstraintsResult {
369 infcx,
370 body_owned,
371 promoted,
372 move_data,
373 borrow_set,
374 location_table,
375 location_map,
376 universal_region_relations,
377 region_bound_pairs,
378 known_type_outlives_obligations,
379 constraints,
380 deferred_closure_requirements,
381 deferred_opaque_type_errors: Default::default(),
382 polonius_facts,
383 polonius_context,
384 }
385}
386
387fn borrowck_check_region_constraints<'tcx>(
391 root_cx: &mut BorrowCheckRootCtxt<'tcx>,
392 CollectRegionConstraintsResult {
393 infcx,
394 body_owned,
395 promoted,
396 move_data,
397 borrow_set,
398 location_table,
399 location_map,
400 universal_region_relations,
401 region_bound_pairs: _,
402 known_type_outlives_obligations: _,
403 constraints,
404 deferred_closure_requirements,
405 deferred_opaque_type_errors,
406 polonius_facts,
407 polonius_context,
408 }: CollectRegionConstraintsResult<'tcx>,
409) -> PropagatedBorrowCheckResults<'tcx> {
410 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());
411 if !deferred_closure_requirements.is_empty() {
::core::panicking::panic("assertion failed: deferred_closure_requirements.is_empty()")
};assert!(deferred_closure_requirements.is_empty());
412 let tcx = root_cx.tcx;
413 let body = &body_owned;
414 let def = body.source.def_id().expect_local();
415
416 let nll::NllOutput {
419 regioncx,
420 polonius_input,
421 polonius_output,
422 opt_closure_req,
423 nll_errors,
424 polonius_context,
425 } = nll::compute_regions(
426 root_cx,
427 &infcx,
428 body,
429 &location_table,
430 &move_data,
431 &borrow_set,
432 location_map,
433 universal_region_relations,
434 constraints,
435 polonius_facts,
436 polonius_context,
437 );
438
439 nll::dump_nll_mir(&infcx, body, ®ioncx, &opt_closure_req, &borrow_set);
442 polonius::dump_polonius_mir(
443 &infcx,
444 body,
445 ®ioncx,
446 &opt_closure_req,
447 &borrow_set,
448 polonius_context.as_ref(),
449 );
450
451 nll::dump_annotation(&infcx, body, ®ioncx, &opt_closure_req);
454
455 let movable_coroutine = body.coroutine.is_some()
456 && tcx.coroutine_movability(def.to_def_id()) == hir::Movability::Movable;
457
458 let diags_buffer = &mut BorrowckDiagnosticsBuffer::default();
459 for promoted_body in &promoted {
462 use rustc_middle::mir::visit::Visitor;
463 let move_data = MoveData::gather_moves(promoted_body, tcx, |_| true);
467 let mut promoted_mbcx = MirBorrowckCtxt {
468 root_cx,
469 infcx: &infcx,
470 body: promoted_body,
471 move_data: &move_data,
472 location_table: &location_table,
474 movable_coroutine,
475 fn_self_span_reported: Default::default(),
476 access_place_error_reported: Default::default(),
477 reservation_error_reported: Default::default(),
478 uninitialized_error_reported: Default::default(),
479 regioncx: ®ioncx,
480 used_mut: Default::default(),
481 used_mut_upvars: SmallVec::new(),
482 borrow_set: &borrow_set,
483 upvars: &[],
484 local_names: OnceCell::from(IndexVec::from_elem(None, &promoted_body.local_decls)),
485 region_names: RefCell::default(),
486 next_region_name: RefCell::new(1),
487 polonius_output: None,
488 move_errors: Vec::new(),
489 diags_buffer,
490 polonius_context: polonius_context.as_ref(),
491 };
492 struct MoveVisitor<'a, 'b, 'infcx, 'tcx> {
493 ctxt: &'a mut MirBorrowckCtxt<'b, 'infcx, 'tcx>,
494 }
495
496 impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, '_, 'tcx> {
497 fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
498 if let Operand::Move(place) = operand {
499 self.ctxt.check_movable_place(location, *place);
500 }
501 }
502 }
503 MoveVisitor { ctxt: &mut promoted_mbcx }.visit_body(promoted_body);
504 promoted_mbcx.report_move_errors();
505 }
506
507 let mut mbcx = MirBorrowckCtxt {
508 root_cx,
509 infcx: &infcx,
510 body,
511 move_data: &move_data,
512 location_table: &location_table,
513 movable_coroutine,
514 fn_self_span_reported: Default::default(),
515 access_place_error_reported: Default::default(),
516 reservation_error_reported: Default::default(),
517 uninitialized_error_reported: Default::default(),
518 regioncx: ®ioncx,
519 used_mut: Default::default(),
520 used_mut_upvars: SmallVec::new(),
521 borrow_set: &borrow_set,
522 upvars: tcx.closure_captures(def),
523 local_names: OnceCell::new(),
524 region_names: RefCell::default(),
525 next_region_name: RefCell::new(1),
526 move_errors: Vec::new(),
527 diags_buffer,
528 polonius_output: polonius_output.as_deref(),
529 polonius_context: polonius_context.as_ref(),
530 };
531
532 if nll_errors.is_empty() {
534 mbcx.report_opaque_type_errors(deferred_opaque_type_errors);
535 } else {
536 mbcx.report_region_errors(nll_errors);
537 }
538
539 let flow_results = get_flow_results(tcx, body, &move_data, &borrow_set, ®ioncx);
540 visit_results(
541 body,
542 traversal::reverse_postorder(body).map(|(bb, _)| bb),
543 &flow_results,
544 &mut mbcx,
545 );
546
547 mbcx.report_move_errors();
548
549 let temporary_used_locals: FxIndexSet<Local> = mbcx
555 .used_mut
556 .iter()
557 .filter(|&local| !mbcx.body.local_decls[*local].is_user_variable())
558 .cloned()
559 .collect();
560 let unused_mut_locals =
564 mbcx.body.mut_vars_iter().filter(|local| !mbcx.used_mut.contains(local)).collect();
565 mbcx.gather_used_muts(temporary_used_locals, unused_mut_locals);
566
567 {
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:567",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(567u32),
::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);
568 mbcx.lint_unused_mut();
569 if let Some(guar) = mbcx.emit_errors() {
570 mbcx.root_cx.set_tainted_by_errors(guar);
571 }
572
573 let result = PropagatedBorrowCheckResults {
574 closure_requirements: opt_closure_req,
575 used_mut_upvars: mbcx.used_mut_upvars,
576 };
577
578 if let Some(consumer) = &mut root_cx.consumer {
579 consumer.insert_body(
580 def,
581 BodyWithBorrowckFacts {
582 body: body_owned,
583 promoted,
584 borrow_set,
585 region_inference_context: regioncx,
586 location_table: polonius_input.as_ref().map(|_| location_table),
587 input_facts: polonius_input,
588 output_facts: polonius_output,
589 },
590 );
591 }
592
593 {
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:593",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(593u32),
::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);
594
595 result
596}
597
598fn get_flow_results<'a, 'tcx>(
599 tcx: TyCtxt<'tcx>,
600 body: &'a Body<'tcx>,
601 move_data: &'a MoveData<'tcx>,
602 borrow_set: &'a BorrowSet<'tcx>,
603 regioncx: &RegionInferenceContext<'tcx>,
604) -> Results<'tcx, Borrowck<'a, 'tcx>> {
605 let borrows = Borrows::new(tcx, body, regioncx, borrow_set).iterate_to_fixpoint(
608 tcx,
609 body,
610 Some("borrowck"),
611 );
612 let uninits = MaybeUninitializedPlaces::new(tcx, body, move_data).iterate_to_fixpoint(
613 tcx,
614 body,
615 Some("borrowck"),
616 );
617 let ever_inits = EverInitializedPlaces::new(body, move_data).iterate_to_fixpoint(
618 tcx,
619 body,
620 Some("borrowck"),
621 );
622
623 let analysis = Borrowck {
624 borrows: borrows.analysis,
625 uninits: uninits.analysis,
626 ever_inits: ever_inits.analysis,
627 };
628
629 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());
630 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());
631 let entry_states: EntryStates<_> =
632 ::itertools::__std_iter::IntoIterator::into_iter(borrows.entry_states).zip(uninits.entry_states).zip(ever_inits.entry_states).map(|((a,
b), b)| (a, b, b))itertools::izip!(borrows.entry_states, uninits.entry_states, ever_inits.entry_states)
633 .map(|(borrows, uninits, ever_inits)| BorrowckDomain { borrows, uninits, ever_inits })
634 .collect();
635
636 Results { analysis, entry_states }
637}
638
639pub(crate) struct BorrowckInferCtxt<'tcx> {
640 pub(crate) infcx: InferCtxt<'tcx>,
641 pub(crate) root_def_id: LocalDefId,
642 pub(crate) param_env: ParamEnv<'tcx>,
643 pub(crate) reg_var_to_origin: RefCell<FxIndexMap<ty::RegionVid, RegionCtxt>>,
644}
645
646impl<'tcx> BorrowckInferCtxt<'tcx> {
647 pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId, root_def_id: LocalDefId) -> Self {
648 let typing_mode = if tcx.use_typing_mode_borrowck() {
649 TypingMode::borrowck(tcx, def_id)
650 } else {
651 TypingMode::analysis_in_body(tcx, def_id)
652 };
653 let infcx = tcx.infer_ctxt().build(typing_mode);
654 let param_env = tcx.param_env(def_id);
655 BorrowckInferCtxt {
656 infcx,
657 root_def_id,
658 reg_var_to_origin: RefCell::new(Default::default()),
659 param_env,
660 }
661 }
662
663 pub(crate) fn next_region_var<F>(
664 &self,
665 origin: RegionVariableOrigin<'tcx>,
666 get_ctxt_fn: F,
667 ) -> ty::Region<'tcx>
668 where
669 F: Fn() -> RegionCtxt,
670 {
671 let next_region = self.infcx.next_region_var(origin);
672 let vid = next_region.as_var();
673
674 if truecfg!(debug_assertions) {
675 {
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:675",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(675u32),
::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);
676 let ctxt = get_ctxt_fn();
677 let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
678 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);
679 }
680
681 next_region
682 }
683
684 #[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(684u32),
::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:697",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(697u32),
::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")]
685 pub(crate) fn next_nll_region_var<F>(
686 &self,
687 origin: NllRegionVariableOrigin<'tcx>,
688 get_ctxt_fn: F,
689 ) -> ty::Region<'tcx>
690 where
691 F: Fn() -> RegionCtxt,
692 {
693 let next_region = self.infcx.next_nll_region_var(origin);
694 let vid = next_region.as_var();
695
696 if cfg!(debug_assertions) {
697 debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin);
698 let ctxt = get_ctxt_fn();
699 let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
700 assert_eq!(var_to_origin.insert(vid, ctxt), None);
701 }
702
703 next_region
704 }
705}
706
707impl<'tcx> Deref for BorrowckInferCtxt<'tcx> {
708 type Target = InferCtxt<'tcx>;
709
710 fn deref(&self) -> &Self::Target {
711 &self.infcx
712 }
713}
714
715pub(crate) struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
716 root_cx: &'a mut BorrowCheckRootCtxt<'tcx>,
717 infcx: &'infcx BorrowckInferCtxt<'tcx>,
718 body: &'a Body<'tcx>,
719 move_data: &'a MoveData<'tcx>,
720
721 location_table: &'a PoloniusLocationTable,
724
725 movable_coroutine: bool,
726 access_place_error_reported: FxIndexSet<(Place<'tcx>, Span)>,
732 reservation_error_reported: FxIndexSet<Place<'tcx>>,
740 fn_self_span_reported: FxIndexSet<Span>,
744 uninitialized_error_reported: FxIndexSet<Local>,
747 used_mut: FxIndexSet<Local>,
750 used_mut_upvars: SmallVec<[FieldIdx; 8]>,
753 regioncx: &'a RegionInferenceContext<'tcx>,
756
757 borrow_set: &'a BorrowSet<'tcx>,
759
760 upvars: &'tcx [&'tcx ty::CapturedPlace<'tcx>],
762
763 local_names: OnceCell<IndexVec<Local, Option<Symbol>>>,
765
766 region_names: RefCell<FxIndexMap<RegionVid, RegionName>>,
769
770 next_region_name: RefCell<usize>,
772
773 diags_buffer: &'a mut BorrowckDiagnosticsBuffer<'infcx, 'tcx>,
774 move_errors: Vec<MoveError<'tcx>>,
775
776 polonius_output: Option<&'a PoloniusOutput>,
778 polonius_context: Option<&'a PoloniusContext>,
780}
781
782impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a, '_, 'tcx> {
788 fn visit_after_early_statement_effect(
789 &mut self,
790 _analysis: &Borrowck<'a, 'tcx>,
791 state: &BorrowckDomain,
792 stmt: &Statement<'tcx>,
793 location: Location,
794 ) {
795 {
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:795",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(795u32),
::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);
796 let span = stmt.source_info.span;
797
798 self.check_activations(location, span, state);
799
800 match &stmt.kind {
801 StatementKind::Assign(box (lhs, rhs)) => {
802 self.consume_rvalue(location, (rhs, span), state);
803
804 self.mutate_place(location, (*lhs, span), Shallow(None), state);
805 }
806 StatementKind::FakeRead(box (_, place)) => {
807 self.check_if_path_or_subpath_is_moved(
818 location,
819 InitializationRequiringAction::Use,
820 (place.as_ref(), span),
821 state,
822 );
823 }
824 StatementKind::Intrinsic(box kind) => match kind {
825 NonDivergingIntrinsic::Assume(op) => {
826 self.consume_operand(location, (op, span), state);
827 }
828 NonDivergingIntrinsic::CopyNonOverlapping(..) => ::rustc_middle::util::bug::span_bug_fmt(span,
format_args!("Unexpected CopyNonOverlapping, should only appear after lower_intrinsics"))span_bug!(
829 span,
830 "Unexpected CopyNonOverlapping, should only appear after lower_intrinsics",
831 )
832 }
833 StatementKind::AscribeUserType(..)
835 | StatementKind::PlaceMention(..)
837 | StatementKind::Coverage(..)
839 | StatementKind::ConstEvalCounter
841 | StatementKind::StorageLive(..) => {}
842 StatementKind::BackwardIncompatibleDropHint { place, reason: BackwardIncompatibleDropReason::Edition2024 } => {
844 self.check_backward_incompatible_drop(location, **place, state);
845 }
846 StatementKind::StorageDead(local) => {
847 self.access_place(
848 location,
849 (Place::from(*local), span),
850 (Shallow(None), Write(WriteKind::StorageDeadOrDrop)),
851 LocalMutationIsAllowed::Yes,
852 state,
853 );
854 }
855 StatementKind::Nop
856 | StatementKind::Retag { .. }
857 | StatementKind::SetDiscriminant { .. } => {
858 ::rustc_middle::util::bug::bug_fmt(format_args!("Statement not allowed in this MIR phase"))bug!("Statement not allowed in this MIR phase")
859 }
860 }
861 }
862
863 fn visit_after_early_terminator_effect(
864 &mut self,
865 _analysis: &Borrowck<'a, 'tcx>,
866 state: &BorrowckDomain,
867 term: &Terminator<'tcx>,
868 loc: Location,
869 ) {
870 {
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:870",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(870u32),
::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);
871 let span = term.source_info.span;
872
873 self.check_activations(loc, span, state);
874
875 match &term.kind {
876 TerminatorKind::SwitchInt { discr, targets: _ } => {
877 self.consume_operand(loc, (discr, span), state);
878 }
879 TerminatorKind::Drop {
880 place,
881 target: _,
882 unwind: _,
883 replace,
884 drop: _,
885 async_fut: _,
886 } => {
887 {
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:887",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(887u32),
::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!(
888 "visit_terminator_drop \
889 loc: {:?} term: {:?} place: {:?} span: {:?}",
890 loc, term, place, span
891 );
892
893 let write_kind =
894 if *replace { WriteKind::Replace } else { WriteKind::StorageDeadOrDrop };
895 self.access_place(
896 loc,
897 (*place, span),
898 (AccessDepth::Drop, Write(write_kind)),
899 LocalMutationIsAllowed::Yes,
900 state,
901 );
902 }
903 TerminatorKind::Call {
904 func,
905 args,
906 destination,
907 target: _,
908 unwind: _,
909 call_source: _,
910 fn_span: _,
911 } => {
912 self.consume_operand(loc, (func, span), state);
913 for arg in args {
914 self.consume_operand(loc, (&arg.node, arg.span), state);
915 }
916 self.mutate_place(loc, (*destination, span), Deep, state);
917 }
918 TerminatorKind::TailCall { func, args, fn_span: _ } => {
919 self.consume_operand(loc, (func, span), state);
920 for arg in args {
921 self.consume_operand(loc, (&arg.node, arg.span), state);
922 }
923 }
924 TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => {
925 self.consume_operand(loc, (cond, span), state);
926 if let AssertKind::BoundsCheck { len, index } = &**msg {
927 self.consume_operand(loc, (len, span), state);
928 self.consume_operand(loc, (index, span), state);
929 }
930 }
931
932 TerminatorKind::Yield { value, resume: _, resume_arg, drop: _ } => {
933 self.consume_operand(loc, (value, span), state);
934 self.mutate_place(loc, (*resume_arg, span), Deep, state);
935 }
936
937 TerminatorKind::InlineAsm {
938 asm_macro: _,
939 template: _,
940 operands,
941 options: _,
942 line_spans: _,
943 targets: _,
944 unwind: _,
945 } => {
946 for op in operands {
947 match op {
948 InlineAsmOperand::In { reg: _, value } => {
949 self.consume_operand(loc, (value, span), state);
950 }
951 InlineAsmOperand::Out { reg: _, late: _, place, .. } => {
952 if let Some(place) = place {
953 self.mutate_place(loc, (*place, span), Shallow(None), state);
954 }
955 }
956 InlineAsmOperand::InOut { reg: _, late: _, in_value, out_place } => {
957 self.consume_operand(loc, (in_value, span), state);
958 if let &Some(out_place) = out_place {
959 self.mutate_place(loc, (out_place, span), Shallow(None), state);
960 }
961 }
962 InlineAsmOperand::Const { value: _ }
963 | InlineAsmOperand::SymFn { value: _ }
964 | InlineAsmOperand::SymStatic { def_id: _ }
965 | InlineAsmOperand::Label { target_index: _ } => {}
966 }
967 }
968 }
969
970 TerminatorKind::Goto { target: _ }
971 | TerminatorKind::UnwindTerminate(_)
972 | TerminatorKind::Unreachable
973 | TerminatorKind::UnwindResume
974 | TerminatorKind::Return
975 | TerminatorKind::CoroutineDrop
976 | TerminatorKind::FalseEdge { real_target: _, imaginary_target: _ }
977 | TerminatorKind::FalseUnwind { real_target: _, unwind: _ } => {
978 }
980 }
981 }
982
983 fn visit_after_primary_terminator_effect(
984 &mut self,
985 _analysis: &Borrowck<'a, 'tcx>,
986 state: &BorrowckDomain,
987 term: &Terminator<'tcx>,
988 loc: Location,
989 ) {
990 let span = term.source_info.span;
991
992 match term.kind {
993 TerminatorKind::Yield { value: _, resume: _, resume_arg: _, drop: _ } => {
994 if self.movable_coroutine {
995 for i in state.borrows.iter() {
997 let borrow = &self.borrow_set[i];
998 self.check_for_local_borrow(borrow, span);
999 }
1000 }
1001 }
1002
1003 TerminatorKind::UnwindResume
1004 | TerminatorKind::Return
1005 | TerminatorKind::TailCall { .. }
1006 | TerminatorKind::CoroutineDrop => {
1007 match self.borrow_set.locals_state_at_exit() {
1008 LocalsStateAtExit::AllAreInvalidated => {
1009 for i in state.borrows.iter() {
1014 let borrow = &self.borrow_set[i];
1015 self.check_for_invalidation_at_exit(loc, borrow, span);
1016 }
1017 }
1018 LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved: _ } => {}
1021 }
1022 }
1023
1024 TerminatorKind::UnwindTerminate(_)
1025 | TerminatorKind::Assert { .. }
1026 | TerminatorKind::Call { .. }
1027 | TerminatorKind::Drop { .. }
1028 | TerminatorKind::FalseEdge { real_target: _, imaginary_target: _ }
1029 | TerminatorKind::FalseUnwind { real_target: _, unwind: _ }
1030 | TerminatorKind::Goto { .. }
1031 | TerminatorKind::SwitchInt { .. }
1032 | TerminatorKind::Unreachable
1033 | TerminatorKind::InlineAsm { .. } => {}
1034 }
1035 }
1036}
1037
1038use self::AccessDepth::{Deep, Shallow};
1039use self::ReadOrWrite::{Activation, Read, Reservation, Write};
1040
1041#[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)]
1042enum ArtificialField {
1043 ArrayLength,
1044 FakeBorrow,
1045}
1046
1047#[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)]
1048enum AccessDepth {
1049 Shallow(Option<ArtificialField>),
1055
1056 Deep,
1060
1061 Drop,
1064}
1065
1066#[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)]
1069enum ReadOrWrite {
1070 Read(ReadKind),
1073
1074 Write(WriteKind),
1078
1079 Reservation(WriteKind),
1083 Activation(WriteKind, BorrowIndex),
1084}
1085
1086#[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)]
1089enum ReadKind {
1090 Borrow(BorrowKind),
1091 Copy,
1092}
1093
1094#[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)]
1097enum WriteKind {
1098 StorageDeadOrDrop,
1099 Replace,
1100 MutableBorrow(BorrowKind),
1101 Mutate,
1102 Move,
1103}
1104
1105#[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)]
1113enum LocalMutationIsAllowed {
1114 Yes,
1115 ExceptUpvars,
1118 No,
1119}
1120
1121#[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)]
1122enum InitializationRequiringAction {
1123 Borrow,
1124 MatchOn,
1125 Use,
1126 Assignment,
1127 PartialAssignment,
1128}
1129
1130#[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)]
1131struct RootPlace<'tcx> {
1132 place_local: Local,
1133 place_projection: &'tcx [PlaceElem<'tcx>],
1134 is_local_mutation_allowed: LocalMutationIsAllowed,
1135}
1136
1137impl InitializationRequiringAction {
1138 fn as_noun(self) -> &'static str {
1139 match self {
1140 InitializationRequiringAction::Borrow => "borrow",
1141 InitializationRequiringAction::MatchOn => "use", InitializationRequiringAction::Use => "use",
1143 InitializationRequiringAction::Assignment => "assign",
1144 InitializationRequiringAction::PartialAssignment => "assign to part",
1145 }
1146 }
1147
1148 fn as_verb_in_past_tense(self) -> &'static str {
1149 match self {
1150 InitializationRequiringAction::Borrow => "borrowed",
1151 InitializationRequiringAction::MatchOn => "matched on",
1152 InitializationRequiringAction::Use => "used",
1153 InitializationRequiringAction::Assignment => "assigned",
1154 InitializationRequiringAction::PartialAssignment => "partially assigned",
1155 }
1156 }
1157
1158 fn as_general_verb_in_past_tense(self) -> &'static str {
1159 match self {
1160 InitializationRequiringAction::Borrow
1161 | InitializationRequiringAction::MatchOn
1162 | InitializationRequiringAction::Use => "used",
1163 InitializationRequiringAction::Assignment => "assigned",
1164 InitializationRequiringAction::PartialAssignment => "partially assigned",
1165 }
1166 }
1167}
1168
1169impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
1170 fn body(&self) -> &'a Body<'tcx> {
1171 self.body
1172 }
1173
1174 fn access_place(
1181 &mut self,
1182 location: Location,
1183 place_span: (Place<'tcx>, Span),
1184 kind: (AccessDepth, ReadOrWrite),
1185 is_local_mutation_allowed: LocalMutationIsAllowed,
1186 state: &BorrowckDomain,
1187 ) {
1188 let (sd, rw) = kind;
1189
1190 if let Activation(_, borrow_index) = rw {
1191 if self.reservation_error_reported.contains(&place_span.0) {
1192 {
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:1192",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1192u32),
::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!(
1193 "skipping access_place for activation of invalid reservation \
1194 place: {:?} borrow_index: {:?}",
1195 place_span.0, borrow_index
1196 );
1197 return;
1198 }
1199 }
1200
1201 if !self.access_place_error_reported.is_empty()
1204 && self.access_place_error_reported.contains(&(place_span.0, place_span.1))
1205 {
1206 {
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:1206",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1206u32),
::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!(
1207 "access_place: suppressing error place_span=`{:?}` kind=`{:?}`",
1208 place_span, kind
1209 );
1210
1211 if rw == ReadOrWrite::Write(WriteKind::Mutate)
1215 && let Ok(root_place) =
1216 self.is_mutable(place_span.0.as_ref(), is_local_mutation_allowed)
1217 {
1218 self.add_used_mut(root_place, state);
1219 }
1220
1221 return;
1222 }
1223
1224 let mutability_error = self.check_access_permissions(
1225 place_span,
1226 rw,
1227 is_local_mutation_allowed,
1228 state,
1229 location,
1230 );
1231 let conflict_error = self.check_access_for_conflict(location, place_span, sd, rw, state);
1232
1233 if conflict_error || mutability_error {
1234 {
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:1234",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1234u32),
::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);
1235 self.access_place_error_reported.insert((place_span.0, place_span.1));
1236 }
1237 }
1238
1239 fn borrows_in_scope<'s>(
1240 &self,
1241 location: Location,
1242 state: &'s BorrowckDomain,
1243 ) -> Cow<'s, MixedBitSet<BorrowIndex>> {
1244 if let Some(polonius) = &self.polonius_output {
1245 let location = self.location_table.start_index(location);
1247 let mut polonius_output = MixedBitSet::new_empty(self.borrow_set.len());
1248 for &idx in polonius.errors_at(location) {
1249 polonius_output.insert(idx);
1250 }
1251 Cow::Owned(polonius_output)
1252 } else {
1253 Cow::Borrowed(&state.borrows)
1254 }
1255 }
1256
1257 #[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(1257u32),
::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);
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:1285",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1285u32),
::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:1339",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1339u32),
::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:1347",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1347u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("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))]
1258 fn check_access_for_conflict(
1259 &mut self,
1260 location: Location,
1261 place_span: (Place<'tcx>, Span),
1262 sd: AccessDepth,
1263 rw: ReadOrWrite,
1264 state: &BorrowckDomain,
1265 ) -> bool {
1266 let mut error_reported = false;
1267
1268 let borrows_in_scope = self.borrows_in_scope(location, state);
1269
1270 each_borrow_involving_path(
1271 self,
1272 self.infcx.tcx,
1273 self.body,
1274 (sd, place_span.0),
1275 self.borrow_set,
1276 |borrow_index| borrows_in_scope.contains(borrow_index),
1277 |this, borrow_index, borrow| match (rw, borrow.kind) {
1278 (Activation(_, activating), _) if activating == borrow_index => {
1285 debug!(
1286 "check_access_for_conflict place_span: {:?} sd: {:?} rw: {:?} \
1287 skipping {:?} b/c activation of same borrow_index",
1288 place_span,
1289 sd,
1290 rw,
1291 (borrow_index, borrow),
1292 );
1293 ControlFlow::Continue(())
1294 }
1295
1296 (Read(_), BorrowKind::Shared | BorrowKind::Fake(_))
1297 | (
1298 Read(ReadKind::Borrow(BorrowKind::Fake(FakeBorrowKind::Shallow))),
1299 BorrowKind::Mut { .. },
1300 ) => ControlFlow::Continue(()),
1301
1302 (Reservation(_), BorrowKind::Fake(_) | BorrowKind::Shared) => {
1303 ControlFlow::Continue(())
1306 }
1307
1308 (Write(WriteKind::Move), BorrowKind::Fake(FakeBorrowKind::Shallow)) => {
1309 ControlFlow::Continue(())
1311 }
1312
1313 (Read(kind), BorrowKind::Mut { .. }) => {
1314 if !is_active(this.dominators(), borrow, location) {
1316 assert!(borrow.kind.is_two_phase_borrow());
1317 return ControlFlow::Continue(());
1318 }
1319
1320 error_reported = true;
1321 match kind {
1322 ReadKind::Copy => {
1323 let err = this
1324 .report_use_while_mutably_borrowed(location, place_span, borrow);
1325 this.buffer_error(err);
1326 }
1327 ReadKind::Borrow(bk) => {
1328 let err =
1329 this.report_conflicting_borrow(location, place_span, bk, borrow);
1330 this.buffer_error(err);
1331 }
1332 }
1333 ControlFlow::Break(())
1334 }
1335
1336 (Reservation(kind) | Activation(kind, _) | Write(kind), _) => {
1337 match rw {
1338 Reservation(..) => {
1339 debug!(
1340 "recording invalid reservation of \
1341 place: {:?}",
1342 place_span.0
1343 );
1344 this.reservation_error_reported.insert(place_span.0);
1345 }
1346 Activation(_, activating) => {
1347 debug!(
1348 "observing check_place for activation of \
1349 borrow_index: {:?}",
1350 activating
1351 );
1352 }
1353 Read(..) | Write(..) => {}
1354 }
1355
1356 error_reported = true;
1357 match kind {
1358 WriteKind::MutableBorrow(bk) => {
1359 let err =
1360 this.report_conflicting_borrow(location, place_span, bk, borrow);
1361 this.buffer_error(err);
1362 }
1363 WriteKind::StorageDeadOrDrop => this
1364 .report_borrowed_value_does_not_live_long_enough(
1365 location,
1366 borrow,
1367 place_span,
1368 Some(WriteKind::StorageDeadOrDrop),
1369 ),
1370 WriteKind::Mutate => {
1371 this.report_illegal_mutation_of_borrowed(location, place_span, borrow)
1372 }
1373 WriteKind::Move => {
1374 this.report_move_out_while_borrowed(location, place_span, borrow)
1375 }
1376 WriteKind::Replace => {
1377 this.report_illegal_mutation_of_borrowed(location, place_span, borrow)
1378 }
1379 }
1380 ControlFlow::Break(())
1381 }
1382 },
1383 );
1384
1385 error_reported
1386 }
1387
1388 #[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(1390u32),
::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))]
1391 fn check_backward_incompatible_drop(
1392 &mut self,
1393 location: Location,
1394 place: Place<'tcx>,
1395 state: &BorrowckDomain,
1396 ) {
1397 let tcx = self.infcx.tcx;
1398 let sd = if place.ty(self.body, tcx).ty.needs_drop(tcx, self.body.typing_env(tcx)) {
1402 AccessDepth::Drop
1403 } else {
1404 AccessDepth::Shallow(None)
1405 };
1406
1407 let borrows_in_scope = self.borrows_in_scope(location, state);
1408
1409 each_borrow_involving_path(
1412 self,
1413 self.infcx.tcx,
1414 self.body,
1415 (sd, place),
1416 self.borrow_set,
1417 |borrow_index| borrows_in_scope.contains(borrow_index),
1418 |this, _borrow_index, borrow| {
1419 if matches!(borrow.kind, BorrowKind::Fake(_)) {
1420 return ControlFlow::Continue(());
1421 }
1422 let borrowed = this.retrieve_borrow_spans(borrow).var_or_use_path_span();
1423 let explain = this.explain_why_borrow_contains_point(
1424 location,
1425 borrow,
1426 Some((WriteKind::StorageDeadOrDrop, place)),
1427 );
1428 this.infcx.tcx.emit_node_span_lint(
1429 TAIL_EXPR_DROP_ORDER,
1430 CRATE_HIR_ID,
1431 borrowed,
1432 session_diagnostics::TailExprDropOrder {
1433 borrowed,
1434 callback: |diag| {
1435 explain.add_explanation_to_diagnostic(&this, diag, "", None, None);
1436 },
1437 },
1438 );
1439 ControlFlow::Break(())
1441 },
1442 );
1443 }
1444
1445 fn mutate_place(
1446 &mut self,
1447 location: Location,
1448 place_span: (Place<'tcx>, Span),
1449 kind: AccessDepth,
1450 state: &BorrowckDomain,
1451 ) {
1452 self.check_if_assigned_path_is_moved(location, place_span, state);
1454
1455 self.access_place(
1456 location,
1457 place_span,
1458 (kind, Write(WriteKind::Mutate)),
1459 LocalMutationIsAllowed::No,
1460 state,
1461 );
1462 }
1463
1464 fn consume_rvalue(
1465 &mut self,
1466 location: Location,
1467 (rvalue, span): (&Rvalue<'tcx>, Span),
1468 state: &BorrowckDomain,
1469 ) {
1470 match rvalue {
1471 &Rvalue::Ref(_ , bk, place) => {
1472 let access_kind = match bk {
1473 BorrowKind::Fake(FakeBorrowKind::Shallow) => {
1474 (Shallow(Some(ArtificialField::FakeBorrow)), Read(ReadKind::Borrow(bk)))
1475 }
1476 BorrowKind::Shared | BorrowKind::Fake(FakeBorrowKind::Deep) => {
1477 (Deep, Read(ReadKind::Borrow(bk)))
1478 }
1479 BorrowKind::Mut { .. } => {
1480 let wk = WriteKind::MutableBorrow(bk);
1481 if bk.is_two_phase_borrow() {
1482 (Deep, Reservation(wk))
1483 } else {
1484 (Deep, Write(wk))
1485 }
1486 }
1487 };
1488
1489 self.access_place(
1490 location,
1491 (place, span),
1492 access_kind,
1493 LocalMutationIsAllowed::No,
1494 state,
1495 );
1496
1497 let action = if bk == BorrowKind::Fake(FakeBorrowKind::Shallow) {
1498 InitializationRequiringAction::MatchOn
1499 } else {
1500 InitializationRequiringAction::Borrow
1501 };
1502
1503 self.check_if_path_or_subpath_is_moved(
1504 location,
1505 action,
1506 (place.as_ref(), span),
1507 state,
1508 );
1509 }
1510
1511 &Rvalue::RawPtr(kind, place) => {
1512 let access_kind = match kind {
1513 RawPtrKind::Mut => (
1514 Deep,
1515 Write(WriteKind::MutableBorrow(BorrowKind::Mut {
1516 kind: MutBorrowKind::Default,
1517 })),
1518 ),
1519 RawPtrKind::Const => (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))),
1520 RawPtrKind::FakeForPtrMetadata => {
1521 (Shallow(Some(ArtificialField::ArrayLength)), Read(ReadKind::Copy))
1522 }
1523 };
1524
1525 self.access_place(
1526 location,
1527 (place, span),
1528 access_kind,
1529 LocalMutationIsAllowed::No,
1530 state,
1531 );
1532
1533 self.check_if_path_or_subpath_is_moved(
1534 location,
1535 InitializationRequiringAction::Borrow,
1536 (place.as_ref(), span),
1537 state,
1538 );
1539 }
1540
1541 Rvalue::ThreadLocalRef(_) => {}
1542
1543 Rvalue::Use(operand)
1544 | Rvalue::Repeat(operand, _)
1545 | Rvalue::UnaryOp(_ , operand)
1546 | Rvalue::Cast(_ , operand, _ ) => {
1547 self.consume_operand(location, (operand, span), state)
1548 }
1549
1550 &Rvalue::Discriminant(place) => {
1551 let af = match *rvalue {
1552 Rvalue::Discriminant(..) => None,
1553 _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1554 };
1555 self.access_place(
1556 location,
1557 (place, span),
1558 (Shallow(af), Read(ReadKind::Copy)),
1559 LocalMutationIsAllowed::No,
1560 state,
1561 );
1562 self.check_if_path_or_subpath_is_moved(
1563 location,
1564 InitializationRequiringAction::Use,
1565 (place.as_ref(), span),
1566 state,
1567 );
1568 }
1569
1570 Rvalue::BinaryOp(_bin_op, box (operand1, operand2)) => {
1571 self.consume_operand(location, (operand1, span), state);
1572 self.consume_operand(location, (operand2, span), state);
1573 }
1574
1575 Rvalue::Aggregate(aggregate_kind, operands) => {
1576 match **aggregate_kind {
1580 AggregateKind::Closure(def_id, _)
1581 | AggregateKind::CoroutineClosure(def_id, _)
1582 | AggregateKind::Coroutine(def_id, _) => {
1583 let def_id = def_id.expect_local();
1584 let used_mut_upvars = self.root_cx.used_mut_upvars(def_id);
1585 {
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:1585",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1585u32),
::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);
1586 for field in used_mut_upvars.clone() {
1590 self.propagate_closure_used_mut_upvar(&operands[field]);
1591 }
1592 }
1593 AggregateKind::Adt(..)
1594 | AggregateKind::Array(..)
1595 | AggregateKind::Tuple { .. }
1596 | AggregateKind::RawPtr(..) => (),
1597 }
1598
1599 for operand in operands {
1600 self.consume_operand(location, (operand, span), state);
1601 }
1602 }
1603
1604 Rvalue::WrapUnsafeBinder(op, _) => {
1605 self.consume_operand(location, (op, span), state);
1606 }
1607
1608 Rvalue::CopyForDeref(_) => ::rustc_middle::util::bug::bug_fmt(format_args!("`CopyForDeref` in borrowck"))bug!("`CopyForDeref` in borrowck"),
1609 }
1610 }
1611
1612 fn propagate_closure_used_mut_upvar(&mut self, operand: &Operand<'tcx>) {
1613 let propagate_closure_used_mut_place = |this: &mut Self, place: Place<'tcx>| {
1614 if let Some(field) = this.is_upvar_field_projection(place.as_ref()) {
1622 this.used_mut_upvars.push(field);
1623 return;
1624 }
1625
1626 for (place_ref, proj) in place.iter_projections().rev() {
1627 if proj == ProjectionElem::Deref {
1629 match place_ref.ty(this.body(), this.infcx.tcx).ty.kind() {
1630 ty::Ref(_, _, hir::Mutability::Mut) => return,
1632
1633 _ => {}
1634 }
1635 }
1636
1637 if let Some(field) = this.is_upvar_field_projection(place_ref) {
1639 this.used_mut_upvars.push(field);
1640 return;
1641 }
1642 }
1643
1644 this.used_mut.insert(place.local);
1646 };
1647
1648 match *operand {
1652 Operand::Move(place) | Operand::Copy(place) => {
1653 match place.as_local() {
1654 Some(local) if !self.body.local_decls[local].is_user_variable() => {
1655 if self.body.local_decls[local].ty.is_mutable_ptr() {
1656 return;
1658 }
1659 let Some(temp_mpi) = self.move_data.rev_lookup.find_local(local) else {
1675 ::rustc_middle::util::bug::bug_fmt(format_args!("temporary should be tracked"));bug!("temporary should be tracked");
1676 };
1677 let init = if let [init_index] = *self.move_data.init_path_map[temp_mpi] {
1678 &self.move_data.inits[init_index]
1679 } else {
1680 ::rustc_middle::util::bug::bug_fmt(format_args!("temporary should be initialized exactly once"))bug!("temporary should be initialized exactly once")
1681 };
1682
1683 let InitLocation::Statement(loc) = init.location else {
1684 ::rustc_middle::util::bug::bug_fmt(format_args!("temporary initialized in arguments"))bug!("temporary initialized in arguments")
1685 };
1686
1687 let body = self.body;
1688 let bbd = &body[loc.block];
1689 let stmt = &bbd.statements[loc.statement_index];
1690 {
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:1690",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1690u32),
::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);
1691
1692 match stmt.kind {
1693 StatementKind::Assign(box (
1694 _,
1695 Rvalue::Ref(_, _, source)
1696 | Rvalue::Use(Operand::Copy(source) | Operand::Move(source)),
1697 )) => {
1698 propagate_closure_used_mut_place(self, source);
1699 }
1700 _ => {
1701 ::rustc_middle::util::bug::bug_fmt(format_args!("closures should only capture user variables or references to user variables"));bug!(
1702 "closures should only capture user variables \
1703 or references to user variables"
1704 );
1705 }
1706 }
1707 }
1708 _ => propagate_closure_used_mut_place(self, place),
1709 }
1710 }
1711 Operand::Constant(..) | Operand::RuntimeChecks(_) => {}
1712 }
1713 }
1714
1715 fn consume_operand(
1716 &mut self,
1717 location: Location,
1718 (operand, span): (&Operand<'tcx>, Span),
1719 state: &BorrowckDomain,
1720 ) {
1721 match *operand {
1722 Operand::Copy(place) => {
1723 self.access_place(
1726 location,
1727 (place, span),
1728 (Deep, Read(ReadKind::Copy)),
1729 LocalMutationIsAllowed::No,
1730 state,
1731 );
1732
1733 self.check_if_path_or_subpath_is_moved(
1735 location,
1736 InitializationRequiringAction::Use,
1737 (place.as_ref(), span),
1738 state,
1739 );
1740 }
1741 Operand::Move(place) => {
1742 self.check_movable_place(location, place);
1744
1745 self.access_place(
1747 location,
1748 (place, span),
1749 (Deep, Write(WriteKind::Move)),
1750 LocalMutationIsAllowed::Yes,
1751 state,
1752 );
1753
1754 self.check_if_path_or_subpath_is_moved(
1756 location,
1757 InitializationRequiringAction::Use,
1758 (place.as_ref(), span),
1759 state,
1760 );
1761 }
1762 Operand::Constant(_) | Operand::RuntimeChecks(_) => {}
1763 }
1764 }
1765
1766 #[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(1768u32),
::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:1804",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1804u32),
::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))]
1769 fn check_for_invalidation_at_exit(
1770 &mut self,
1771 location: Location,
1772 borrow: &BorrowData<'tcx>,
1773 span: Span,
1774 ) {
1775 let place = borrow.borrowed_place;
1776 let mut root_place = PlaceRef { local: place.local, projection: &[] };
1777
1778 let might_be_alive = if self.body.local_decls[root_place.local].is_ref_to_thread_local() {
1784 root_place.projection = TyCtxtConsts::DEREF_PROJECTION;
1788 true
1789 } else {
1790 false
1791 };
1792
1793 let sd = if might_be_alive { Deep } else { Shallow(None) };
1794
1795 if places_conflict::borrow_conflicts_with_place(
1796 self.infcx.tcx,
1797 self.body,
1798 place,
1799 borrow.kind,
1800 root_place,
1801 sd,
1802 places_conflict::PlaceConflictBias::Overlap,
1803 ) {
1804 debug!("check_for_invalidation_at_exit({:?}): INVALID", place);
1805 let span = self.infcx.tcx.sess.source_map().end_point(span);
1808 self.report_borrowed_value_does_not_live_long_enough(
1809 location,
1810 borrow,
1811 (place, span),
1812 None,
1813 )
1814 }
1815 }
1816
1817 fn check_for_local_borrow(&mut self, borrow: &BorrowData<'tcx>, yield_span: Span) {
1820 {
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:1820",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(1820u32),
::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);
1821
1822 if borrow_of_local_data(borrow.borrowed_place) {
1823 let err = self.cannot_borrow_across_coroutine_yield(
1824 self.retrieve_borrow_spans(borrow).var_or_use(),
1825 yield_span,
1826 );
1827
1828 self.buffer_error(err);
1829 }
1830 }
1831
1832 fn check_activations(&mut self, location: Location, span: Span, state: &BorrowckDomain) {
1833 for &borrow_index in self.borrow_set.activations_at_location(location) {
1837 let borrow = &self.borrow_set[borrow_index];
1838
1839 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 {
1841 BorrowKind::Shared | BorrowKind::Fake(_) => false,
1842 BorrowKind::Mut { .. } => true,
1843 });
1844
1845 self.access_place(
1846 location,
1847 (borrow.borrowed_place, span),
1848 (Deep, Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index)),
1849 LocalMutationIsAllowed::No,
1850 state,
1851 );
1852 }
1856 }
1857
1858 fn check_movable_place(&mut self, location: Location, place: Place<'tcx>) {
1859 use IllegalMoveOriginKind::*;
1860
1861 let body = self.body;
1862 let tcx = self.infcx.tcx;
1863 let mut place_ty = PlaceTy::from_ty(body.local_decls[place.local].ty);
1864 for (place_ref, elem) in place.iter_projections() {
1865 match elem {
1866 ProjectionElem::Deref => match place_ty.ty.kind() {
1867 ty::Ref(..) | ty::RawPtr(..) => {
1868 self.move_errors.push(MoveError::new(
1869 place,
1870 location,
1871 BorrowedContent {
1872 target_place: place_ref.project_deeper(&[elem], tcx),
1873 },
1874 ));
1875 return;
1876 }
1877 ty::Adt(adt, _) => {
1878 if !adt.is_box() {
1879 ::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");
1880 }
1881 }
1882 ty::Bool
1883 | ty::Char
1884 | ty::Int(_)
1885 | ty::Uint(_)
1886 | ty::Float(_)
1887 | ty::Foreign(_)
1888 | ty::Str
1889 | ty::Array(_, _)
1890 | ty::Pat(_, _)
1891 | ty::Slice(_)
1892 | ty::FnDef(_, _)
1893 | ty::FnPtr(..)
1894 | ty::Dynamic(_, _)
1895 | ty::Closure(_, _)
1896 | ty::CoroutineClosure(_, _)
1897 | ty::Coroutine(_, _)
1898 | ty::CoroutineWitness(..)
1899 | ty::Never
1900 | ty::Tuple(_)
1901 | ty::UnsafeBinder(_)
1902 | ty::Alias(_, _)
1903 | ty::Param(_)
1904 | ty::Bound(_, _)
1905 | ty::Infer(_)
1906 | ty::Error(_)
1907 | ty::Placeholder(_) => {
1908 ::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:#?}")
1909 }
1910 },
1911 ProjectionElem::Field(_, _) => match place_ty.ty.kind() {
1912 ty::Adt(adt, _) => {
1913 if adt.has_dtor(tcx) {
1914 self.move_errors.push(MoveError::new(
1915 place,
1916 location,
1917 InteriorOfTypeWithDestructor { container_ty: place_ty.ty },
1918 ));
1919 return;
1920 }
1921 }
1922 ty::Closure(..)
1923 | ty::CoroutineClosure(..)
1924 | ty::Coroutine(_, _)
1925 | ty::Tuple(_) => (),
1926 ty::Bool
1927 | ty::Char
1928 | ty::Int(_)
1929 | ty::Uint(_)
1930 | ty::Float(_)
1931 | ty::Foreign(_)
1932 | ty::Str
1933 | ty::Array(_, _)
1934 | ty::Pat(_, _)
1935 | ty::Slice(_)
1936 | ty::RawPtr(_, _)
1937 | ty::Ref(_, _, _)
1938 | ty::FnDef(_, _)
1939 | ty::FnPtr(..)
1940 | ty::Dynamic(_, _)
1941 | ty::CoroutineWitness(..)
1942 | ty::Never
1943 | ty::UnsafeBinder(_)
1944 | ty::Alias(_, _)
1945 | ty::Param(_)
1946 | ty::Bound(_, _)
1947 | ty::Infer(_)
1948 | ty::Error(_)
1949 | 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!(
1950 "When Place contains ProjectionElem::Field it's type shouldn't be {place_ty:#?}"
1951 ),
1952 },
1953 ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {
1954 match place_ty.ty.kind() {
1955 ty::Slice(_) => {
1956 self.move_errors.push(MoveError::new(
1957 place,
1958 location,
1959 InteriorOfSliceOrArray { ty: place_ty.ty, is_index: false },
1960 ));
1961 return;
1962 }
1963 ty::Array(_, _) => (),
1964 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("Unexpected type {0:#?}",
place_ty.ty))bug!("Unexpected type {:#?}", place_ty.ty),
1965 }
1966 }
1967 ProjectionElem::Index(_) => match place_ty.ty.kind() {
1968 ty::Array(..) | ty::Slice(..) => {
1969 self.move_errors.push(MoveError::new(
1970 place,
1971 location,
1972 InteriorOfSliceOrArray { ty: place_ty.ty, is_index: true },
1973 ));
1974 return;
1975 }
1976 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("Unexpected type {0:#?}",
place_ty))bug!("Unexpected type {place_ty:#?}"),
1977 },
1978 ProjectionElem::OpaqueCast(_)
1982 | ProjectionElem::Downcast(_, _)
1983 | ProjectionElem::UnwrapUnsafeBinder(_) => (),
1984 }
1985
1986 place_ty = place_ty.projection_ty(tcx, elem);
1987 }
1988 }
1989
1990 fn check_if_full_path_is_moved(
1991 &mut self,
1992 location: Location,
1993 desired_action: InitializationRequiringAction,
1994 place_span: (PlaceRef<'tcx>, Span),
1995 state: &BorrowckDomain,
1996 ) {
1997 let maybe_uninits = &state.uninits;
1998
1999 {
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:2034",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(2034u32),
::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);
2035 let (prefix, mpi) = self.move_path_closest_to(place_span.0);
2036 if maybe_uninits.contains(mpi) {
2037 self.report_use_of_moved_or_uninitialized(
2038 location,
2039 desired_action,
2040 (prefix, place_span.0, place_span.1),
2041 mpi,
2042 );
2043 } }
2050
2051 fn check_if_subslice_element_is_moved(
2057 &mut self,
2058 location: Location,
2059 desired_action: InitializationRequiringAction,
2060 place_span: (PlaceRef<'tcx>, Span),
2061 maybe_uninits: &MixedBitSet<MovePathIndex>,
2062 from: u64,
2063 to: u64,
2064 ) {
2065 if let Some(mpi) = self.move_path_for_place(place_span.0) {
2066 let move_paths = &self.move_data.move_paths;
2067
2068 let root_path = &move_paths[mpi];
2069 for (child_mpi, child_move_path) in root_path.children(move_paths) {
2070 let last_proj = child_move_path.place.projection.last().unwrap();
2071 if let ProjectionElem::ConstantIndex { offset, from_end, .. } = last_proj {
2072 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`.");
2073
2074 if (from..to).contains(offset) {
2075 let uninit_child =
2076 self.move_data.find_in_move_path_or_its_descendants(child_mpi, |mpi| {
2077 maybe_uninits.contains(mpi)
2078 });
2079
2080 if let Some(uninit_child) = uninit_child {
2081 self.report_use_of_moved_or_uninitialized(
2082 location,
2083 desired_action,
2084 (place_span.0, place_span.0, place_span.1),
2085 uninit_child,
2086 );
2087 return; }
2089 }
2090 }
2091 }
2092 }
2093 }
2094
2095 fn check_if_path_or_subpath_is_moved(
2096 &mut self,
2097 location: Location,
2098 desired_action: InitializationRequiringAction,
2099 place_span: (PlaceRef<'tcx>, Span),
2100 state: &BorrowckDomain,
2101 ) {
2102 let maybe_uninits = &state.uninits;
2103
2104 self.check_if_full_path_is_moved(location, desired_action, place_span, state);
2120
2121 if let Some((place_base, ProjectionElem::Subslice { from, to, from_end: false })) =
2122 place_span.0.last_projection()
2123 {
2124 let place_ty = place_base.ty(self.body(), self.infcx.tcx);
2125 if let ty::Array(..) = place_ty.ty.kind() {
2126 self.check_if_subslice_element_is_moved(
2127 location,
2128 desired_action,
2129 (place_base, place_span.1),
2130 maybe_uninits,
2131 from,
2132 to,
2133 );
2134 return;
2135 }
2136 }
2137
2138 {
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:2147",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(2147u32),
::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);
2148 if let Some(mpi) = self.move_path_for_place(place_span.0) {
2149 let uninit_mpi = self
2150 .move_data
2151 .find_in_move_path_or_its_descendants(mpi, |mpi| maybe_uninits.contains(mpi));
2152
2153 if let Some(uninit_mpi) = uninit_mpi {
2154 self.report_use_of_moved_or_uninitialized(
2155 location,
2156 desired_action,
2157 (place_span.0, place_span.0, place_span.1),
2158 uninit_mpi,
2159 );
2160 return; }
2162 }
2163 }
2164
2165 fn move_path_closest_to(&mut self, place: PlaceRef<'tcx>) -> (PlaceRef<'tcx>, MovePathIndex) {
2176 match self.move_data.rev_lookup.find(place) {
2177 LookupResult::Parent(Some(mpi)) | LookupResult::Exact(mpi) => {
2178 (self.move_data.move_paths[mpi].place.as_ref(), mpi)
2179 }
2180 LookupResult::Parent(None) => {
::core::panicking::panic_fmt(format_args!("should have move path for every Local"));
}panic!("should have move path for every Local"),
2181 }
2182 }
2183
2184 fn move_path_for_place(&mut self, place: PlaceRef<'tcx>) -> Option<MovePathIndex> {
2185 match self.move_data.rev_lookup.find(place) {
2190 LookupResult::Parent(_) => None,
2191 LookupResult::Exact(mpi) => Some(mpi),
2192 }
2193 }
2194
2195 fn check_if_assigned_path_is_moved(
2196 &mut self,
2197 location: Location,
2198 (place, span): (Place<'tcx>, Span),
2199 state: &BorrowckDomain,
2200 ) {
2201 {
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:2201",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(2201u32),
::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);
2202
2203 for (place_base, elem) in place.iter_projections().rev() {
2205 match elem {
2206 ProjectionElem::Index(_) |
2207 ProjectionElem::OpaqueCast(_) |
2208 ProjectionElem::ConstantIndex { .. } |
2209 ProjectionElem::Downcast(_, _) =>
2211 { }
2215
2216 ProjectionElem::UnwrapUnsafeBinder(_) => {
2217 check_parent_of_field(self, location, place_base, span, state);
2218 }
2219
2220 ProjectionElem::Deref => {
2222 self.check_if_full_path_is_moved(
2223 location, InitializationRequiringAction::Use,
2224 (place_base, span), state);
2225 break;
2228 }
2229
2230 ProjectionElem::Subslice { .. } => {
2231 {
::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:?}");
2232 }
2233
2234 ProjectionElem::Field(..) => {
2235 let tcx = self.infcx.tcx;
2239 let base_ty = place_base.ty(self.body(), tcx).ty;
2240 match base_ty.kind() {
2241 ty::Adt(def, _) if def.has_dtor(tcx) => {
2242 self.check_if_path_or_subpath_is_moved(
2243 location, InitializationRequiringAction::Assignment,
2244 (place_base, span), state);
2245
2246 break;
2249 }
2250
2251 ty::Adt(..) | ty::Tuple(..) => {
2254 check_parent_of_field(self, location, place_base, span, state);
2255 }
2256
2257 _ => {}
2258 }
2259 }
2260 }
2261 }
2262
2263 fn check_parent_of_field<'a, 'tcx>(
2264 this: &mut MirBorrowckCtxt<'a, '_, 'tcx>,
2265 location: Location,
2266 base: PlaceRef<'tcx>,
2267 span: Span,
2268 state: &BorrowckDomain,
2269 ) {
2270 let maybe_uninits = &state.uninits;
2302
2303 let mut shortest_uninit_seen = None;
2306 for prefix in this.prefixes(base, PrefixSet::Shallow) {
2307 let Some(mpi) = this.move_path_for_place(prefix) else { continue };
2308
2309 if maybe_uninits.contains(mpi) {
2310 {
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:2310",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(2310u32),
::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!(
2311 "check_parent_of_field updating shortest_uninit_seen from {:?} to {:?}",
2312 shortest_uninit_seen,
2313 Some((prefix, mpi))
2314 );
2315 shortest_uninit_seen = Some((prefix, mpi));
2316 } else {
2317 {
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:2317",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(2317u32),
::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));
2318 }
2319 }
2320
2321 if let Some((prefix, mpi)) = shortest_uninit_seen {
2322 let tcx = this.infcx.tcx;
2328 if base.ty(this.body(), tcx).ty.is_union()
2329 && this.move_data.path_map[mpi].iter().any(|moi| {
2330 this.move_data.moves[*moi].source.is_predecessor_of(location, this.body)
2331 })
2332 {
2333 return;
2334 }
2335
2336 this.report_use_of_moved_or_uninitialized(
2337 location,
2338 InitializationRequiringAction::PartialAssignment,
2339 (prefix, base, span),
2340 mpi,
2341 );
2342
2343 this.used_mut.insert(base.local);
2347 }
2348 }
2349 }
2350
2351 fn check_access_permissions(
2355 &mut self,
2356 (place, span): (Place<'tcx>, Span),
2357 kind: ReadOrWrite,
2358 is_local_mutation_allowed: LocalMutationIsAllowed,
2359 state: &BorrowckDomain,
2360 location: Location,
2361 ) -> bool {
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_access_permissions({0:?}, {1:?}, is_local_mutation_allowed: {2:?})",
place, kind, is_local_mutation_allowed) as &dyn Value))])
});
} else { ; }
};debug!(
2363 "check_access_permissions({:?}, {:?}, is_local_mutation_allowed: {:?})",
2364 place, kind, is_local_mutation_allowed
2365 );
2366
2367 let error_access;
2368 let the_place_err;
2369
2370 match kind {
2371 Reservation(WriteKind::MutableBorrow(BorrowKind::Mut { kind: mut_borrow_kind }))
2372 | Write(WriteKind::MutableBorrow(BorrowKind::Mut { kind: mut_borrow_kind })) => {
2373 let is_local_mutation_allowed = match mut_borrow_kind {
2374 MutBorrowKind::ClosureCapture => LocalMutationIsAllowed::Yes,
2378 MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow => {
2379 is_local_mutation_allowed
2380 }
2381 };
2382 match self.is_mutable(place.as_ref(), is_local_mutation_allowed) {
2383 Ok(root_place) => {
2384 self.add_used_mut(root_place, state);
2385 return false;
2386 }
2387 Err(place_err) => {
2388 error_access = AccessKind::MutableBorrow;
2389 the_place_err = place_err;
2390 }
2391 }
2392 }
2393 Reservation(WriteKind::Mutate) | Write(WriteKind::Mutate) => {
2394 match self.is_mutable(place.as_ref(), is_local_mutation_allowed) {
2395 Ok(root_place) => {
2396 self.add_used_mut(root_place, state);
2397 return false;
2398 }
2399 Err(place_err) => {
2400 error_access = AccessKind::Mutate;
2401 the_place_err = place_err;
2402 }
2403 }
2404 }
2405
2406 Reservation(
2407 WriteKind::Move
2408 | WriteKind::Replace
2409 | WriteKind::StorageDeadOrDrop
2410 | WriteKind::MutableBorrow(BorrowKind::Shared)
2411 | WriteKind::MutableBorrow(BorrowKind::Fake(_)),
2412 )
2413 | Write(
2414 WriteKind::Move
2415 | WriteKind::Replace
2416 | WriteKind::StorageDeadOrDrop
2417 | WriteKind::MutableBorrow(BorrowKind::Shared)
2418 | WriteKind::MutableBorrow(BorrowKind::Fake(_)),
2419 ) => {
2420 if self.is_mutable(place.as_ref(), is_local_mutation_allowed).is_err()
2421 && !self.has_buffered_diags()
2422 {
2423 self.dcx().span_delayed_bug(
2429 span,
2430 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Accessing `{0:?}` with the kind `{1:?}` shouldn\'t be possible",
place, kind))
})format!(
2431 "Accessing `{place:?}` with the kind `{kind:?}` shouldn't be possible",
2432 ),
2433 );
2434 }
2435 return false;
2436 }
2437 Activation(..) => {
2438 return false;
2440 }
2441 Read(
2442 ReadKind::Borrow(BorrowKind::Mut { .. } | BorrowKind::Shared | BorrowKind::Fake(_))
2443 | ReadKind::Copy,
2444 ) => {
2445 return false;
2447 }
2448 }
2449
2450 let previously_initialized = self.is_local_ever_initialized(place.local, state);
2455
2456 if let Some(init_index) = previously_initialized {
2458 if let (AccessKind::Mutate, Some(_)) = (error_access, place.as_local()) {
2459 let init = &self.move_data.inits[init_index];
2462 let assigned_span = init.span(self.body);
2463 self.report_illegal_reassignment((place, span), assigned_span, place);
2464 } else {
2465 self.report_mutability_error(place, span, the_place_err, error_access, location)
2466 }
2467 true
2468 } else {
2469 false
2470 }
2471 }
2472
2473 fn is_local_ever_initialized(&self, local: Local, state: &BorrowckDomain) -> Option<InitIndex> {
2474 let mpi = self.move_data.rev_lookup.find_local(local)?;
2475 let ii = &self.move_data.init_path_map[mpi];
2476 ii.into_iter().find(|&&index| state.ever_inits.contains(index)).copied()
2477 }
2478
2479 fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, state: &BorrowckDomain) {
2481 match root_place {
2482 RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => {
2483 if is_local_mutation_allowed != LocalMutationIsAllowed::Yes
2487 && self.is_local_ever_initialized(local, state).is_some()
2488 {
2489 self.used_mut.insert(local);
2490 }
2491 }
2492 RootPlace {
2493 place_local: _,
2494 place_projection: _,
2495 is_local_mutation_allowed: LocalMutationIsAllowed::Yes,
2496 } => {}
2497 RootPlace {
2498 place_local,
2499 place_projection: place_projection @ [.., _],
2500 is_local_mutation_allowed: _,
2501 } => {
2502 if let Some(field) = self.is_upvar_field_projection(PlaceRef {
2503 local: place_local,
2504 projection: place_projection,
2505 }) {
2506 self.used_mut_upvars.push(field);
2507 }
2508 }
2509 }
2510 }
2511
2512 fn is_mutable(
2515 &self,
2516 place: PlaceRef<'tcx>,
2517 is_local_mutation_allowed: LocalMutationIsAllowed,
2518 ) -> Result<RootPlace<'tcx>, PlaceRef<'tcx>> {
2519 {
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:2519",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(2519u32),
::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);
2520 match place.last_projection() {
2521 None => {
2522 let local = &self.body.local_decls[place.local];
2523 match local.mutability {
2524 Mutability::Not => match is_local_mutation_allowed {
2525 LocalMutationIsAllowed::Yes => Ok(RootPlace {
2526 place_local: place.local,
2527 place_projection: place.projection,
2528 is_local_mutation_allowed: LocalMutationIsAllowed::Yes,
2529 }),
2530 LocalMutationIsAllowed::ExceptUpvars => Ok(RootPlace {
2531 place_local: place.local,
2532 place_projection: place.projection,
2533 is_local_mutation_allowed: LocalMutationIsAllowed::ExceptUpvars,
2534 }),
2535 LocalMutationIsAllowed::No => Err(place),
2536 },
2537 Mutability::Mut => Ok(RootPlace {
2538 place_local: place.local,
2539 place_projection: place.projection,
2540 is_local_mutation_allowed,
2541 }),
2542 }
2543 }
2544 Some((place_base, elem)) => {
2545 match elem {
2546 ProjectionElem::Deref => {
2547 let base_ty = place_base.ty(self.body(), self.infcx.tcx).ty;
2548
2549 match base_ty.kind() {
2551 ty::Ref(_, _, mutbl) => {
2552 match mutbl {
2553 hir::Mutability::Not => Err(place),
2555 hir::Mutability::Mut => {
2558 let mode = match self.is_upvar_field_projection(place) {
2559 Some(field)
2560 if self.upvars[field.index()].is_by_ref() =>
2561 {
2562 is_local_mutation_allowed
2563 }
2564 _ => LocalMutationIsAllowed::Yes,
2565 };
2566
2567 self.is_mutable(place_base, mode)
2568 }
2569 }
2570 }
2571 ty::RawPtr(_, mutbl) => {
2572 match mutbl {
2573 hir::Mutability::Not => Err(place),
2575 hir::Mutability::Mut => Ok(RootPlace {
2578 place_local: place.local,
2579 place_projection: place.projection,
2580 is_local_mutation_allowed,
2581 }),
2582 }
2583 }
2584 _ if base_ty.is_box() => {
2586 self.is_mutable(place_base, is_local_mutation_allowed)
2587 }
2588 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("Deref of unexpected type: {0:?}",
base_ty))bug!("Deref of unexpected type: {:?}", base_ty),
2590 }
2591 }
2592 ProjectionElem::Field(FieldIdx::ZERO, _)
2595 if let Some(adt) =
2596 place_base.ty(self.body(), self.infcx.tcx).ty.ty_adt_def()
2597 && adt.is_pin()
2598 && self.infcx.tcx.features().pin_ergonomics() =>
2599 {
2600 self.is_mutable(place_base, is_local_mutation_allowed)
2601 }
2602 ProjectionElem::Field(..)
2605 | ProjectionElem::Index(..)
2606 | ProjectionElem::ConstantIndex { .. }
2607 | ProjectionElem::Subslice { .. }
2608 | ProjectionElem::OpaqueCast { .. }
2609 | ProjectionElem::Downcast(..)
2610 | ProjectionElem::UnwrapUnsafeBinder(_) => {
2611 let upvar_field_projection = self.is_upvar_field_projection(place);
2612 if let Some(field) = upvar_field_projection {
2613 let upvar = &self.upvars[field.index()];
2614 {
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:2614",
"rustc_borrowck", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(2614u32),
::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!(
2615 "is_mutable: upvar.mutability={:?} local_mutation_is_allowed={:?} \
2616 place={:?}, place_base={:?}",
2617 upvar, is_local_mutation_allowed, place, place_base
2618 );
2619 match (upvar.mutability, is_local_mutation_allowed) {
2620 (
2621 Mutability::Not,
2622 LocalMutationIsAllowed::No
2623 | LocalMutationIsAllowed::ExceptUpvars,
2624 ) => Err(place),
2625 (Mutability::Not, LocalMutationIsAllowed::Yes)
2626 | (Mutability::Mut, _) => {
2627 let _ =
2646 self.is_mutable(place_base, is_local_mutation_allowed)?;
2647 Ok(RootPlace {
2648 place_local: place.local,
2649 place_projection: place.projection,
2650 is_local_mutation_allowed,
2651 })
2652 }
2653 }
2654 } else {
2655 self.is_mutable(place_base, is_local_mutation_allowed)
2656 }
2657 }
2658 }
2659 }
2660 }
2661 }
2662
2663 fn is_upvar_field_projection(&self, place_ref: PlaceRef<'tcx>) -> Option<FieldIdx> {
2668 path_utils::is_upvar_field_projection(self.infcx.tcx, &self.upvars, place_ref, self.body())
2669 }
2670
2671 fn dominators(&self) -> &Dominators<BasicBlock> {
2672 self.body.basic_blocks.dominators()
2674 }
2675
2676 fn lint_unused_mut(&self) {
2677 let tcx = self.infcx.tcx;
2678 let body = self.body;
2679 for local in body.mut_vars_and_args_iter().filter(|local| !self.used_mut.contains(local)) {
2680 let local_decl = &body.local_decls[local];
2681 let ClearCrossCrate::Set(SourceScopeLocalData { lint_root, .. }) =
2682 body.source_scopes[local_decl.source_info.scope].local_data
2683 else {
2684 continue;
2685 };
2686
2687 if self.local_excluded_from_unused_mut_lint(local) {
2689 continue;
2690 }
2691
2692 let span = local_decl.source_info.span;
2693 if span.desugaring_kind().is_some() {
2694 continue;
2696 }
2697
2698 let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);
2699
2700 tcx.emit_node_span_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span: mut_span })
2701 }
2702 }
2703}
2704
2705enum Overlap {
2707 Arbitrary,
2713 EqualOrDisjoint,
2718 Disjoint,
2721}