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:
Mazdak Farrokhzad 2019-10-04 07:24:33 +02:00 committed by GitHub
commit 314fbf48cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 142 additions and 528 deletions

View File

@ -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);

View File

@ -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,
);
}
}

View File

@ -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() {

View File

@ -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();

View File

@ -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

View File

@ -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`.

View File

@ -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`.

View File

@ -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`.

View File

@ -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`.

View File

@ -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(&reg.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(&reg.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(&reg.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`.

View File

@ -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`.

View File

@ -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`.

View File

@ -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`.

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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`.

View File

@ -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

View File

@ -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"];
}

View File

@ -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`.

View File

@ -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`.