Rollup merge of #64749 - matthewjasper:liveness-opt, r=nikomatsakis
Fix most remaining Polonius test differences This fixes most of the Polonius test differences and also avoids overflow in issue-38591.rs. r? @nikomatsakis
This commit is contained in:
commit
314fbf48cf
|
@ -70,6 +70,10 @@ impl LocalUseMap {
|
|||
appearances: IndexVec::new(),
|
||||
};
|
||||
|
||||
if live_locals.is_empty() {
|
||||
return local_use_map;
|
||||
}
|
||||
|
||||
let mut locals_with_use_data: IndexVec<Local, bool> =
|
||||
IndexVec::from_elem_n(false, body.local_decls.len());
|
||||
live_locals.iter().for_each(|&local| locals_with_use_data[local] = true);
|
||||
|
|
|
@ -36,31 +36,39 @@ pub(super) fn generate<'tcx>(
|
|||
) {
|
||||
debug!("liveness::generate");
|
||||
|
||||
let live_locals: Vec<Local> = if AllFacts::enabled(typeck.tcx()) {
|
||||
// If "dump facts from NLL analysis" was requested perform
|
||||
// the liveness analysis for all `Local`s. This case opens
|
||||
// the possibility of the variables being analyzed in `trace`
|
||||
// to be *any* `Local`, not just the "live" ones, so we can't
|
||||
// make any assumptions past this point as to the characteristics
|
||||
// of the `live_locals`.
|
||||
// FIXME: Review "live" terminology past this point, we should
|
||||
// not be naming the `Local`s as live.
|
||||
body.local_decls.indices().collect()
|
||||
let free_regions = regions_that_outlive_free_regions(
|
||||
typeck.infcx.num_region_vars(),
|
||||
&typeck.borrowck_context.universal_regions,
|
||||
&typeck.borrowck_context.constraints.outlives_constraints,
|
||||
);
|
||||
let live_locals = compute_live_locals(typeck.tcx(), &free_regions, body);
|
||||
let facts_enabled = AllFacts::enabled(typeck.tcx());
|
||||
|
||||
|
||||
let polonius_drop_used = if facts_enabled {
|
||||
let mut drop_used = Vec::new();
|
||||
polonius::populate_access_facts(
|
||||
typeck,
|
||||
body,
|
||||
location_table,
|
||||
move_data,
|
||||
&mut drop_used,
|
||||
);
|
||||
Some(drop_used)
|
||||
} else {
|
||||
let free_regions = {
|
||||
regions_that_outlive_free_regions(
|
||||
typeck.infcx.num_region_vars(),
|
||||
&typeck.borrowck_context.universal_regions,
|
||||
&typeck.borrowck_context.constraints.outlives_constraints,
|
||||
)
|
||||
};
|
||||
compute_live_locals(typeck.tcx(), &free_regions, body)
|
||||
None
|
||||
};
|
||||
|
||||
if !live_locals.is_empty() {
|
||||
trace::trace(typeck, body, elements, flow_inits, move_data, live_locals);
|
||||
|
||||
polonius::populate_access_facts(typeck, body, location_table, move_data);
|
||||
if !live_locals.is_empty() || facts_enabled {
|
||||
trace::trace(
|
||||
typeck,
|
||||
body,
|
||||
elements,
|
||||
flow_inits,
|
||||
move_data,
|
||||
live_locals,
|
||||
polonius_drop_used,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ struct UseFactsExtractor<'me> {
|
|||
var_defined: &'me mut VarPointRelations,
|
||||
var_used: &'me mut VarPointRelations,
|
||||
location_table: &'me LocationTable,
|
||||
var_drop_used: &'me mut VarPointRelations,
|
||||
var_drop_used: &'me mut Vec<(Local, Location)>,
|
||||
move_data: &'me MoveData<'me>,
|
||||
path_accessed_at: &'me mut MovePathPointRelations,
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ impl UseFactsExtractor<'_> {
|
|||
|
||||
fn insert_drop_use(&mut self, local: Local, location: Location) {
|
||||
debug!("LivenessFactsExtractor::insert_drop_use()");
|
||||
self.var_drop_used.push((local, self.location_to_index(location)));
|
||||
self.var_drop_used.push((local, location));
|
||||
}
|
||||
|
||||
fn insert_path_access(&mut self, path: MovePathIndex, location: Location) {
|
||||
|
@ -100,6 +100,7 @@ pub(super) fn populate_access_facts(
|
|||
body: &Body<'tcx>,
|
||||
location_table: &LocationTable,
|
||||
move_data: &MoveData<'_>,
|
||||
drop_used: &mut Vec<(Local, Location)>,
|
||||
) {
|
||||
debug!("populate_var_liveness_facts()");
|
||||
|
||||
|
@ -107,12 +108,16 @@ pub(super) fn populate_access_facts(
|
|||
UseFactsExtractor {
|
||||
var_defined: &mut facts.var_defined,
|
||||
var_used: &mut facts.var_used,
|
||||
var_drop_used: &mut facts.var_drop_used,
|
||||
var_drop_used: drop_used,
|
||||
path_accessed_at: &mut facts.path_accessed_at,
|
||||
location_table,
|
||||
move_data,
|
||||
}
|
||||
.visit_body(body);
|
||||
|
||||
facts.var_drop_used.extend(drop_used.iter().map(|&(local, location)| {
|
||||
(local, location_table.mid_index(location))
|
||||
}));
|
||||
}
|
||||
|
||||
for (local, local_decl) in body.local_decls.iter_enumerated() {
|
||||
|
|
|
@ -13,7 +13,7 @@ use rustc::traits::query::type_op::outlives::DropckOutlives;
|
|||
use rustc::traits::query::type_op::TypeOp;
|
||||
use rustc::ty::{Ty, TypeFoldable};
|
||||
use rustc_index::bit_set::HybridBitSet;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use std::rc::Rc;
|
||||
|
||||
/// This is the heart of the liveness computation. For each variable X
|
||||
|
@ -37,6 +37,7 @@ pub(super) fn trace(
|
|||
flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'tcx>>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
live_locals: Vec<Local>,
|
||||
polonius_drop_used: Option<Vec<(Local, Location)>>,
|
||||
) {
|
||||
debug!("trace()");
|
||||
|
||||
|
@ -52,7 +53,13 @@ pub(super) fn trace(
|
|||
drop_data: FxHashMap::default(),
|
||||
};
|
||||
|
||||
LivenessResults::new(cx).compute_for_all_locals(live_locals);
|
||||
let mut results = LivenessResults::new(cx);
|
||||
|
||||
if let Some(drop_used) = polonius_drop_used {
|
||||
results.add_extra_drop_facts(drop_used, live_locals.iter().copied().collect())
|
||||
}
|
||||
|
||||
results.compute_for_all_locals(live_locals);
|
||||
}
|
||||
|
||||
/// Contextual state for the type-liveness generator.
|
||||
|
@ -145,6 +152,32 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Add extra drop facts needed for Polonius.
|
||||
///
|
||||
/// Add facts for all locals with free regions, since regions may outlive
|
||||
/// the function body only at certain nodes in the CFG.
|
||||
fn add_extra_drop_facts(
|
||||
&mut self,
|
||||
drop_used: Vec<(Local, Location)>,
|
||||
live_locals: FxHashSet<Local>,
|
||||
) {
|
||||
let locations = HybridBitSet::new_empty(self.cx.elements.num_points());
|
||||
|
||||
for (local, location) in drop_used {
|
||||
if !live_locals.contains(&local) {
|
||||
let local_ty = self.cx.body.local_decls[local].ty;
|
||||
if local_ty.has_free_regions() {
|
||||
self.cx.add_drop_live_facts_for(
|
||||
local,
|
||||
local_ty,
|
||||
&[location],
|
||||
&locations,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear the value of fields that are "per local variable".
|
||||
fn reset_local_state(&mut self) {
|
||||
self.defs.clear();
|
||||
|
|
|
@ -276,7 +276,17 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
|||
|
||||
fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
|
||||
self.super_constant(constant, location);
|
||||
self.sanitize_type(constant, constant.literal.ty);
|
||||
let ty = self.sanitize_type(constant, constant.literal.ty);
|
||||
|
||||
self.cx.infcx.tcx.for_each_free_region(&ty, |live_region| {
|
||||
let live_region_vid =
|
||||
self.cx.borrowck_context.universal_regions.to_region_vid(live_region);
|
||||
self.cx
|
||||
.borrowck_context
|
||||
.constraints
|
||||
.liveness_constraints
|
||||
.add_element(live_region_vid, location);
|
||||
});
|
||||
|
||||
if let Some(annotation_index) = constant.user_ty {
|
||||
if let Err(terr) = self.cx.relate_type_and_user_type(
|
||||
|
@ -528,25 +538,37 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
|||
|
||||
let parent_body = mem::replace(&mut self.body, promoted_body);
|
||||
|
||||
// Use new sets of constraints and closure bounds so that we can
|
||||
// modify their locations.
|
||||
let all_facts = &mut None;
|
||||
let mut constraints = Default::default();
|
||||
let mut closure_bounds = Default::default();
|
||||
let mut liveness_constraints = LivenessValues::new(
|
||||
Rc::new(RegionValueElements::new(promoted_body)),
|
||||
);
|
||||
// Don't try to add borrow_region facts for the promoted MIR
|
||||
mem::swap(self.cx.borrowck_context.all_facts, all_facts);
|
||||
|
||||
// Use a new sets of constraints and closure bounds so that we can
|
||||
// modify their locations.
|
||||
mem::swap(
|
||||
&mut self.cx.borrowck_context.constraints.outlives_constraints,
|
||||
&mut constraints
|
||||
);
|
||||
mem::swap(
|
||||
&mut self.cx.borrowck_context.constraints.closure_bounds_mapping,
|
||||
&mut closure_bounds
|
||||
);
|
||||
let mut swap_constraints = |this: &mut Self| {
|
||||
mem::swap(this.cx.borrowck_context.all_facts, all_facts);
|
||||
mem::swap(
|
||||
&mut this.cx.borrowck_context.constraints.outlives_constraints,
|
||||
&mut constraints
|
||||
);
|
||||
mem::swap(
|
||||
&mut this.cx.borrowck_context.constraints.closure_bounds_mapping,
|
||||
&mut closure_bounds
|
||||
);
|
||||
mem::swap(
|
||||
&mut this.cx.borrowck_context.constraints.liveness_constraints,
|
||||
&mut liveness_constraints
|
||||
);
|
||||
};
|
||||
|
||||
swap_constraints(self);
|
||||
|
||||
self.visit_body(promoted_body);
|
||||
|
||||
|
||||
if !self.errors_reported {
|
||||
// if verifier failed, don't do further checks to avoid ICEs
|
||||
self.cx.typeck_mir(promoted_body);
|
||||
|
@ -554,23 +576,15 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
|||
|
||||
self.body = parent_body;
|
||||
// Merge the outlives constraints back in, at the given location.
|
||||
mem::swap(self.cx.borrowck_context.all_facts, all_facts);
|
||||
mem::swap(
|
||||
&mut self.cx.borrowck_context.constraints.outlives_constraints,
|
||||
&mut constraints
|
||||
);
|
||||
mem::swap(
|
||||
&mut self.cx.borrowck_context.constraints.closure_bounds_mapping,
|
||||
&mut closure_bounds
|
||||
);
|
||||
swap_constraints(self);
|
||||
|
||||
let locations = location.to_locations();
|
||||
for constraint in constraints.outlives().iter() {
|
||||
let mut constraint = *constraint;
|
||||
constraint.locations = locations;
|
||||
if let ConstraintCategory::Return
|
||||
| ConstraintCategory::UseAsConst
|
||||
| ConstraintCategory::UseAsStatic = constraint.category
|
||||
| ConstraintCategory::UseAsConst
|
||||
| ConstraintCategory::UseAsStatic = constraint.category
|
||||
{
|
||||
// "Returning" from a promoted is an assigment to a
|
||||
// temporary from the user's point of view.
|
||||
|
@ -578,6 +592,10 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
|||
}
|
||||
self.cx.borrowck_context.constraints.outlives_constraints.push(constraint)
|
||||
}
|
||||
for live_region in liveness_constraints.rows() {
|
||||
self.cx.borrowck_context.constraints.liveness_constraints
|
||||
.add_element(live_region, location);
|
||||
}
|
||||
|
||||
if !closure_bounds.is_empty() {
|
||||
let combined_bounds_mapping = closure_bounds
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
error[E0597]: `x` does not live long enough
|
||||
--> $DIR/async-borrowck-escaping-closure-error.rs:5:24
|
||||
|
|
||||
LL | Box::new((async || x)())
|
||||
| -------------------^----
|
||||
| | | |
|
||||
| | | borrowed value does not live long enough
|
||||
| | value captured here
|
||||
| borrow later used here
|
||||
LL |
|
||||
LL | }
|
||||
| - `x` dropped here while still borrowed
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
|
@ -1,16 +0,0 @@
|
|||
error[E0597]: `books` does not live long enough
|
||||
--> $DIR/borrowck-escaping-closure-error-2.rs:11:17
|
||||
|
|
||||
LL | Box::new(|| books.push(4))
|
||||
| ------------^^^^^---------
|
||||
| | | |
|
||||
| | | borrowed value does not live long enough
|
||||
| | value captured here
|
||||
| borrow later used here
|
||||
LL |
|
||||
LL | }
|
||||
| - `books` dropped here while still borrowed
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
|
@ -1,59 +0,0 @@
|
|||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/promote-ref-mut-in-let-issue-46557.rs:5:21
|
||||
|
|
||||
LL | let ref mut x = 1234543;
|
||||
| ^^^^^^^ creates a temporary which is freed while still in use
|
||||
LL | x
|
||||
| - borrow later used here
|
||||
LL | }
|
||||
| - temporary value is freed at the end of this statement
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/promote-ref-mut-in-let-issue-46557.rs:10:25
|
||||
|
|
||||
LL | let (ref mut x, ) = (1234543, );
|
||||
| ^^^^^^^^^^^ creates a temporary which is freed while still in use
|
||||
LL | x
|
||||
| - borrow later used here
|
||||
LL | }
|
||||
| - temporary value is freed at the end of this statement
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
|
||||
error[E0515]: cannot return value referencing temporary value
|
||||
--> $DIR/promote-ref-mut-in-let-issue-46557.rs:15:5
|
||||
|
|
||||
LL | match 1234543 {
|
||||
| ^ ------- temporary value created here
|
||||
| _____|
|
||||
| |
|
||||
LL | | ref mut x => x
|
||||
LL | | }
|
||||
| |_____^ returns a value referencing data owned by the current function
|
||||
|
||||
error[E0515]: cannot return value referencing temporary value
|
||||
--> $DIR/promote-ref-mut-in-let-issue-46557.rs:21:5
|
||||
|
|
||||
LL | match (123443,) {
|
||||
| ^ --------- temporary value created here
|
||||
| _____|
|
||||
| |
|
||||
LL | | (ref mut x,) => x,
|
||||
LL | | }
|
||||
| |_____^ returns a value referencing data owned by the current function
|
||||
|
||||
error[E0515]: cannot return reference to temporary value
|
||||
--> $DIR/promote-ref-mut-in-let-issue-46557.rs:27:5
|
||||
|
|
||||
LL | &mut 1234543
|
||||
| ^^^^^-------
|
||||
| | |
|
||||
| | temporary value created here
|
||||
| returns a reference to data owned by the current function
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0515, E0716.
|
||||
For more information about an error, try `rustc --explain E0515`.
|
|
@ -1,16 +0,0 @@
|
|||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/return-local-binding-from-desugaring.rs:26:18
|
||||
|
|
||||
LL | for ref x in xs {
|
||||
| ^^ creates a temporary which is freed while still in use
|
||||
...
|
||||
LL | }
|
||||
| - temporary value is freed at the end of this statement
|
||||
LL | result
|
||||
| ------ borrow later used here
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0716`.
|
|
@ -1,148 +0,0 @@
|
|||
error[E0503]: cannot use `self.cx` because it was mutably borrowed
|
||||
--> $DIR/two-phase-surprise-no-conflict.rs:21:23
|
||||
|
|
||||
LL | let _mut_borrow = &mut *self;
|
||||
| ---------- borrow of `*self` occurs here
|
||||
LL | let _access = self.cx;
|
||||
| ^^^^^^^ use of borrowed `*self`
|
||||
LL |
|
||||
LL | _mut_borrow;
|
||||
| ----------- borrow later used here
|
||||
|
||||
error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable
|
||||
--> $DIR/two-phase-surprise-no-conflict.rs:57:17
|
||||
|
|
||||
LL | self.hash_expr(&self.cx_mut.body(eid).value);
|
||||
| ^^^^^---------^^-----------^^^^^^^^^^^^^^^^^
|
||||
| | | |
|
||||
| | | immutable borrow occurs here
|
||||
| | immutable borrow later used by call
|
||||
| mutable borrow occurs here
|
||||
|
||||
error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
|
||||
--> $DIR/two-phase-surprise-no-conflict.rs:119:51
|
||||
|
|
||||
LL | reg.register_static(Box::new(TrivialPass::new(&mut reg.sess_mut)));
|
||||
| --- --------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
|
||||
| | |
|
||||
| | first borrow later used by call
|
||||
| first mutable borrow occurs here
|
||||
|
||||
error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
|
||||
--> $DIR/two-phase-surprise-no-conflict.rs:122:54
|
||||
|
|
||||
LL | reg.register_bound(Box::new(TrivialPass::new_mut(&mut reg.sess_mut)));
|
||||
| --- -------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
|
||||
| | |
|
||||
| | first borrow later used by call
|
||||
| first mutable borrow occurs here
|
||||
|
||||
error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
|
||||
--> $DIR/two-phase-surprise-no-conflict.rs:125:53
|
||||
|
|
||||
LL | reg.register_univ(Box::new(TrivialPass::new_mut(&mut reg.sess_mut)));
|
||||
| --- ------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
|
||||
| | |
|
||||
| | first borrow later used by call
|
||||
| first mutable borrow occurs here
|
||||
|
||||
error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
|
||||
--> $DIR/two-phase-surprise-no-conflict.rs:128:44
|
||||
|
|
||||
LL | reg.register_ref(&TrivialPass::new_mut(&mut reg.sess_mut));
|
||||
| --- ------------ ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
|
||||
| | |
|
||||
| | first borrow later used by call
|
||||
| first mutable borrow occurs here
|
||||
|
||||
error[E0502]: cannot borrow `*reg` as mutable because it is also borrowed as immutable
|
||||
--> $DIR/two-phase-surprise-no-conflict.rs:138:5
|
||||
|
|
||||
LL | reg.register_bound(Box::new(CapturePass::new(®.sess_mut)));
|
||||
| ^^^^--------------^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------^^^
|
||||
| | | |
|
||||
| | | immutable borrow occurs here
|
||||
| | immutable borrow later used by call
|
||||
| mutable borrow occurs here
|
||||
|
||||
error[E0502]: cannot borrow `*reg` as mutable because it is also borrowed as immutable
|
||||
--> $DIR/two-phase-surprise-no-conflict.rs:141:5
|
||||
|
|
||||
LL | reg.register_univ(Box::new(CapturePass::new(®.sess_mut)));
|
||||
| ^^^^-------------^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------^^^
|
||||
| | | |
|
||||
| | | immutable borrow occurs here
|
||||
| | immutable borrow later used by call
|
||||
| mutable borrow occurs here
|
||||
|
||||
error[E0502]: cannot borrow `*reg` as mutable because it is also borrowed as immutable
|
||||
--> $DIR/two-phase-surprise-no-conflict.rs:144:5
|
||||
|
|
||||
LL | reg.register_ref(&CapturePass::new(®.sess_mut));
|
||||
| ^^^^------------^^^^^^^^^^^^^^^^^^^-------------^^
|
||||
| | | |
|
||||
| | | immutable borrow occurs here
|
||||
| | immutable borrow later used by call
|
||||
| mutable borrow occurs here
|
||||
|
||||
error[E0499]: cannot borrow `*reg` as mutable more than once at a time
|
||||
--> $DIR/two-phase-surprise-no-conflict.rs:154:5
|
||||
|
|
||||
LL | reg.register_bound(Box::new(CapturePass::new_mut(&mut reg.sess_mut)));
|
||||
| ^^^^--------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------^^^
|
||||
| | | |
|
||||
| | | first mutable borrow occurs here
|
||||
| | first borrow later used by call
|
||||
| second mutable borrow occurs here
|
||||
|
||||
error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
|
||||
--> $DIR/two-phase-surprise-no-conflict.rs:154:54
|
||||
|
|
||||
LL | reg.register_bound(Box::new(CapturePass::new_mut(&mut reg.sess_mut)));
|
||||
| --- -------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
|
||||
| | |
|
||||
| | first borrow later used by call
|
||||
| first mutable borrow occurs here
|
||||
|
||||
error[E0499]: cannot borrow `*reg` as mutable more than once at a time
|
||||
--> $DIR/two-phase-surprise-no-conflict.rs:158:5
|
||||
|
|
||||
LL | reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut)));
|
||||
| ^^^^-------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------^^^
|
||||
| | | |
|
||||
| | | first mutable borrow occurs here
|
||||
| | first borrow later used by call
|
||||
| second mutable borrow occurs here
|
||||
|
||||
error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
|
||||
--> $DIR/two-phase-surprise-no-conflict.rs:158:53
|
||||
|
|
||||
LL | reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut)));
|
||||
| --- ------------- ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
|
||||
| | |
|
||||
| | first borrow later used by call
|
||||
| first mutable borrow occurs here
|
||||
|
||||
error[E0499]: cannot borrow `*reg` as mutable more than once at a time
|
||||
--> $DIR/two-phase-surprise-no-conflict.rs:162:5
|
||||
|
|
||||
LL | reg.register_ref(&CapturePass::new_mut(&mut reg.sess_mut));
|
||||
| ^^^^------------^^^^^^^^^^^^^^^^^^^^^^^-----------------^^
|
||||
| | | |
|
||||
| | | first mutable borrow occurs here
|
||||
| | first borrow later used by call
|
||||
| second mutable borrow occurs here
|
||||
|
||||
error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
|
||||
--> $DIR/two-phase-surprise-no-conflict.rs:162:44
|
||||
|
|
||||
LL | reg.register_ref(&CapturePass::new_mut(&mut reg.sess_mut));
|
||||
| --- ------------ ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
|
||||
| | |
|
||||
| | first borrow later used by call
|
||||
| first mutable borrow occurs here
|
||||
|
||||
error: aborting due to 15 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0499, E0502, E0503.
|
||||
For more information about an error, try `rustc --explain E0499`.
|
|
@ -1,29 +0,0 @@
|
|||
error[E0597]: `y` does not live long enough
|
||||
--> $DIR/promote_const_let.rs:4:9
|
||||
|
|
||||
LL | let x: &'static u32 = {
|
||||
| - borrow later stored here
|
||||
LL | let y = 42;
|
||||
LL | &y
|
||||
| ^^ borrowed value does not live long enough
|
||||
LL | };
|
||||
| - `y` dropped here while still borrowed
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/promote_const_let.rs:6:28
|
||||
|
|
||||
LL | let x: &'static u32 = &{
|
||||
| ____________------------____^
|
||||
| | |
|
||||
| | type annotation requires that borrow lasts for `'static`
|
||||
LL | | let y = 42;
|
||||
LL | | y
|
||||
LL | | };
|
||||
| |_____^ creates a temporary which is freed while still in use
|
||||
LL | }
|
||||
| - temporary value is freed at the end of this statement
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0597, E0716.
|
||||
For more information about an error, try `rustc --explain E0597`.
|
|
@ -1,78 +0,0 @@
|
|||
error[E0597]: `o2` does not live long enough
|
||||
--> $DIR/dropck_trait_cycle_checked.rs:111:13
|
||||
|
|
||||
LL | o1.set0(&o2);
|
||||
| ^^^ borrowed value does not live long enough
|
||||
...
|
||||
LL | }
|
||||
| -
|
||||
| |
|
||||
| `o2` dropped here while still borrowed
|
||||
| borrow might be used here, when `o1` is dropped and runs the destructor for type `std::boxed::Box<dyn Obj<'_>>`
|
||||
|
|
||||
= note: values in a scope are dropped in the opposite order they are defined
|
||||
|
||||
error[E0597]: `o3` does not live long enough
|
||||
--> $DIR/dropck_trait_cycle_checked.rs:112:13
|
||||
|
|
||||
LL | o1.set1(&o3);
|
||||
| ^^^ borrowed value does not live long enough
|
||||
...
|
||||
LL | }
|
||||
| -
|
||||
| |
|
||||
| `o3` dropped here while still borrowed
|
||||
| borrow might be used here, when `o1` is dropped and runs the destructor for type `std::boxed::Box<dyn Obj<'_>>`
|
||||
|
|
||||
= note: values in a scope are dropped in the opposite order they are defined
|
||||
|
||||
error[E0597]: `o2` does not live long enough
|
||||
--> $DIR/dropck_trait_cycle_checked.rs:113:13
|
||||
|
|
||||
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
|
||||
| -------- cast requires that `o2` is borrowed for `'static`
|
||||
...
|
||||
LL | o2.set0(&o2);
|
||||
| ^^^ borrowed value does not live long enough
|
||||
...
|
||||
LL | }
|
||||
| - `o2` dropped here while still borrowed
|
||||
|
||||
error[E0597]: `o3` does not live long enough
|
||||
--> $DIR/dropck_trait_cycle_checked.rs:114:13
|
||||
|
|
||||
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
|
||||
| -------- cast requires that `o3` is borrowed for `'static`
|
||||
...
|
||||
LL | o2.set1(&o3);
|
||||
| ^^^ borrowed value does not live long enough
|
||||
...
|
||||
LL | }
|
||||
| - `o3` dropped here while still borrowed
|
||||
|
||||
error[E0597]: `o1` does not live long enough
|
||||
--> $DIR/dropck_trait_cycle_checked.rs:115:13
|
||||
|
|
||||
LL | o3.set0(&o1);
|
||||
| ^^^ borrowed value does not live long enough
|
||||
LL | o3.set1(&o2);
|
||||
LL | }
|
||||
| -
|
||||
| |
|
||||
| `o1` dropped here while still borrowed
|
||||
| borrow might be used here, when `o1` is dropped and runs the destructor for type `std::boxed::Box<dyn Obj<'_>>`
|
||||
|
||||
error[E0597]: `o2` does not live long enough
|
||||
--> $DIR/dropck_trait_cycle_checked.rs:116:13
|
||||
|
|
||||
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
|
||||
| -------- cast requires that `o2` is borrowed for `'static`
|
||||
...
|
||||
LL | o3.set1(&o2);
|
||||
| ^^^ borrowed value does not live long enough
|
||||
LL | }
|
||||
| - `o2` dropped here while still borrowed
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
|
@ -1,20 +0,0 @@
|
|||
error[E0597]: `b` does not live long enough
|
||||
--> $DIR/ref-escapes-but-not-over-yield.rs:11:13
|
||||
|
|
||||
LL | let mut b = move || {
|
||||
| _________________-
|
||||
LL | | yield();
|
||||
LL | | let b = 5;
|
||||
LL | | a = &b;
|
||||
| | ^^ borrowed value does not live long enough
|
||||
LL | |
|
||||
LL | | };
|
||||
| | -
|
||||
| | |
|
||||
| | `b` dropped here while still borrowed
|
||||
| |_____... and the borrow might be used here, when that temporary is dropped and runs the destructor for generator
|
||||
| a temporary with access to the borrow is created here ...
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
|
@ -0,0 +1,8 @@
|
|||
error: higher-ranked subtype error
|
||||
--> $DIR/due-to-where-clause.rs:2:5
|
||||
|
|
||||
LL | test::<FooS>(&mut 42);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -1,6 +1,3 @@
|
|||
// ignore-compare-mode-nll
|
||||
// ^ This code works in nll mode.
|
||||
|
||||
fn main() {
|
||||
test::<FooS>(&mut 42); //~ ERROR implementation of `Foo` is not general enough
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: implementation of `Foo` is not general enough
|
||||
--> $DIR/due-to-where-clause.rs:5:5
|
||||
--> $DIR/due-to-where-clause.rs:2:5
|
||||
|
|
||||
LL | test::<FooS>(&mut 42);
|
||||
| ^^^^^^^^^^^^ implementation of `Foo` is not general enough
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
|
||||
--> $DIR/get_default.rs:32:17
|
||||
|
|
||||
LL | fn err(map: &mut Map) -> &String {
|
||||
| - let's call the lifetime of this reference `'1`
|
||||
LL | loop {
|
||||
LL | match map.get() {
|
||||
| --- immutable borrow occurs here
|
||||
LL | Some(v) => {
|
||||
|
@ -8,7 +11,7 @@ LL | map.set(String::new()); // Both AST and MIR error here
|
|||
| ^^^ mutable borrow occurs here
|
||||
LL |
|
||||
LL | return v;
|
||||
| - immutable borrow later used here
|
||||
| - returning this value requires that `*map` is borrowed for `'1`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
error[E0506]: cannot assign to `data.0` because it is borrowed
|
||||
--> $DIR/loan_ends_mid_block_pair.rs:12:5
|
||||
|
|
||||
LL | let c = &mut data.0;
|
||||
| ----------- borrow of `data.0` occurs here
|
||||
LL | capitalize(c);
|
||||
LL | data.0 = 'e';
|
||||
| ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here
|
||||
...
|
||||
LL | capitalize(c);
|
||||
| - borrow later used here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0506`.
|
|
@ -17,12 +17,14 @@ LL | let w = y;
|
|||
error[E0505]: cannot move out of `x` because it is borrowed
|
||||
--> $DIR/polonius-smoke-test.rs:19:13
|
||||
|
|
||||
LL | pub fn use_while_mut_fr(x: &mut i32) -> &mut i32 {
|
||||
| - let's call the lifetime of this reference `'1`
|
||||
LL | let y = &mut *x;
|
||||
| ------- borrow of `*x` occurs here
|
||||
LL | let z = x;
|
||||
| ^ move out of `x` occurs here
|
||||
LL | y
|
||||
| - borrow later used here
|
||||
| - returning this value requires that `*x` is borrowed for `'1`
|
||||
|
||||
error[E0505]: cannot move out of `s` because it is borrowed
|
||||
--> $DIR/polonius-smoke-test.rs:43:5
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
// Test that promoted that have larger mir bodies than their containing function
|
||||
// don't cause an ICE.
|
||||
|
||||
// check-pass
|
||||
|
||||
fn main() {
|
||||
&["0", "1", "2", "3", "4", "5", "6", "7"];
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/return-ref-mut-issue-46557.rs:4:21
|
||||
|
|
||||
LL | let ref mut x = 1234543;
|
||||
| ^^^^^^^ creates a temporary which is freed while still in use
|
||||
LL | x
|
||||
| - borrow later used here
|
||||
LL | }
|
||||
| - temporary value is freed at the end of this statement
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0716`.
|
|
@ -1,60 +0,0 @@
|
|||
error[E0597]: `factorial` does not live long enough
|
||||
--> $DIR/unboxed-closures-failed-recursive-fn-1.rs:15:17
|
||||
|
|
||||
LL | let f = |x: u32| -> u32 {
|
||||
| --------------- value captured here
|
||||
LL | let g = factorial.as_ref().unwrap();
|
||||
| ^^^^^^^^^ borrowed value does not live long enough
|
||||
...
|
||||
LL | }
|
||||
| -
|
||||
| |
|
||||
| `factorial` dropped here while still borrowed
|
||||
| borrow might be used here, when `factorial` is dropped and runs the destructor for type `std::option::Option<std::boxed::Box<dyn std::ops::Fn(u32) -> u32>>`
|
||||
|
||||
error[E0506]: cannot assign to `factorial` because it is borrowed
|
||||
--> $DIR/unboxed-closures-failed-recursive-fn-1.rs:20:5
|
||||
|
|
||||
LL | let f = |x: u32| -> u32 {
|
||||
| --------------- borrow of `factorial` occurs here
|
||||
LL | let g = factorial.as_ref().unwrap();
|
||||
| --------- borrow occurs due to use in closure
|
||||
...
|
||||
LL | factorial = Some(Box::new(f));
|
||||
| ^^^^^^^^^
|
||||
| |
|
||||
| assignment to borrowed `factorial` occurs here
|
||||
| borrow later used here
|
||||
|
||||
error[E0597]: `factorial` does not live long enough
|
||||
--> $DIR/unboxed-closures-failed-recursive-fn-1.rs:28:17
|
||||
|
|
||||
LL | let f = |x: u32| -> u32 {
|
||||
| --------------- value captured here
|
||||
LL | let g = factorial.as_ref().unwrap();
|
||||
| ^^^^^^^^^ borrowed value does not live long enough
|
||||
...
|
||||
LL | }
|
||||
| -
|
||||
| |
|
||||
| `factorial` dropped here while still borrowed
|
||||
| borrow might be used here, when `factorial` is dropped and runs the destructor for type `std::option::Option<std::boxed::Box<dyn std::ops::Fn(u32) -> u32>>`
|
||||
|
||||
error[E0506]: cannot assign to `factorial` because it is borrowed
|
||||
--> $DIR/unboxed-closures-failed-recursive-fn-1.rs:33:5
|
||||
|
|
||||
LL | let f = |x: u32| -> u32 {
|
||||
| --------------- borrow of `factorial` occurs here
|
||||
LL | let g = factorial.as_ref().unwrap();
|
||||
| --------- borrow occurs due to use in closure
|
||||
...
|
||||
LL | factorial = Some(Box::new(f));
|
||||
| ^^^^^^^^^
|
||||
| |
|
||||
| assignment to borrowed `factorial` occurs here
|
||||
| borrow later used here
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0506, E0597.
|
||||
For more information about an error, try `rustc --explain E0506`.
|
Loading…
Reference in New Issue