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