pub(crate) struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {Show 22 fields
pub(crate) infcx: &'infcx BorrowckInferCtxt<'tcx>,
pub(crate) param_env: ParamEnv<'tcx>,
pub(crate) body: &'a Body<'tcx>,
pub(crate) move_data: &'a MoveData<'tcx>,
pub(crate) location_table: &'a LocationTable,
pub(crate) movable_coroutine: bool,
pub(crate) locals_are_invalidated_at_exit: bool,
pub(crate) access_place_error_reported: FxIndexSet<(Place<'tcx>, Span)>,
pub(crate) reservation_error_reported: FxIndexSet<Place<'tcx>>,
pub(crate) fn_self_span_reported: FxIndexSet<Span>,
pub(crate) uninitialized_error_reported: FxIndexSet<Local>,
pub(crate) used_mut: FxIndexSet<Local>,
pub(crate) used_mut_upvars: SmallVec<[FieldIdx; 8]>,
pub(crate) regioncx: &'a RegionInferenceContext<'tcx>,
pub(crate) borrow_set: &'a BorrowSet<'tcx>,
pub(crate) upvars: &'tcx [&'tcx CapturedPlace<'tcx>],
pub(crate) local_names: IndexVec<Local, Option<Symbol>>,
pub(crate) region_names: RefCell<FxIndexMap<RegionVid, RegionName>>,
pub(crate) next_region_name: RefCell<usize>,
pub(crate) polonius_output: Option<Box<PoloniusOutput>>,
pub(crate) diags: &'a mut BorrowckDiags<'infcx, 'tcx>,
pub(crate) move_errors: Vec<MoveError<'tcx>>,
}
Fields§
§infcx: &'infcx BorrowckInferCtxt<'tcx>
§param_env: ParamEnv<'tcx>
§body: &'a Body<'tcx>
§move_data: &'a MoveData<'tcx>
§location_table: &'a LocationTable
Map from MIR Location
to LocationIndex
; created
when MIR borrowck begins.
movable_coroutine: bool
§locals_are_invalidated_at_exit: bool
This keeps track of whether local variables are free-ed when the function
exits even without a StorageDead
, which appears to be the case for
constants.
I’m not sure this is the right approach - @eddyb could you try and figure this out?
access_place_error_reported: FxIndexSet<(Place<'tcx>, Span)>
This field keeps track of when borrow errors are reported in the access_place function
so that there is no duplicate reporting. This field cannot also be used for the conflicting
borrow errors that is handled by the reservation_error_reported
field as the inclusion
of the Span
type (while required to mute some errors) stops the muting of the reservation
errors.
reservation_error_reported: FxIndexSet<Place<'tcx>>
This field keeps track of when borrow conflict errors are reported for reservations, so that we don’t report seemingly duplicate errors for corresponding activations.
fn_self_span_reported: FxIndexSet<Span>
This fields keeps track of the Span
s that we have
used to report extra information for FnSelfUse
, to avoid
unnecessarily verbose errors.
uninitialized_error_reported: FxIndexSet<Local>
This field keeps track of errors reported in the checking of uninitialized variables, so that we don’t report seemingly duplicate errors.
used_mut: FxIndexSet<Local>
This field keeps track of all the local variables that are declared mut and are mutated. Used for the warning issued by an unused mutable local variable.
used_mut_upvars: SmallVec<[FieldIdx; 8]>
If the function we’re checking is a closure, then we’ll need to report back the list of mutable upvars that have been used. This field keeps track of them.
regioncx: &'a RegionInferenceContext<'tcx>
Region inference context. This contains the results from region inference and lets us e.g. find out which CFG points are contained in each borrow region.
borrow_set: &'a BorrowSet<'tcx>
The set of borrows extracted from the MIR
upvars: &'tcx [&'tcx CapturedPlace<'tcx>]
Information about upvars not necessarily preserved in types or MIR
local_names: IndexVec<Local, Option<Symbol>>
Names of local (user) variables (extracted from var_debug_info
).
region_names: RefCell<FxIndexMap<RegionVid, RegionName>>
Record the region names generated for each region in the given MIR def so that we can reuse them later in help/error messages.
next_region_name: RefCell<usize>
The counter for generating new region names.
polonius_output: Option<Box<PoloniusOutput>>
Results of Polonius analysis.
diags: &'a mut BorrowckDiags<'infcx, 'tcx>
§move_errors: Vec<MoveError<'tcx>>
Implementations§
Source§impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx>
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx>
pub(crate) fn dcx(&self) -> DiagCtxtHandle<'infcx>
pub(crate) fn cannot_move_when_borrowed( &self, span: Span, borrow_span: Span, place: &str, borrow_place: &str, value_place: &str, ) -> Diag<'infcx>
pub(crate) fn cannot_use_when_mutably_borrowed( &self, span: Span, desc: &str, borrow_span: Span, borrow_desc: &str, ) -> Diag<'infcx>
pub(crate) fn cannot_mutably_borrow_multiply( &self, new_loan_span: Span, desc: &str, opt_via: &str, old_loan_span: Span, old_opt_via: &str, old_load_end_span: Option<Span>, ) -> Diag<'infcx>
pub(crate) fn cannot_uniquely_borrow_by_two_closures( &self, new_loan_span: Span, desc: &str, old_loan_span: Span, old_load_end_span: Option<Span>, ) -> Diag<'infcx>
pub(crate) fn cannot_uniquely_borrow_by_one_closure( &self, new_loan_span: Span, container_name: &str, desc_new: &str, opt_via: &str, old_loan_span: Span, noun_old: &str, old_opt_via: &str, previous_end_span: Option<Span>, ) -> Diag<'infcx>
pub(crate) fn cannot_reborrow_already_uniquely_borrowed( &self, new_loan_span: Span, container_name: &str, desc_new: &str, opt_via: &str, kind_new: &str, old_loan_span: Span, old_opt_via: &str, previous_end_span: Option<Span>, second_borrow_desc: &str, ) -> Diag<'infcx>
pub(crate) fn cannot_reborrow_already_borrowed( &self, span: Span, desc_new: &str, msg_new: &str, kind_new: &str, old_span: Span, noun_old: &str, kind_old: &str, msg_old: &str, old_load_end_span: Option<Span>, ) -> Diag<'infcx>
pub(crate) fn cannot_assign_to_borrowed( &self, span: Span, borrow_span: Span, desc: &str, ) -> Diag<'infcx>
pub(crate) fn cannot_reassign_immutable( &self, span: Span, desc: &str, is_arg: bool, ) -> Diag<'infcx>
pub(crate) fn cannot_assign(&self, span: Span, desc: &str) -> Diag<'infcx>
pub(crate) fn cannot_move_out_of( &self, move_from_span: Span, move_from_desc: &str, ) -> Diag<'infcx>
Sourcepub(crate) fn cannot_move_out_of_interior_noncopy(
&self,
move_from_span: Span,
ty: Ty<'_>,
is_index: Option<bool>,
) -> Diag<'infcx>
pub(crate) fn cannot_move_out_of_interior_noncopy( &self, move_from_span: Span, ty: Ty<'_>, is_index: Option<bool>, ) -> Diag<'infcx>
Signal an error due to an attempt to move out of the interior
of an array or slice. is_index
is None when error origin
didn’t capture whether there was an indexing operation or not.
pub(crate) fn cannot_move_out_of_interior_of_drop( &self, move_from_span: Span, container_ty: Ty<'_>, ) -> Diag<'infcx>
pub(crate) fn cannot_act_on_moved_value( &self, use_span: Span, verb: &str, optional_adverb_for_moved: &str, moved_path: Option<String>, ) -> Diag<'infcx>
pub(crate) fn cannot_borrow_path_as_mutable_because( &self, span: Span, path: &str, reason: &str, ) -> Diag<'infcx>
pub(crate) fn cannot_mutate_in_immutable_section( &self, mutate_span: Span, immutable_span: Span, immutable_place: &str, immutable_section: &str, action: &str, ) -> Diag<'infcx>
pub(crate) fn cannot_borrow_across_coroutine_yield( &self, span: Span, yield_span: Span, ) -> Diag<'infcx>
pub(crate) fn cannot_borrow_across_destructor( &self, borrow_span: Span, ) -> Diag<'infcx>
pub(crate) fn path_does_not_live_long_enough( &self, span: Span, path: &str, ) -> Diag<'infcx>
pub(crate) fn cannot_return_reference_to_local( &self, span: Span, return_kind: &str, reference_desc: &str, path_desc: &str, ) -> Diag<'infcx>
pub(crate) fn cannot_capture_in_long_lived_closure( &self, closure_span: Span, closure_kind: &str, borrowed_path: &str, capture_span: Span, scope: &str, ) -> Diag<'infcx>
pub(crate) fn thread_local_value_does_not_live_long_enough( &self, span: Span, ) -> Diag<'infcx>
pub(crate) fn temporary_value_borrowed_for_too_long( &self, span: Span, ) -> Diag<'infcx>
Source§impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx>
impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx>
pub(crate) fn mir_def_id(&self) -> LocalDefId
pub(crate) fn mir_hir_id(&self) -> HirId
Sourcepub(crate) fn synthesize_region_name(&self) -> Symbol
pub(crate) fn synthesize_region_name(&self) -> Symbol
Generate a synthetic region named 'N
, where N
is the next value of the counter. Then,
increment the counter.
This is not idempotent. Call give_region_a_name
when possible.
Sourcepub(crate) fn give_region_a_name(&self, fr: RegionVid) -> Option<RegionName>
pub(crate) fn give_region_a_name(&self, fr: RegionVid) -> Option<RegionName>
Maps from an internal MIR region vid to something that we can
report to the user. In some cases, the region vids will map
directly to lifetimes that the user has a name for (e.g.,
'static
). But frequently they will not, in which case we
have to find some way to identify the lifetime to the user. To
that end, this function takes a “diagnostic” so that it can
create auxiliary notes as needed.
The names are memoized, so this is both cheap to recompute and idempotent.
Example (function arguments):
Suppose we are trying to give a name to the lifetime of the
reference x
:
fn foo(x: &u32) { .. }
This function would create a label like this:
| fn foo(x: &u32) { .. }
------- fully elaborated type of `x` is `&'1 u32`
and then return the name '1
for us to use.
Sourcefn give_name_from_error_region(&self, fr: RegionVid) -> Option<RegionName>
fn give_name_from_error_region(&self, fr: RegionVid) -> Option<RegionName>
Checks for the case where fr
maps to something that the
user has a name for. In that case, we’ll be able to map
fr
to a Region<'tcx>
, and that region will be one of
named variants.
Sourcefn give_name_if_anonymous_region_appears_in_arguments(
&self,
fr: RegionVid,
) -> Option<RegionName>
fn give_name_if_anonymous_region_appears_in_arguments( &self, fr: RegionVid, ) -> Option<RegionName>
Finds an argument that contains fr
and label it with a fully
elaborated type, returning something like '1
. Result looks
like:
| fn foo(x: &u32) { .. }
------- fully elaborated type of `x` is `&'1 u32`
fn get_argument_hir_ty_for_highlighting( &self, argument_index: usize, ) -> Option<&Ty<'tcx>>
Sourcefn highlight_if_we_cannot_match_hir_ty(
&self,
needle_fr: RegionVid,
ty: Ty<'tcx>,
span: Span,
counter: usize,
) -> RegionNameHighlight
fn highlight_if_we_cannot_match_hir_ty( &self, needle_fr: RegionVid, ty: Ty<'tcx>, span: Span, counter: usize, ) -> RegionNameHighlight
Attempts to highlight the specific part of a type in an argument that has no type annotation. For example, we might produce an annotation like this:
| foo(|a, b| b)
| - -
| | |
| | has type `&'1 u32`
| has type `&'2 u32`
Sourcefn highlight_if_we_can_match_hir_ty(
&self,
needle_fr: RegionVid,
ty: Ty<'tcx>,
hir_ty: &Ty<'_>,
) -> Option<RegionNameHighlight>
fn highlight_if_we_can_match_hir_ty( &self, needle_fr: RegionVid, ty: Ty<'tcx>, hir_ty: &Ty<'_>, ) -> Option<RegionNameHighlight>
Attempts to highlight the specific part of a type annotation that contains the anonymous reference we want to give a name to. For example, we might produce an annotation like this:
| fn a<T>(items: &[T]) -> Box<dyn Iterator<Item = &T>> {
| - let's call the lifetime of this reference `'1`
the way this works is that we match up ty
, which is
a Ty<'tcx>
(the internal form of the type) with
hir_ty
, a hir::Ty
(the syntax of the type
annotation). We are descending through the types stepwise,
looking in to find the region needle_fr
in the internal
type. Once we find that, we can use the span of the hir::Ty
to add the highlight.
This is a somewhat imperfect process, so along the way we also
keep track of the closest type we’ve found. If we fail to
find the exact &
or '_
to highlight, then we may fall back
to highlighting that closest type instead.
Sourcefn match_adt_and_segment<'hir>(
&self,
args: GenericArgsRef<'tcx>,
needle_fr: RegionVid,
last_segment: &'hir PathSegment<'hir>,
search_stack: &mut Vec<(Ty<'tcx>, &'hir Ty<'hir>)>,
) -> Option<RegionNameHighlight>
fn match_adt_and_segment<'hir>( &self, args: GenericArgsRef<'tcx>, needle_fr: RegionVid, last_segment: &'hir PathSegment<'hir>, search_stack: &mut Vec<(Ty<'tcx>, &'hir Ty<'hir>)>, ) -> Option<RegionNameHighlight>
We’ve found an enum/struct/union type with the generic args
args
and – in the HIR – a path type with the final
segment last_segment
. Try to find a '_
to highlight in
the generic args (or, if not, to produce new zipped pairs of
types+hir to search through).
Sourcefn try_match_adt_and_generic_args<'hir>(
&self,
args: GenericArgsRef<'tcx>,
needle_fr: RegionVid,
hir_args: &'hir GenericArgs<'hir>,
search_stack: &mut Vec<(Ty<'tcx>, &'hir Ty<'hir>)>,
) -> Option<&'hir Lifetime>
fn try_match_adt_and_generic_args<'hir>( &self, args: GenericArgsRef<'tcx>, needle_fr: RegionVid, hir_args: &'hir GenericArgs<'hir>, search_stack: &mut Vec<(Ty<'tcx>, &'hir Ty<'hir>)>, ) -> Option<&'hir Lifetime>
We’ve found an enum/struct/union type with the generic args
args
and – in the HIR – a path with the generic
arguments hir_args
. If needle_fr
appears in the args, return
the hir::Lifetime
that corresponds to it. If not, push onto
search_stack
the types+hir to search through.
Sourcefn give_name_if_anonymous_region_appears_in_upvars(
&self,
fr: RegionVid,
) -> Option<RegionName>
fn give_name_if_anonymous_region_appears_in_upvars( &self, fr: RegionVid, ) -> Option<RegionName>
Finds a closure upvar that contains fr
and label it with a
fully elaborated type, returning something like '1
. Result
looks like:
| let x = Some(&22);
- fully elaborated type of `x` is `Option<&'1 u32>`
Sourcefn give_name_if_anonymous_region_appears_in_output(
&self,
fr: RegionVid,
) -> Option<RegionName>
fn give_name_if_anonymous_region_appears_in_output( &self, fr: RegionVid, ) -> Option<RegionName>
Checks for arguments appearing in the (closure) return type. It must be a closure since, in a free fn, such an argument would have to either also appear in an argument (if using elision) or be early bound (named, not in argument).
Sourcefn get_future_inner_return_ty(&self, hir_ty: &'tcx Ty<'tcx>) -> &'tcx Ty<'tcx>
fn get_future_inner_return_ty(&self, hir_ty: &'tcx Ty<'tcx>) -> &'tcx Ty<'tcx>
From the hir::Ty
of an async function’s lowered return type,
retrieve the hir::Ty
representing the type the user originally wrote.
e.g. given the function:
async fn foo() -> i32 { 2 }
this function, given the lowered return type of foo
, an OpaqueDef
that implements
Future<Output=i32>
, returns the i32
.
fn give_name_if_anonymous_region_appears_in_yield_ty( &self, fr: RegionVid, ) -> Option<RegionName>
fn give_name_if_anonymous_region_appears_in_impl_signature( &self, fr: RegionVid, ) -> Option<RegionName>
fn give_name_if_anonymous_region_appears_in_arg_position_impl_trait( &self, fr: RegionVid, ) -> Option<RegionName>
fn any_param_predicate_mentions( &self, clauses: &[Clause<'tcx>], ty: Ty<'tcx>, region: EarlyParamRegion, ) -> bool
Source§impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx>
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx>
pub(crate) fn report_use_of_moved_or_uninitialized( &mut self, location: Location, desired_action: InitializationRequiringAction, (moved_place, used_place, span): (PlaceRef<'tcx>, PlaceRef<'tcx>, Span), mpi: MovePathIndex, )
fn suggest_ref_or_clone( &self, mpi: MovePathIndex, err: &mut Diag<'infcx>, in_pattern: &mut bool, move_spans: UseSpans<'tcx>, moved_place: PlaceRef<'tcx>, has_suggest_reborrow: &mut bool, moved_or_invoked_closure: bool, )
fn suggest_ref_for_dbg_args( &self, body: &Expr<'_>, place: &Place<'tcx>, move_span: Span, err: &mut Diag<'infcx>, )
pub(crate) fn suggest_reborrow( &self, err: &mut Diag<'infcx>, span: Span, moved_place: PlaceRef<'tcx>, )
Sourcefn suggest_borrow_generic_arg(
&self,
err: &mut Diag<'_>,
callee_did: DefId,
generic_args: GenericArgsRef<'tcx>,
param: ParamTy,
moved_place: PlaceRef<'tcx>,
moved_arg_pos: usize,
moved_arg_ty: Ty<'tcx>,
place_span: Span,
) -> Option<Mutability>
fn suggest_borrow_generic_arg( &self, err: &mut Diag<'_>, callee_did: DefId, generic_args: GenericArgsRef<'tcx>, param: ParamTy, moved_place: PlaceRef<'tcx>, moved_arg_pos: usize, moved_arg_ty: Ty<'tcx>, place_span: Span, ) -> Option<Mutability>
If a place is used after being moved as an argument to a function, the function is generic
in that argument, and a reference to the argument’s type would still satisfy the function’s
bounds, suggest borrowing. This covers, e.g., borrowing an impl Fn()
argument being passed
in an impl FnOnce()
position.
Returns Some(mutability)
when suggesting to borrow with mutability mutability
, or None
if no suggestion is made.
fn report_use_of_uninitialized( &self, mpi: MovePathIndex, used_place: PlaceRef<'tcx>, moved_place: PlaceRef<'tcx>, desired_action: InitializationRequiringAction, span: Span, use_spans: UseSpans<'tcx>, ) -> Diag<'infcx>
fn suggest_assign_value( &self, err: &mut Diag<'_>, moved_place: PlaceRef<'tcx>, sugg_span: Span, )
Sourcefn suggest_hoisting_call_outside_loop(
&self,
err: &mut Diag<'_>,
expr: &Expr<'_>,
) -> bool
fn suggest_hoisting_call_outside_loop( &self, err: &mut Diag<'_>, expr: &Expr<'_>, ) -> bool
In a move error that occurs on a call within a loop, we try to identify cases where cloning
the value would lead to a logic error. We infer these cases by seeing if the moved value is
part of the logic to break the loop, either through an explicit break
or if the expression
is part of a while let
.
Sourcefn suggest_cloning_on_functional_record_update(
&self,
err: &mut Diag<'_>,
ty: Ty<'tcx>,
expr: &Expr<'_>,
)
fn suggest_cloning_on_functional_record_update( &self, err: &mut Diag<'_>, ty: Ty<'tcx>, expr: &Expr<'_>, )
We have S { foo: val, ..base }
, and we suggest instead writing
S { foo: val, bar: base.bar.clone(), .. }
when valid.
pub(crate) fn suggest_cloning( &self, err: &mut Diag<'_>, ty: Ty<'tcx>, expr: &'tcx Expr<'tcx>, use_spans: Option<UseSpans<'tcx>>, )
pub(crate) fn implements_clone(&self, ty: Ty<'tcx>) -> bool
Sourcepub(crate) fn clone_on_reference(&self, expr: &Expr<'_>) -> Option<Span>
pub(crate) fn clone_on_reference(&self, expr: &Expr<'_>) -> Option<Span>
Given an expression, check if it is a method call foo.clone()
, where foo
and
foo.clone()
both have the same type, returning the span for .clone()
if so.
fn in_move_closure(&self, expr: &Expr<'_>) -> bool
fn suggest_cloning_inner( &self, err: &mut Diag<'_>, ty: Ty<'tcx>, expr: &Expr<'_>, ) -> bool
fn suggest_adding_bounds( &self, err: &mut Diag<'_>, ty: Ty<'tcx>, def_id: DefId, span: Span, )
pub(crate) fn report_move_out_while_borrowed( &mut self, location: Location, (place, span): (Place<'tcx>, Span), borrow: &BorrowData<'tcx>, )
pub(crate) fn report_use_while_mutably_borrowed( &self, location: Location, (place, _span): (Place<'tcx>, Span), borrow: &BorrowData<'tcx>, ) -> Diag<'infcx>
pub(crate) fn report_conflicting_borrow( &self, location: Location, (place, span): (Place<'tcx>, Span), gen_borrow_kind: BorrowKind, issued_borrow: &BorrowData<'tcx>, ) -> Diag<'infcx>
fn suggest_copy_for_type_in_cloned_ref( &self, err: &mut Diag<'infcx>, place: Place<'tcx>, )
pub(crate) fn suggest_adding_bounds_or_derive( &self, err: &mut Diag<'_>, ty: Ty<'tcx>, trait_def_id: DefId, span: Span, )
fn suggest_using_local_if_applicable( &self, err: &mut Diag<'_>, location: Location, issued_borrow: &BorrowData<'tcx>, explanation: BorrowExplanation<'tcx>, )
pub(crate) fn find_expr(&self, span: Span) -> Option<&'tcx Expr<'tcx>>
fn suggest_slice_method_if_applicable( &self, err: &mut Diag<'_>, place: Place<'tcx>, borrowed_place: Place<'tcx>, span: Span, issued_span: Span, )
Sourcepub(crate) fn explain_iterator_advancement_in_for_loop_if_applicable(
&self,
err: &mut Diag<'_>,
span: Span,
issued_spans: &UseSpans<'tcx>,
)
pub(crate) fn explain_iterator_advancement_in_for_loop_if_applicable( &self, err: &mut Diag<'_>, span: Span, issued_spans: &UseSpans<'tcx>, )
Suggest using while let
for call next
on an iterator in a for loop.
For example:
for x in iter {
...
iter.next()
}
Sourcefn suggest_using_closure_argument_instead_of_capture(
&self,
err: &mut Diag<'_>,
borrowed_place: Place<'tcx>,
issued_spans: &UseSpans<'tcx>,
)
fn suggest_using_closure_argument_instead_of_capture( &self, err: &mut Diag<'_>, borrowed_place: Place<'tcx>, issued_spans: &UseSpans<'tcx>, )
Suggest using closure argument instead of capture.
For example:
struct S;
impl S {
fn call(&mut self, f: impl Fn(&mut Self)) { /* ... */ }
fn x(&self) {}
}
let mut v = S;
v.call(|this: &mut S| v.x());
// ^\ ^-- help: try using the closure argument: `this`
// *-- error: cannot borrow `v` as mutable because it is also borrowed as immutable
fn suggest_binding_for_closure_capture_self( &self, err: &mut Diag<'_>, issued_spans: &UseSpans<'tcx>, )
Sourcefn describe_place_for_conflicting_borrow(
&self,
first_borrowed_place: Place<'tcx>,
second_borrowed_place: Place<'tcx>,
) -> (String, String, String, String)
fn describe_place_for_conflicting_borrow( &self, first_borrowed_place: Place<'tcx>, second_borrowed_place: Place<'tcx>, ) -> (String, String, String, String)
Returns the description of the root place for a conflicting borrow and the full descriptions of the places that caused the conflict.
In the simplest case, where there are no unions involved, if a mutable borrow of x
is
attempted while a shared borrow is live, then this function will return:
("x", "", "")
In the simple union case, if a mutable borrow of a union field x.z
is attempted while
a shared borrow of another field x.y
, then this function will return:
("x", "x.z", "x.y")
In the more complex union case, where the union is a field of a struct, then if a mutable
borrow of a union field in a struct x.u.z
is attempted while a shared borrow of
another field x.u.y
, then this function will return:
("x.u", "x.u.z", "x.u.y")
This is used when creating error messages like below:
cannot borrow `a.u` (via `a.u.z.c`) as immutable because it is also borrowed as
mutable (via `a.u.s.b`) [E0502]
Sourcepub(crate) fn report_borrowed_value_does_not_live_long_enough(
&mut self,
location: Location,
borrow: &BorrowData<'tcx>,
place_span: (Place<'tcx>, Span),
kind: Option<WriteKind>,
)
pub(crate) fn report_borrowed_value_does_not_live_long_enough( &mut self, location: Location, borrow: &BorrowData<'tcx>, place_span: (Place<'tcx>, Span), kind: Option<WriteKind>, )
This means that some data referenced by borrow
needs to live
past the point where the StorageDeadOrDrop of place
occurs.
This is usually interpreted as meaning that place
has too
short a lifetime. (But sometimes it is more useful to report
it as a more direct conflict between the execution of a
Drop::drop
with an aliasing borrow.)
fn report_local_value_does_not_live_long_enough( &self, location: Location, name: &str, borrow: &BorrowData<'tcx>, drop_span: Span, borrow_spans: UseSpans<'tcx>, explanation: BorrowExplanation<'tcx>, ) -> Diag<'infcx>
fn report_borrow_conflicts_with_destructor( &mut self, location: Location, borrow: &BorrowData<'tcx>, (place, drop_span): (Place<'tcx>, Span), kind: Option<WriteKind>, dropped_ty: Ty<'tcx>, )
fn report_thread_local_value_does_not_live_long_enough( &self, drop_span: Span, borrow_span: Span, ) -> Diag<'infcx>
fn report_temporary_value_does_not_live_long_enough( &self, location: Location, borrow: &BorrowData<'tcx>, drop_span: Span, borrow_spans: UseSpans<'tcx>, proper_span: Span, explanation: BorrowExplanation<'tcx>, ) -> Diag<'infcx>
fn try_report_cannot_return_reference_to_local( &self, borrow: &BorrowData<'tcx>, borrow_span: Span, return_span: Span, category: ConstraintCategory<'tcx>, opt_place_desc: Option<&String>, ) -> Result<(), Diag<'infcx>>
fn report_escaping_closure_capture( &self, use_span: UseSpans<'tcx>, var_span: Span, fr_name: &RegionName, category: ConstraintCategory<'tcx>, constraint_span: Span, captured_var: &str, scope: &str, ) -> Diag<'infcx>
fn report_escaping_data( &self, borrow_span: Span, name: &Option<String>, upvar_span: Span, upvar_name: Symbol, escape_span: Span, ) -> Diag<'infcx>
fn get_moved_indexes( &self, location: Location, mpi: MovePathIndex, ) -> (Vec<MoveSite>, Vec<Location>)
pub(crate) fn report_illegal_mutation_of_borrowed( &mut self, location: Location, (place, span): (Place<'tcx>, Span), loan: &BorrowData<'tcx>, )
fn explain_deref_coercion( &mut self, loan: &BorrowData<'tcx>, err: &mut Diag<'_>, )
Sourcepub(crate) fn report_illegal_reassignment(
&mut self,
(place, span): (Place<'tcx>, Span),
assigned_span: Span,
err_place: Place<'tcx>,
)
pub(crate) fn report_illegal_reassignment( &mut self, (place, span): (Place<'tcx>, Span), assigned_span: Span, err_place: Place<'tcx>, )
Reports an illegal reassignment; for example, an assignment to
(part of) a non-mut
local that occurs potentially after that
local has already been initialized. place
is the path being
assigned; err_place
is a place providing a reason why
place
is not mutable (e.g., the non-mut
local x
in an
assignment to x.f
).
fn classify_drop_access_kind( &self, place: PlaceRef<'tcx>, ) -> StorageDeadOrDrop<'tcx>
Sourcefn classify_immutable_section(&self, place: Place<'tcx>) -> Option<&'static str>
fn classify_immutable_section(&self, place: Place<'tcx>) -> Option<&'static str>
Describe the reason for the fake borrow that was assigned to place
.
Sourcefn annotate_argument_and_return_for_borrow(
&self,
borrow: &BorrowData<'tcx>,
) -> Option<AnnotatedBorrowFnSignature<'tcx>>
fn annotate_argument_and_return_for_borrow( &self, borrow: &BorrowData<'tcx>, ) -> Option<AnnotatedBorrowFnSignature<'tcx>>
Annotate argument and return type of function and closure with (synthesized) lifetime for borrow of local value that does not live long enough.
Sourcefn annotate_fn_sig(
&self,
did: LocalDefId,
sig: PolyFnSig<'tcx>,
) -> Option<AnnotatedBorrowFnSignature<'tcx>>
fn annotate_fn_sig( &self, did: LocalDefId, sig: PolyFnSig<'tcx>, ) -> Option<AnnotatedBorrowFnSignature<'tcx>>
Annotate the first argument and return type of a function signature if they are references.
Source§impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx>
impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx>
fn free_region_constraint_info( &self, borrow_region: RegionVid, outlived_region: RegionVid, ) -> (ConstraintCategory<'tcx>, bool, Span, Option<RegionName>, Vec<ExtraConstraintInfo>)
Sourcepub(crate) fn explain_why_borrow_contains_point(
&self,
location: Location,
borrow: &BorrowData<'tcx>,
kind_place: Option<(WriteKind, Place<'tcx>)>,
) -> BorrowExplanation<'tcx>
pub(crate) fn explain_why_borrow_contains_point( &self, location: Location, borrow: &BorrowData<'tcx>, kind_place: Option<(WriteKind, Place<'tcx>)>, ) -> BorrowExplanation<'tcx>
Returns structured explanation for why the borrow contains the
point from location
. This is key for the “3-point errors”
described in the NLL RFC.
§Parameters
borrow
: the borrow in questionlocation
: where the borrow occurskind_place
: if Some, this describes the statement that triggered the error.- first half is the kind of write, if any, being performed
- second half is the place being accessed
Sourcefn later_use_kind(
&self,
borrow: &BorrowData<'tcx>,
use_spans: UseSpans<'tcx>,
location: Location,
) -> (LaterUseKind, Span, Option<Span>)
fn later_use_kind( &self, borrow: &BorrowData<'tcx>, use_spans: UseSpans<'tcx>, location: Location, ) -> (LaterUseKind, Span, Option<Span>)
Determine how the borrow was later used.
First span returned points to the location of the conflicting use
Second span if Some
is returned in the case of closures and points
to the use of the path
Sourcefn was_captured_by_trait_object(&self, borrow: &BorrowData<'tcx>) -> bool
fn was_captured_by_trait_object(&self, borrow: &BorrowData<'tcx>) -> bool
Checks if a borrowed value was captured by a trait object. We do this by looking forward in the MIR from the reserve location and checking if we see an unsized cast to a trait object on our data.
Source§impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx>
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx>
pub(crate) fn report_move_errors(&mut self)
fn group_move_errors(&mut self) -> Vec<GroupedMoveError<'tcx>>
fn append_to_grouped_errors( &self, grouped_errors: &mut Vec<GroupedMoveError<'tcx>>, error: MoveError<'tcx>, )
fn append_binding_error( &self, grouped_errors: &mut Vec<GroupedMoveError<'tcx>>, kind: IllegalMoveOriginKind<'tcx>, original_path: Place<'tcx>, move_from: Place<'tcx>, bind_to: Local, match_place: Option<Place<'tcx>>, match_span: Span, statement_span: Span, )
fn report(&mut self, error: GroupedMoveError<'tcx>)
fn has_ambiguous_copy(&mut self, ty: Ty<'tcx>) -> bool
fn report_cannot_move_from_static( &mut self, place: Place<'tcx>, span: Span, ) -> Diag<'infcx>
fn suggest_clone_of_captured_var_in_move_closure( &self, err: &mut Diag<'_>, upvar_hir_id: HirId, upvar_name: &str, use_spans: Option<UseSpans<'tcx>>, )
fn report_cannot_move_from_borrowed_content( &mut self, move_place: Place<'tcx>, deref_target_place: Place<'tcx>, span: Span, use_spans: Option<UseSpans<'tcx>>, ) -> Diag<'infcx>
fn add_move_hints( &self, error: GroupedMoveError<'tcx>, err: &mut Diag<'_>, span: Span, )
fn add_borrow_suggestions(&self, err: &mut Diag<'_>, span: Span)
fn add_move_error_suggestions(&self, err: &mut Diag<'_>, binds_to: &[Local])
fn add_move_error_details(&self, err: &mut Diag<'_>, binds_to: &[Local])
Sourcefn add_note_for_packed_struct_derive(&self, err: &mut Diag<'_>, local: Local)
fn add_note_for_packed_struct_derive(&self, err: &mut Diag<'_>, local: Local)
Adds an explanatory note if the move error occurs in a derive macro expansion of a packed struct. Such errors happen because derive macro expansions shy away from taking references to the struct’s fields since doing so would be undefined behaviour
Source§impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx>
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx>
pub(crate) fn report_mutability_error( &mut self, access_place: Place<'tcx>, span: Span, the_place_err: PlaceRef<'tcx>, error_access: AccessKind, location: Location, )
Sourcefn suggest_map_index_mut_alternatives(
&self,
ty: Ty<'tcx>,
err: &mut Diag<'infcx>,
span: Span,
)
fn suggest_map_index_mut_alternatives( &self, ty: Ty<'tcx>, err: &mut Diag<'infcx>, span: Span, )
Suggest map[k] = v
=> map.insert(k, v)
and the like.
Sourcefn is_error_in_trait(&self, local: Local) -> (bool, bool, Option<Span>)
fn is_error_in_trait(&self, local: Local) -> (bool, bool, Option<Span>)
User cannot make signature of a trait mutable without changing the trait. So we find if this error belongs to a trait and if so we move suggestion to the trait or disable it if it is out of scope of this crate
The returned values are:
- is the current item an assoc
fn
of an impl that corresponds to a trait def? if so, we have to suggest changing both the implfn
arg and the traitfn
arg - is the trait from the local crate? If not, we can’t suggest changing signatures
Span
of the argument in the trait definition
fn construct_mut_suggestion_for_local_binding_patterns( &self, err: &mut Diag<'_>, local: Local, )
fn show_mutating_upvar( &self, tcx: TyCtxt<'_>, closure_local_def_id: LocalDefId, the_place_err: PlaceRef<'tcx>, err: &mut Diag<'_>, )
fn suggest_similar_mut_method_for_for_loop( &self, err: &mut Diag<'_>, span: Span, )
Sourcefn expected_fn_found_fn_mut_call(&self, err: &mut Diag<'_>, sp: Span, act: &str)
fn expected_fn_found_fn_mut_call(&self, err: &mut Diag<'_>, sp: Span, act: &str)
Targeted error when encountering an FnMut
closure where an Fn
closure was expected.
fn suggest_using_iter_mut(&self, err: &mut Diag<'_>)
fn suggest_make_local_mut(&self, err: &mut Diag<'_>, local: Local, name: Symbol)
Source§impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx>
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx>
Sourcepub(crate) fn note_due_to_edition_2024_opaque_capture_rules(
&self,
borrow: &BorrowData<'tcx>,
diag: &mut Diag<'_>,
)
pub(crate) fn note_due_to_edition_2024_opaque_capture_rules( &self, borrow: &BorrowData<'tcx>, diag: &mut Diag<'_>, )
Try to note when an opaque is involved in a borrowck error and that opaque captures lifetimes due to edition 2024.
Source§impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx>
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx>
Sourcepub(super) fn to_error_region(&self, r: RegionVid) -> Option<Region<'tcx>>
pub(super) fn to_error_region(&self, r: RegionVid) -> Option<Region<'tcx>>
Converts a region inference variable into a ty::Region
that
we can use for error reporting. If r
is universally bound,
then we use the name that we have on record for it. If r
is
existentially bound, then we check its inferred value and try
to find a good name from that. Returns None
if we can’t find
one (e.g., this is just some random part of the CFG).
Sourcepub(super) fn to_error_region_vid(&self, r: RegionVid) -> Option<RegionVid>
pub(super) fn to_error_region_vid(&self, r: RegionVid) -> Option<RegionVid>
Returns the RegionVid
corresponding to the region returned by
to_error_region
.
Sourcefn is_closure_fn_mut(&self, fr: RegionVid) -> bool
fn is_closure_fn_mut(&self, fr: RegionVid) -> bool
Returns true
if a closure is inferred to be an FnMut
closure.
fn suggest_static_lifetime_for_gat_from_hrtb( &self, diag: &mut Diag<'_>, lower_bound: RegionVid, )
Sourcepub(crate) fn report_region_errors(&mut self, nll_errors: RegionErrors<'tcx>)
pub(crate) fn report_region_errors(&mut self, nll_errors: RegionErrors<'tcx>)
Produces nice borrowck error diagnostics for all the errors collected in nll_errors
.
Sourcepub(crate) fn report_region_error(
&mut self,
fr: RegionVid,
fr_origin: NllRegionVariableOrigin,
outlived_fr: RegionVid,
outlives_suggestion: &mut OutlivesSuggestionBuilder,
)
pub(crate) fn report_region_error( &mut self, fr: RegionVid, fr_origin: NllRegionVariableOrigin, outlived_fr: RegionVid, outlives_suggestion: &mut OutlivesSuggestionBuilder, )
Report an error because the universal region fr
was required to outlive
outlived_fr
but it is not known to do so. For example:
fn foo<'a, 'b>(x: &'a u32) -> &'b u32 { x }
Here we would be invoked with fr = 'a
and outlived_fr = 'b
.
Sourcefn report_fnmut_error(
&self,
errci: &ErrorConstraintInfo<'tcx>,
kind: ReturnConstraint,
) -> Diag<'infcx>
fn report_fnmut_error( &self, errci: &ErrorConstraintInfo<'tcx>, kind: ReturnConstraint, ) -> Diag<'infcx>
Report a specialized error when FnMut
closures return a reference to a captured variable.
This function expects fr
to be local and outlived_fr
to not be local.
error: captured variable cannot escape `FnMut` closure body
--> $DIR/issue-53040.rs:15:8
|
LL | || &mut v;
| -- ^^^^^^ creates a reference to a captured variable which escapes the closure body
| |
| inferred to be a `FnMut` closure
|
= note: `FnMut` closures only have access to their captured variables while they are
executing...
= note: ...therefore, returned references to captured variables will escape the closure
Sourcefn report_escaping_data_error(
&self,
errci: &ErrorConstraintInfo<'tcx>,
) -> Diag<'infcx>
fn report_escaping_data_error( &self, errci: &ErrorConstraintInfo<'tcx>, ) -> Diag<'infcx>
Reports an error specifically for when data is escaping a closure.
error: borrowed data escapes outside of function
--> $DIR/lifetime-bound-will-change-warning.rs:44:5
|
LL | fn test2<'a>(x: &'a Box<Fn()+'a>) {
| - `x` is a reference that is only valid in the function body
LL | // but ref_obj will not, so warn.
LL | ref_obj(x)
| ^^^^^^^^^^ `x` escapes the function body here
Sourcefn report_general_error(
&self,
errci: &ErrorConstraintInfo<'tcx>,
) -> Diag<'infcx>
fn report_general_error( &self, errci: &ErrorConstraintInfo<'tcx>, ) -> Diag<'infcx>
Reports a region inference error for the general case with named/synthesized lifetimes to explain what is happening.
error: unsatisfied lifetime constraints
--> $DIR/regions-creating-enums3.rs:17:5
|
LL | fn mk_add_bad1<'a,'b>(x: &'a ast<'a>, y: &'b ast<'b>) -> ast<'a> {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | ast::add(x, y)
| ^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it
| is returning data with lifetime `'b`
Sourcefn add_static_impl_trait_suggestion(
&self,
diag: &mut Diag<'_>,
fr: RegionVid,
fr_name: RegionName,
outlived_fr: RegionVid,
)
fn add_static_impl_trait_suggestion( &self, diag: &mut Diag<'_>, fr: RegionVid, fr_name: RegionName, outlived_fr: RegionVid, )
Adds a suggestion to errors where an impl Trait
is returned.
help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as
a constraint
|
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
fn maybe_suggest_constrain_dyn_trait_impl( &self, diag: &mut Diag<'_>, f: Region<'tcx>, o: Region<'tcx>, category: &ConstraintCategory<'tcx>, )
fn suggest_constrain_dyn_trait_in_impl( &self, err: &mut Diag<'_>, found_dids: &FxIndexSet<DefId>, ident: Ident, self_ty: &Ty<'_>, ) -> bool
fn suggest_adding_lifetime_params( &self, diag: &mut Diag<'_>, sub: RegionVid, sup: RegionVid, )
Sourcefn suggest_deref_closure_return(&self, diag: &mut Diag<'_>)
fn suggest_deref_closure_return(&self, diag: &mut Diag<'_>)
When encountering a lifetime error caused by the return type of a closure, check the corresponding trait bound and see if dereferencing the closure return value would satisfy them. If so, we produce a structured suggestion.
fn suggest_move_on_borrowing_closure(&self, diag: &mut Diag<'_>)
Source§impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx>
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx>
Sourcepub(crate) fn add_moved_or_invoked_closure_note(
&self,
location: Location,
place: PlaceRef<'tcx>,
diag: &mut Diag<'infcx>,
) -> bool
pub(crate) fn add_moved_or_invoked_closure_note( &self, location: Location, place: PlaceRef<'tcx>, diag: &mut Diag<'infcx>, ) -> bool
Adds a suggestion when a closure is invoked twice with a moved variable or when a closure is moved after being invoked.
note: closure cannot be invoked more than once because it moves the variable `dict` out of
its environment
--> $DIR/issue-42065.rs:16:29
|
LL | for (key, value) in dict {
| ^^^^
Sourcepub(crate) fn describe_any_place(&self, place_ref: PlaceRef<'tcx>) -> String
pub(crate) fn describe_any_place(&self, place_ref: PlaceRef<'tcx>) -> String
End-user visible description of place
if one can be found.
If the place is a temporary for instance, "value"
will be returned.
Sourcepub(crate) fn describe_place(&self, place_ref: PlaceRef<'tcx>) -> Option<String>
pub(crate) fn describe_place(&self, place_ref: PlaceRef<'tcx>) -> Option<String>
End-user visible description of place
if one can be found.
If the place is a temporary for instance, None
will be returned.
Sourcepub(crate) fn describe_place_with_options(
&self,
place: PlaceRef<'tcx>,
opt: DescribePlaceOpt,
) -> Option<String>
pub(crate) fn describe_place_with_options( &self, place: PlaceRef<'tcx>, opt: DescribePlaceOpt, ) -> Option<String>
End-user visible description of place
if one can be found. If the place is a temporary
for instance, None
will be returned.
IncludingDowncast
parameter makes the function return None
if ProjectionElem
is
Downcast
and IncludingDowncast
is true
fn describe_name(&self, place: PlaceRef<'tcx>) -> Option<Symbol>
Sourcefn append_local_to_string(
&self,
local: Local,
buf: &mut String,
) -> Result<(), ()>
fn append_local_to_string( &self, local: Local, buf: &mut String, ) -> Result<(), ()>
Appends end-user visible description of the local
place to buf
. If local
doesn’t have
a name, or its name was generated by the compiler, then Err
is returned
Sourcefn describe_field(
&self,
place: PlaceRef<'tcx>,
field: FieldIdx,
including_tuple_field: IncludingTupleField,
) -> Option<String>
fn describe_field( &self, place: PlaceRef<'tcx>, field: FieldIdx, including_tuple_field: IncludingTupleField, ) -> Option<String>
End-user visible description of the field
nth field of base
Sourcefn describe_field_from_ty(
&self,
ty: Ty<'_>,
field: FieldIdx,
variant_index: Option<VariantIdx>,
including_tuple_field: IncludingTupleField,
) -> Option<String>
fn describe_field_from_ty( &self, ty: Ty<'_>, field: FieldIdx, variant_index: Option<VariantIdx>, including_tuple_field: IncludingTupleField, ) -> Option<String>
End-user visible description of the field_index
nth field of ty
pub(crate) fn borrowed_content_source( &self, deref_base: PlaceRef<'tcx>, ) -> BorrowedContentSource<'tcx>
Sourcepub(crate) fn get_name_for_ty(&self, ty: Ty<'tcx>, counter: usize) -> String
pub(crate) fn get_name_for_ty(&self, ty: Ty<'tcx>, counter: usize) -> String
Return the name of the provided Ty
(that must be a reference) with a synthesized lifetime
name where required.
Sourcepub(crate) fn get_region_name_for_ty(
&self,
ty: Ty<'tcx>,
counter: usize,
) -> String
pub(crate) fn get_region_name_for_ty( &self, ty: Ty<'tcx>, counter: usize, ) -> String
Returns the name of the provided Ty
(that must be a reference)’s region with a
synthesized lifetime name where required.
Source§impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx>
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx>
Sourcepub(crate) fn move_spans(
&self,
moved_place: PlaceRef<'tcx>,
location: Location,
) -> UseSpans<'tcx>
pub(crate) fn move_spans( &self, moved_place: PlaceRef<'tcx>, location: Location, ) -> UseSpans<'tcx>
Finds the spans associated to a move or copy of move_place at location.
Sourcepub(crate) fn borrow_spans(
&self,
use_span: Span,
location: Location,
) -> UseSpans<'tcx>
pub(crate) fn borrow_spans( &self, use_span: Span, location: Location, ) -> UseSpans<'tcx>
Finds the span of arguments of a closure (within maybe_closure_span
)
and its usage of the local assigned at location
.
This is done by searching in statements succeeding location
and originating from maybe_closure_span
.
Sourcefn closure_span(
&self,
def_id: LocalDefId,
target_place: PlaceRef<'tcx>,
places: &IndexSlice<FieldIdx, Operand<'tcx>>,
) -> Option<(Span, ClosureKind, Span, Span)>
fn closure_span( &self, def_id: LocalDefId, target_place: PlaceRef<'tcx>, places: &IndexSlice<FieldIdx, Operand<'tcx>>, ) -> Option<(Span, ClosureKind, Span, Span)>
Finds the spans of a captured place within a closure or coroutine. The first span is the location of the use resulting in the capture kind of the capture The second span is the location the use resulting in the captured path of the capture
Sourcepub(crate) fn retrieve_borrow_spans(
&self,
borrow: &BorrowData<'_>,
) -> UseSpans<'tcx>
pub(crate) fn retrieve_borrow_spans( &self, borrow: &BorrowData<'_>, ) -> UseSpans<'tcx>
Helper to retrieve span(s) of given borrow from the current MIR representation
fn explain_captures( &mut self, err: &mut Diag<'infcx>, span: Span, move_span: Span, move_spans: UseSpans<'tcx>, moved_place: Place<'tcx>, msg_opt: CapturedMessageOpt, )
Source§impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx>
impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx>
Source§impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx>
impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx>
Sourcepub(crate) fn gather_used_muts(
&mut self,
temporary_used_locals: FxIndexSet<Local>,
never_initialized_mut_locals: FxIndexSet<Local>,
)
pub(crate) fn gather_used_muts( &mut self, temporary_used_locals: FxIndexSet<Local>, never_initialized_mut_locals: FxIndexSet<Local>, )
Walks the MIR adding to the set of used_mut
locals that will be ignored for the purposes
of the unused_mut
lint.
temporary_used_locals
should contain locals that were found to be temporary, mutable and
used from borrow checking. This function looks for assignments into these locals from
user-declared locals and adds those user-defined locals to the used_mut
set. This can
occur due to a rare case involving upvars in closures.
never_initialized_mut_locals
should contain the set of user-declared mutable locals
(not arguments) that have not already been marked as being used.
This function then looks for assignments from statements or the terminator into the locals
from this set and removes them from the set. This leaves only those locals that have not
been assigned to - this set is used as a proxy for locals that were not initialized due to
unreachable code. These locals are then considered “used” to silence the lint for them.
See #55344 for context.
Source§impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx>
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx>
pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>)
pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>)
pub(crate) fn buffer_move_error( &mut self, move_out_indices: Vec<MoveOutIndex>, place_and_err: (PlaceRef<'tcx>, Diag<'infcx>), ) -> bool
pub(crate) fn get_buffered_mut_error( &mut self, span: Span, ) -> Option<(Diag<'infcx>, usize)>
pub(crate) fn buffer_mut_error( &mut self, span: Span, diag: Diag<'infcx>, count: usize, )
pub(crate) fn emit_errors(&mut self) -> Option<ErrorGuaranteed>
pub(crate) fn has_buffered_diags(&self) -> bool
pub(crate) fn has_move_error( &self, move_out_indices: &[MoveOutIndex], ) -> Option<&(PlaceRef<'tcx>, Diag<'infcx>)>
Source§impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx>
impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx>
pub(crate) fn body(&self) -> &'a Body<'tcx>
Sourcepub(crate) fn access_place(
&mut self,
location: Location,
place_span: (Place<'tcx>, Span),
kind: (AccessDepth, ReadOrWrite),
is_local_mutation_allowed: LocalMutationIsAllowed,
state: &BorrowckDomain<'a, 'tcx>,
)
pub(crate) fn access_place( &mut self, location: Location, place_span: (Place<'tcx>, Span), kind: (AccessDepth, ReadOrWrite), is_local_mutation_allowed: LocalMutationIsAllowed, state: &BorrowckDomain<'a, 'tcx>, )
Checks an access to the given place to see if it is allowed. Examines the set of borrows that are in scope, as well as which paths have been initialized, to ensure that (a) the place is initialized and (b) it is not borrowed in some way that would prevent this access.
Returns true
if an error is reported.
pub(crate) fn check_access_for_conflict( &mut self, location: Location, place_span: (Place<'tcx>, Span), sd: AccessDepth, rw: ReadOrWrite, state: &BorrowckDomain<'a, 'tcx>, ) -> bool
pub(crate) fn mutate_place( &mut self, location: Location, place_span: (Place<'tcx>, Span), kind: AccessDepth, state: &BorrowckDomain<'a, 'tcx>, )
pub(crate) fn consume_rvalue( &mut self, location: Location, (rvalue, span): (&'a Rvalue<'tcx>, Span), state: &BorrowckDomain<'a, 'tcx>, )
pub(crate) fn propagate_closure_used_mut_upvar( &mut self, operand: &Operand<'tcx>, )
pub(crate) fn consume_operand( &mut self, location: Location, (operand, span): (&'a Operand<'tcx>, Span), state: &BorrowckDomain<'a, 'tcx>, )
Sourcepub(crate) fn check_for_invalidation_at_exit(
&mut self,
location: Location,
borrow: &BorrowData<'tcx>,
span: Span,
)
pub(crate) fn check_for_invalidation_at_exit( &mut self, location: Location, borrow: &BorrowData<'tcx>, span: Span, )
Checks whether a borrow of this place is invalidated when the function exits
Sourcepub(crate) fn check_for_local_borrow(
&mut self,
borrow: &BorrowData<'tcx>,
yield_span: Span,
)
pub(crate) fn check_for_local_borrow( &mut self, borrow: &BorrowData<'tcx>, yield_span: Span, )
Reports an error if this is a borrow of local data. This is called for all Yield expressions on movable coroutines
pub(crate) fn check_activations( &mut self, location: Location, span: Span, state: &BorrowckDomain<'a, 'tcx>, )
pub(crate) fn check_movable_place( &mut self, location: Location, place: Place<'tcx>, )
pub(crate) fn check_if_full_path_is_moved( &mut self, location: Location, desired_action: InitializationRequiringAction, place_span: (PlaceRef<'tcx>, Span), state: &BorrowckDomain<'a, 'tcx>, )
Sourcepub(crate) fn check_if_subslice_element_is_moved(
&mut self,
location: Location,
desired_action: InitializationRequiringAction,
place_span: (PlaceRef<'tcx>, Span),
maybe_uninits: &ChunkedBitSet<MovePathIndex>,
from: u64,
to: u64,
)
pub(crate) fn check_if_subslice_element_is_moved( &mut self, location: Location, desired_action: InitializationRequiringAction, place_span: (PlaceRef<'tcx>, Span), maybe_uninits: &ChunkedBitSet<MovePathIndex>, from: u64, to: u64, )
Subslices correspond to multiple move paths, so we iterate through the elements of the base array. For each element we check
- Does this element overlap with our slice.
- Is any part of it uninitialized.
pub(crate) fn check_if_path_or_subpath_is_moved( &mut self, location: Location, desired_action: InitializationRequiringAction, place_span: (PlaceRef<'tcx>, Span), state: &BorrowckDomain<'a, 'tcx>, )
Sourcepub(crate) fn move_path_closest_to(
&mut self,
place: PlaceRef<'tcx>,
) -> (PlaceRef<'tcx>, MovePathIndex)
pub(crate) fn move_path_closest_to( &mut self, place: PlaceRef<'tcx>, ) -> (PlaceRef<'tcx>, MovePathIndex)
Currently MoveData does not store entries for all places in the input MIR. For example it will currently filter out places that are Copy; thus we do not track places of shared reference type. This routine will walk up a place along its prefixes, searching for a foundational place that is tracked in the MoveData.
An Err result includes a tag indicated why the search failed. Currently this can only occur if the place is built off of a static variable, as we do not track those in the MoveData.
pub(crate) fn move_path_for_place( &mut self, place: PlaceRef<'tcx>, ) -> Option<MovePathIndex>
pub(crate) fn check_if_assigned_path_is_moved( &mut self, location: Location, (place, span): (Place<'tcx>, Span), state: &BorrowckDomain<'a, 'tcx>, )
Sourcepub(crate) fn check_access_permissions(
&mut self,
(place, span): (Place<'tcx>, Span),
kind: ReadOrWrite,
is_local_mutation_allowed: LocalMutationIsAllowed,
state: &BorrowckDomain<'a, 'tcx>,
location: Location,
) -> bool
pub(crate) fn check_access_permissions( &mut self, (place, span): (Place<'tcx>, Span), kind: ReadOrWrite, is_local_mutation_allowed: LocalMutationIsAllowed, state: &BorrowckDomain<'a, 'tcx>, location: Location, ) -> bool
Checks the permissions for the given place and read or write kind
Returns true
if an error is reported.
pub(crate) fn is_local_ever_initialized( &self, local: Local, state: &BorrowckDomain<'a, 'tcx>, ) -> Option<InitIndex>
Sourcepub(crate) fn add_used_mut(
&mut self,
root_place: RootPlace<'tcx>,
state: &BorrowckDomain<'a, 'tcx>,
)
pub(crate) fn add_used_mut( &mut self, root_place: RootPlace<'tcx>, state: &BorrowckDomain<'a, 'tcx>, )
Adds the place into the used mutable variables set
Sourcepub(crate) fn is_mutable(
&self,
place: PlaceRef<'tcx>,
is_local_mutation_allowed: LocalMutationIsAllowed,
) -> Result<RootPlace<'tcx>, PlaceRef<'tcx>>
pub(crate) fn is_mutable( &self, place: PlaceRef<'tcx>, is_local_mutation_allowed: LocalMutationIsAllowed, ) -> Result<RootPlace<'tcx>, PlaceRef<'tcx>>
Whether this value can be written or borrowed mutably. Returns the root place if the place passed in is a projection.
Sourcepub(crate) fn is_upvar_field_projection(
&self,
place_ref: PlaceRef<'tcx>,
) -> Option<FieldIdx>
pub(crate) fn is_upvar_field_projection( &self, place_ref: PlaceRef<'tcx>, ) -> Option<FieldIdx>
If place
is a field projection, and the field is being projected from a closure type,
then returns the index of the field being projected. Note that this closure will always
be self
in the current MIR, because that is the only time we directly access the fields
of a closure type.
pub(crate) fn dominators(&self) -> &Dominators<BasicBlock>
Trait Implementations§
Source§impl<'a, 'tcx, R> ResultsVisitor<'a, 'tcx, R> for MirBorrowckCtxt<'a, '_, 'tcx>
impl<'a, 'tcx, R> ResultsVisitor<'a, 'tcx, R> for MirBorrowckCtxt<'a, '_, 'tcx>
type Domain = BorrowckDomain<'a, 'tcx>
Source§fn visit_statement_before_primary_effect(
&mut self,
_results: &mut R,
state: &BorrowckDomain<'a, 'tcx>,
stmt: &'a Statement<'tcx>,
location: Location,
)
fn visit_statement_before_primary_effect( &mut self, _results: &mut R, state: &BorrowckDomain<'a, 'tcx>, stmt: &'a Statement<'tcx>, location: Location, )
before_statement_effect
of the given statement applied to state
but not
its statement_effect
.Source§fn visit_terminator_before_primary_effect(
&mut self,
_results: &mut R,
state: &BorrowckDomain<'a, 'tcx>,
term: &'a Terminator<'tcx>,
loc: Location,
)
fn visit_terminator_before_primary_effect( &mut self, _results: &mut R, state: &BorrowckDomain<'a, 'tcx>, term: &'a Terminator<'tcx>, loc: Location, )
before_terminator_effect
of the given terminator applied to state
but not
its terminator_effect
.Source§fn visit_terminator_after_primary_effect(
&mut self,
_results: &mut R,
state: &BorrowckDomain<'a, 'tcx>,
term: &'a Terminator<'tcx>,
loc: Location,
)
fn visit_terminator_after_primary_effect( &mut self, _results: &mut R, state: &BorrowckDomain<'a, 'tcx>, term: &'a Terminator<'tcx>, loc: Location, )
before_terminator_effect
and the terminator_effect
of the given
terminator applied to state
. Read morefn visit_block_start(&mut self, _state: &Self::Domain)
Source§fn visit_statement_after_primary_effect(
&mut self,
_results: &mut R,
_state: &Self::Domain,
_statement: &'mir Statement<'tcx>,
_location: Location,
)
fn visit_statement_after_primary_effect( &mut self, _results: &mut R, _state: &Self::Domain, _statement: &'mir Statement<'tcx>, _location: Location, )
before_statement_effect
and the statement_effect
of the given
statement applied to state
.fn visit_block_end(&mut self, _state: &Self::Domain)
Auto Trait Implementations§
impl<'a, 'infcx, 'tcx> !DynSend for MirBorrowckCtxt<'a, 'infcx, 'tcx>
impl<'a, 'infcx, 'tcx> !DynSync for MirBorrowckCtxt<'a, 'infcx, 'tcx>
impl<'a, 'infcx, 'tcx> !Freeze for MirBorrowckCtxt<'a, 'infcx, 'tcx>
impl<'a, 'infcx, 'tcx> !RefUnwindSafe for MirBorrowckCtxt<'a, 'infcx, 'tcx>
impl<'a, 'infcx, 'tcx> !Send for MirBorrowckCtxt<'a, 'infcx, 'tcx>
impl<'a, 'infcx, 'tcx> !Sync for MirBorrowckCtxt<'a, 'infcx, 'tcx>
impl<'a, 'infcx, 'tcx> Unpin for MirBorrowckCtxt<'a, 'infcx, 'tcx>
impl<'a, 'infcx, 'tcx> !UnwindSafe for MirBorrowckCtxt<'a, 'infcx, 'tcx>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T, R> CollectAndApply<T, R> for T
impl<T, R> CollectAndApply<T, R> for T
Source§impl<T> Filterable for T
impl<T> Filterable for T
Source§fn filterable(
self,
filter_name: &'static str,
) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>
fn filterable( self, filter_name: &'static str, ) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§impl<P> IntoQueryParam<P> for P
impl<P> IntoQueryParam<P> for P
fn into_query_param(self) -> P
Source§impl<T> MaybeResult<T> for T
impl<T> MaybeResult<T> for T
Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<I, T, U> Upcast<I, U> for Twhere
U: UpcastFrom<I, T>,
impl<I, T, U> Upcast<I, U> for Twhere
U: UpcastFrom<I, T>,
Source§impl<I, T> UpcastFrom<I, T> for T
impl<I, T> UpcastFrom<I, T> for T
fn upcast_from(from: T, _tcx: I) -> T
Source§impl<Tcx, T> Value<Tcx> for Twhere
Tcx: DepContext,
impl<Tcx, T> Value<Tcx> for Twhere
Tcx: DepContext,
default fn from_cycle_error( tcx: Tcx, cycle_error: &CycleError, _guar: ErrorGuaranteed, ) -> T
Source§impl<T> WithSubscriber for T
impl<T> WithSubscriber for T
Source§fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
Source§fn with_current_subscriber(self) -> WithDispatch<Self>
fn with_current_subscriber(self) -> WithDispatch<Self>
impl<'a, T> Captures<'a> for Twhere
T: ?Sized,
impl<T> ErasedDestructor for Twhere
T: 'static,
Layout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...)
attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: 544 bytes