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