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