Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

only compute liveness for variables whose types include regions #52115

Merged
merged 16 commits into from
Jul 21, 2018

Conversation

Dylan-DPC-zz
Copy link

Closes #52034

r? @nikomatsakis

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 6, 2018
@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-3.9 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.

[00:04:22] travis_fold:start:tidy
travis_time:start:tidy
tidy check
[00:04:23] tidy error: /checkout/src/librustc_mir/borrow_check/nll/type_check/liveness.rs:79: line longer than 100 chars
[00:04:23] tidy error: /checkout/src/librustc_mir/util/liveness.rs:345: line longer than 100 chars
[00:04:24] some tidy checks failed
[00:04:24] 
[00:04:24] 
[00:04:24] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/tidy" "/checkout/src" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "--no-vendor" "--quiet"
[00:04:24] 
[00:04:24] 
[00:04:24] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test src/tools/tidy
[00:04:24] Build completed unsuccessfully in 0:00:47
[00:04:24] Build completed unsuccessfully in 0:00:47
[00:04:24] make: *** [tidy] Error 1
[00:04:24] Makefile:79: recipe for target 'tidy' failed

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:0c73c773
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
---
travis_time:end:34725414:start=1530898061462538636,finish=1530898061469979993,duration=7441357
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:14902ac4
$ head -30 ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
head: cannot open ‘./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers’ for reading: No such file or directory
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:16102546
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@@ -201,9 +202,9 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
(regioncx, polonius_output, closure_region_requirements)
}

fn dump_mir_results<'a, 'gcx, 'tcx>(
fn dump_mir_results<'a, 'gcx, 'tcx, V: Idx>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably not parameterize this function...

infcx: &InferCtxt<'a, 'gcx, 'tcx>,
liveness: &LivenessResults,
liveness: &LivenessResults<V>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...but instead here have LivenessResults<Local> (at least to start -- later we'll change this I think)

@@ -392,7 +393,7 @@ impl ToRegionVid for RegionVid {
}
}

fn live_variable_set(regular: &LocalSet, drops: &LocalSet) -> String {
fn live_variable_set<V: Idx>(regular: &LocalSet<V>, drops: &LocalSet<V>) -> String {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, for this first refactoring, we would have LocalSet<Local> here -- the idea is that the liveness computation is generic over the index, but we as the users of it still want to compute the liveness of every MIR local variable to start

cx: &mut TypeChecker<'_, 'gcx, 'tcx>,
mir: &Mir<'tcx>,
liveness: &LivenessResults,
liveness: &LivenessResults<V>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, this would be LivenessResults<Local> to start

@@ -54,16 +55,17 @@ pub(super) fn generate<'gcx, 'tcx>(
}
}

struct TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx>
struct TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx, V>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, no need for V here, as we are consuming the results


/// This gives the result of the liveness analysis at the boundary of
/// basic blocks. You can use `simulate_block` to obtain the
/// intra-block results.
pub struct LivenessResult {
pub struct LivenessResult<V: Idx> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably add some kind of trait like LiveVariableMap, which would look kind of like so:

trait LiveVariableMap {
    type LiveVar;

    fn from_local(&self, local: Local) -> Option<Self::LiveVar>;
    fn from_live_var(&self, local: Self::LiveVar) -> Local;
}

We would also make an "identity map" type that we use for now:

struct IdentityMap;

impl LiveVariableMap for IdentityMap {
    type LiveVar = Local;

    fn from_local(&self, local: Local) -> Option<Local> {
        Some(local)
    }

    fn from_live_var(&self, local: Self::LiveVar) -> Local {
        local
    }
}

struct DefsUses {
defs: LocalSet,
uses: LocalSet,
struct DefsUses<V: Idx>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This struct is going to need to take the &impl LiveVariableMap and store it in a field (map, say)

impl LivenessResults {
pub fn compute<'tcx>(mir: &Mir<'tcx>) -> LivenessResults {
impl<V: Idx> LivenessResults<V> {
pub fn compute<'tcx>(mir: &Mir<'tcx>) -> LivenessResults<V> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would also take a &impl LiveVariableMap<LiveVar = V>

fn clear(&mut self) {
self.uses.clear();
self.defs.clear();
}

fn apply(&self, bits: &mut LocalSet) -> bool {
fn apply(&self, bits: &mut LocalSet<V>) -> bool {
bits.subtract(&self.defs) | bits.union(&self.uses)
}

This comment was marked as resolved.

@@ -388,12 +393,12 @@ fn block<'tcx>(mode: LivenessMode, b: &BasicBlockData<'tcx>, locals: usize) -> D
visitor.defs_uses
}

pub fn dump_mir<'a, 'tcx>(
pub fn dump_mir<'a, 'tcx, V: Idx>(

This comment was marked as resolved.

This comment was marked as resolved.

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-3.9 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.

[00:04:48] travis_fold:start:tidy
travis_time:start:tidy
tidy check
[00:04:48] tidy error: /checkout/src/librustc_mir/util/liveness.rs:117: line longer than 100 chars
[00:04:48] tidy error: /checkout/src/librustc_mir/util/liveness.rs:373: line longer than 100 chars
[00:04:49] some tidy checks failed
[00:04:49] 
[00:04:49] 
[00:04:49] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/tidy" "/checkout/src" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "--no-vendor" "--quiet"
[00:04:49] 
[00:04:49] 
[00:04:49] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test src/tools/tidy
[00:04:49] Build completed unsuccessfully in 0:00:49
[00:04:49] Build completed unsuccessfully in 0:00:49
[00:04:49] Makefile:79: recipe for target 'tidy' failed
[00:04:49] make: *** [tidy] Error 1

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:06e9b812
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
---
travis_time:end:07980fd0:start=1530996817842801910,finish=1530996817848524653,duration=5722743
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:2c48f04c
$ head -30 ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
head: cannot open ‘./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers’ for reading: No such file or directory
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:1a65f5ad
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-3.9 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.

[00:03:48] travis_fold:start:tidy
travis_time:start:tidy
tidy check
[00:03:48] tidy error: /checkout/src/librustc_mir/borrow_check/nll/type_check/liveness.rs:79: line longer than 100 chars
[00:03:48] tidy error: /checkout/src/librustc_mir/util/liveness.rs:117: line longer than 100 chars
[00:03:48] tidy error: /checkout/src/librustc_mir/util/liveness.rs:141: line longer than 100 chars
[00:03:48] tidy error: /checkout/src/librustc_mir/util/liveness.rs:372: line longer than 100 chars
[00:03:50] some tidy checks failed
[00:03:50] 
[00:03:50] 
[00:03:50] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/tidy" "/checkout/src" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "--no-vendor" "--quiet"
[00:03:50] 
[00:03:50] 
[00:03:50] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test src/tools/tidy
[00:03:50] Build completed unsuccessfully in 0:00:50
[00:03:50] Build completed unsuccessfully in 0:00:50
[00:03:50] Makefile:79: recipe for target 'tidy' failed
[00:03:50] make: *** [tidy] Error 1

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:0610a5f8
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
---
travis_time:end:1d84fdba:start=1531057878711266136,finish=1531057878718215191,duration=6949055
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:1518100f
$ head -30 ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
head: cannot open ‘./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers’ for reading: No such file or directory
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:09756d00
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

Copy link
Contributor

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok I have to run but here is a first round of feedback

@@ -33,10 +34,10 @@ use super::TypeChecker;
///
/// NB. This computation requires normalization; therefore, it must be
/// performed before
pub(super) fn generate<'gcx, 'tcx>(
pub(super) fn generate<'gcx, 'tcx, V: LiveVariableMap>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this file should be generic over V...

use rustc::mir::visit::MirVisitable;
use std::path::{Path, PathBuf};
use std::fs;
use rustc::ty::TyCtxt;
use std::io::{self, Write};
use transform::MirSource;

pub type LocalSet = IdxSetBuf<Local>;
pub type LocalSet<V: LiveVariableMap> = IdxSetBuf<V::LiveVar>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this giving a warning? If so, change V::LiveVar to <V as LiveVariableMap>::LiveVar and remove the bound (for better or worse, this compiles)

@@ -80,18 +103,18 @@ pub struct LivenessMode {
}

/// A combination of liveness results, used in NLL.
pub struct LivenessResults {
pub struct LivenessResults<V: LiveVariableMap> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I intended this to be just <V>...

}

impl LivenessResults {
pub fn compute<'tcx>(mir: &Mir<'tcx>) -> LivenessResults {
impl<V: LiveVariableMap> LivenessResults<V> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...and here we would have impl<V, M: LiveVariableMap<LiveVar = V>...

impl LivenessResults {
pub fn compute<'tcx>(mir: &Mir<'tcx>) -> LivenessResults {
impl<V: LiveVariableMap> LivenessResults<V> {
pub fn compute<'tcx>(mir: &Mir<'tcx>, map: &dyn LiveVariableMap<LiveVar = V>) -> LivenessResults<V::LiveVar> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and here

pub fn compute<'tcx>(mir: &Mir<'tcx>, map: &M) -> LivenessResults<V> {

@@ -115,7 +138,7 @@ impl LivenessResults {
/// Compute which local variables are live within the given function
/// `mir`. The liveness mode `mode` determines what sorts of uses are
/// considered to make a variable live (e.g., do drops count?).
pub fn liveness_of_locals<'tcx>(mir: &Mir<'tcx>, mode: LivenessMode) -> LivenessResult {
pub fn liveness_of_locals<'tcx, V: LiveVariableMap>(mir: &Mir<'tcx>, mode: LivenessMode) -> LivenessResult<V::LiveVar> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can just be V then, I think

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-5.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.

[00:03:40] travis_fold:start:tidy
travis_time:start:tidy
tidy check
[00:03:40] tidy error: /checkout/src/librustc_mir/borrow_check/nll/type_check/liveness.rs:79: line longer than 100 chars
[00:03:40] tidy error: /checkout/src/librustc_mir/util/liveness.rs:372: line longer than 100 chars
[00:03:41] some tidy checks failed
[00:03:41] 
[00:03:41] 
[00:03:41] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/tidy" "/checkout/src" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "--no-vendor" "--quiet"
[00:03:41] 
[00:03:41] 
[00:03:41] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test src/tools/tidy
[00:03:41] Build completed unsuccessfully in 0:00:45
[00:03:41] Build completed unsuccessfully in 0:00:45
[00:03:41] Makefile:79: recipe for target 'tidy' failed
[00:03:41] make: *** [tidy] Error 1

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:0ca7cfcd
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
---
travis_time:end:0bb57731:start=1531480643727623078,finish=1531480643734350747,duration=6727669
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:0ca8d216
$ head -30 ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
head: cannot open ‘./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers’ for reading: No such file or directory
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:193a7a90
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@bors
Copy link
Contributor

bors commented Jul 13, 2018

☔ The latest upstream changes (presumably #51987) made this pull request unmergeable. Please resolve the merge conflicts.

impl<V: LiveVariableMap> LivenessResults<V> {
pub fn compute<'tcx>(mir: &Mir<'tcx>, map: &dyn LiveVariableMap<LiveVar = V>) -> LivenessResults<V::LiveVar> {
impl<V, M: LiveVariableMap<LiveVar = V>> LivenessResults<V> {
pub fn compute<'tcx>(mir: &Mir<'tcx>, map: &M) -> LivenessResults<V> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably make this map: &impl LiveVariableMap<LiveVar = V> and remove the explicit M parameter altogether

@@ -138,7 +138,7 @@ impl<V: LiveVariableMap> LivenessResults<V> {
/// Compute which local variables are live within the given function
/// `mir`. The liveness mode `mode` determines what sorts of uses are
/// considered to make a variable live (e.g., do drops count?).
pub fn liveness_of_locals<'tcx, V: LiveVariableMap>(mir: &Mir<'tcx>, mode: LivenessMode) -> LivenessResult<V::LiveVar> {
pub fn liveness_of_locals<'tcx, V>(mir: &Mir<'tcx>, mode: LivenessMode) -> LivenessResult<V> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will presumably need the map to be given to it as well

@@ -138,7 +138,7 @@ impl<V: LiveVariableMap> LivenessResults<V> {
/// Compute which local variables are live within the given function
/// `mir`. The liveness mode `mode` determines what sorts of uses are
/// considered to make a variable live (e.g., do drops count?).
pub fn liveness_of_locals<'tcx, V: LiveVariableMap>(mir: &Mir<'tcx>, mode: LivenessMode) -> LivenessResult<V::LiveVar> {
pub fn liveness_of_locals<'tcx, V>(mir: &Mir<'tcx>, mode: LivenessMode) -> LivenessResult<V> {
let locals = mir.local_decls.len();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this variable represents the total number of variables we are computing liveness for. We may need to extend the LiveVariableMap trait to include a num_variables(mir: &Mir<'tcx>) method -- for the identity case, it would return mir.local_decls.len().

@@ -53,7 +53,7 @@ pub mod traversal;
pub mod visit;

/// Types for locals
type LocalDecls<'tcx> = IndexVec<Local, LocalDecl<'tcx>>;
type LocalDecls<'tcx> = IndexVec<LocalWithRegion, LocalDecl<'tcx>>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should remain Local! This is the full set of local declarations -- LocalWithRegion is meant to be a subset of the full set of locals.

flow_inits: &'gen mut FlowAtLocation<MaybeInitializedPlaces<'flow, 'gcx, 'tcx>>,
move_data: &'gen MoveData<'tcx>,
drop_data: FxHashMap<Ty<'tcx>, DropData<'tcx>>,
map: &'gen IdentityMap<'gen, 'tcx>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I suspect this is the problem -- this should not be IdentityMap, right? But rather LocalWithRegionMap or whatever that type is called

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-5.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.

[00:03:46] travis_fold:start:tidy
travis_time:start:tidy
tidy check
[00:03:46] tidy error: /checkout/src/librustc_mir/borrow_check/nll/mod.rs:411: line longer than 100 chars
[00:03:46] tidy error: /checkout/src/librustc_mir/util/liveness.rs:573: line longer than 100 chars
[00:03:46] tidy error: /checkout/src/librustc/mir/mod.rs: missing trailing newline
[00:03:47] some tidy checks failed
[00:03:47] 
[00:03:47] 
[00:03:47] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/tidy" "/checkout/src" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "--no-vendor" "--quiet"
[00:03:47] 
[00:03:47] 
[00:03:47] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test src/tools/tidy
[00:03:47] Build completed unsuccessfully in 0:00:51
[00:03:47] Build completed unsuccessfully in 0:00:51
[00:03:47] make: *** [tidy] Error 1
[00:03:47] Makefile:79: recipe for target 'tidy' failed

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:08fbb2a0
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
---
travis_time:end:195387f2:start=1532025024650716936,finish=1532025024657243344,duration=6526408
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:1369bff6
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:1722bca8
travis_time:start:1722bca8
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:2341a488
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

Copy link
Contributor

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Tidy errors though mean that we can't see the travis results.

@@ -2932,3 +2932,5 @@ impl<'tcx> TypeFoldable<'tcx> for Literal<'tcx> {
}
}
}

newtype_index!(LocalWithRegion);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect this to live in the borrow_check somewhere -- probably nll/liveness_map.rs (See below)

@@ -455,3 +544,42 @@ pub fn write_mir_fn<'a, 'tcx>(
writeln!(w, "}}")?;
Ok(())
}

crate struct NllLivenessMap {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect this to live in the nll code -- I'd probably put it in a new module nll/liveness_map.rs along with the LocalWithRegion index declaration.

@nikomatsakis
Copy link
Contributor

Lots of interesting failures: https://travis-ci.org/rust-lang/rust/jobs/405945256#L1943 =)


pub type LocalSet = IdxSetBuf<Local>;
pub type LocalSet<V> = IdxSetBuf<V>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, let's rename this to LiveVarSet<V> -- it'd be nice to distinguish locals (all variables) from live variables (the set of variables we are computing liveness on). Maybe not the best name, but it works (and fits with e.g. LiveVariableMap etc)

@nikomatsakis
Copy link
Contributor

@bors try

@bors
Copy link
Contributor

bors commented Jul 20, 2018

☀️ Test successful - status-travis
State: approved= try=True

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-5.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.

[00:04:04] travis_fold:start:tidy
travis_time:start:tidy
tidy check
[00:04:04] tidy error: /checkout/src/librustc_mir/borrow_check/nll/liveness_map.rs: missing trailing newline
[00:04:04] tidy error: /checkout/src/librustc_mir/util/liveness.rs: too many trailing newlines (3)
[00:04:05] tidy error: /checkout/src/librustc/mir/mod.rs: too many trailing newlines (3)
[00:04:06] some tidy checks failed
[00:04:06] 
[00:04:06] 
[00:04:06] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/tidy" "/checkout/src" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "--no-vendor" "--quiet"
[00:04:06] 
[00:04:06] 
[00:04:06] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test src/tools/tidy
[00:04:06] Build completed unsuccessfully in 0:00:50
[00:04:06] Build completed unsuccessfully in 0:00:50
[00:04:06] make: *** [tidy] Error 1
[00:04:06] Makefile:79: recipe for target 'tidy' failed

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:030c885d
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
---
travis_time:end:31145c8e:start=1532089759629678182,finish=1532089759636637161,duration=6958979
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:02adea38
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:2733c3c0
travis_time:start:2733c3c0
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:00d964da
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-5.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:start:test_mir-opt
Check compiletest suite=mir-opt mode=mir-opt (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
[00:48:55] 
[00:48:55] running 51 tests
[00:49:04] ERROR 2018-07-20T14:03:32Z: compiletest::runtest: None
[00:49:04] ERROR 2018-07-20T14:03:33Z: compiletest::runtest: None
[00:49:05] ERROR 2018-07-20T14:03:33Z: compiletest::runtest: None
[00:49:05] ERROR 2018-07-20T14:03:34Z: compiletest::runtest: None
[00:49:13] .............................FF.F..F...............
[00:49:13] 
[00:49:13] ---- [mir-opt] mir-opt/nll/liveness-call-subtlety.rs stdout ----
[00:49:13] ---- [mir-opt] mir-opt/nll/liveness-call-subtlety.rs stdout ----
[00:49:13] thread '[mir-opt] mir-opt/nll/liveness-call-subtlety.rs' panicked at 'Did not find expected line, error: Mismatch in lines
[00:49:13] Current block: None
[00:49:13] Actual Line: "    | Live variables on exit from bb0: []"
[00:49:13] Expected Line: "           | Live variables on exit from bb0: [_1 (drop)]"
[00:49:13] Test Name: rustc.main.nll.0.mir
[00:49:13] Expected:
[00:49:13] ... (elided)
[00:49:13]    bb0: {
[00:49:13]            | Live variables on entry to bb0[0]: []
[00:49:13]        StorageLive(_1);
[00:49:13]            | Live variables on entry to bb0[1]: []
[00:49:13]        _1 = const <std::boxed::Box<T>>::new(const 22usize) -> [return: bb2, unwind: bb1];
[00:49:13]            | Live variables on exit from bb0: [_1 (drop)]
[00:49:13] Actual:
[00:49:13] | Free Region Mapping
[00:49:13] | Free Region Mapping
[00:49:13] | '_#0r    | Global   | ['_#0r, '_#1r]
[00:49:13] | '_#1r    | Local    | ['_#1r]
[00:49:13] | Inferred Region Values
[00:49:13] | Inferred Region Values
[00:49:13] | '_#0r    | {'_#0r, bb0[0..=1], bb1[0], bb2[0..=1], bb3[0], bb4[0], bb5[0], bb6[0], bb7[0..=2], bb8[0..=1]}
[00:49:13] | '_#1r    | {'_#1r, bb0[0..=1], bb1[0], bb2[0..=1], bb3[0], bb4[0], bb5[0], bb6[0], bb7[0..=2], bb8[0..=1]}
[00:49:13] | Inference Constraints
[00:49:13] | Inference Constraints
[00:49:13] | '_#0r live at {'_#0r, bb0[0..=1], bb1[0], bb2[0..=1], bb3[0], bb4[0], bb5[0], bb6[0], bb7[0..=2], bb8[0..=1]}
[00:49:13] | '_#1r live at {'_#1r, bb0[0..=1], bb1[0], bb2[0..=1], bb3[0], bb4[0], bb5[0], bb6[0], bb7[0..=2], bb8[0..=1]}
[00:49:13] fn main() -> (){
[00:49:13]     let mut _0: ();
[00:49:13]     scope 1 {
[00:49:13]     scope 2 {
[00:49:13]     scope 2 {
[00:49:13]         let mut _1: std::boxed::Box<usize>;
[00:49:13]     }
[00:49:13]     let mut _2: std::boxed::Box<usize>;
[00:49:13]     bb0: {                              
[00:49:13]                                          | Live variables on entry to bb0[0]: []
[00:49:13]         StorageLive(_1);
[00:49:13]                                          | Live variables on entry to bb0[1]: []
[00:49:13]         _1 = const <std::boxed::Box<T>>::new(const 22usize) -> [return: bb2, unwind: bb1];
[00:49:13]     | Live variables on exit from bb0: []
[00:49:13]     bb1: {
[00:49:13]     bb1: {
[00:49:13]                                          | Live variables on entry to bb1[0]: []
[00:49:13]         resume;
[00:49:13]     | Live variables on exit from bb1: []
[00:49:13]     }
[00:49:13]     bb2: {                              
[00:49:13]                                          | Live variables on entry to bb2[0]: []
[00:49:13]         StorageLive(_2);
[00:49:13]                                          | Live variables on entry to bb2[1]: []
[00:49:13]         _2 = const can_panic() -> [return: bb3, unwind: bb4];
[00:49:13]     | Live variables on exit from bb2: []
[00:49:13]     }
[00:49:13]     bb3: {                              
[00:49:13]                                          | Live variables on entry to bb3[0]: []
[00:49:13]         replace(_1 <- move _2) -> [return: bb5, unwind: bb6];
[00:49:13]     | Live variables on exit from bb3: []
[00:49:13]     bb4: {
[00:49:13]     bb4: {
[00:49:13]                                          | Live variables on entry to bb4[0]: []
[00:49:13]         drop(_1) -> bb1;
[00:49:13]     | Live variables on exit from bb4: []
[00:49:13]     }
[00:49:13]     bb5: {                              
[00:49:13]                                          | Live variables on entry to bb5[0]: []
[00:49:13]         drop(_2) -> [return: bb7, unwind: bb4];
[00:49:13]     | Live variables on exit from bb5: []
[00:49:13]     bb6: {
[00:49:13]     bb6: {
[00:49:13]                                          | Live variables on entry to bb6[0]: []
[00:49:13]         drop(_2) -> bb4;
[00:49:13]     | Live variables on exit from bb6: []
[00:49:13]     }
[00:49:13]     bb7: {                              
[00:49:13]                                          | Live variables on entry to bb7[0]: []
[00:49:13]         StorageDead(_2);
[00:49:13]                                          | Live variables on entry to bb7[1]: []
[00:49:13]         _0 = ();
[00:49:13]                                          | Live variables on entry to bb7[2]: []
[00:49:13]         drop(_1) -> [return: bb8, unwind: bb1];
[00:49:13]     | Live variables on exit from bb7: []
[00:49:13]     }
[00:49:13]     bb8: {                              
[00:49:13]                                          | Live variables on entry to bb8[0]: []
[00:49:13]         StorageDead(_1);
[00:49:13]                                          | Live variables on entry to bb8[1]: []
[00:49:13]         return;
[00:49:13]     | Live variables on exit from bb8: []
[00:49:13] }', tools/compiletest/src/runtest.rs:2813:13
[00:49:13] note: Run with `RUST_BACKTRACE=1` for a backtrace.
[00:49:13] 
[00:49:13] ---- [mir-opt] mir-opt/nll/liveness-drop-intra-block.rs stdout ----
[00:49:13] ---- [mir-opt] mir-opt/nll/liveness-drop-intra-block.rs stdout ----
[00:49:13] thread '[mir-opt] mir-opt/nll/liveness-drop-intra-block.rs' panicked at 'Did not find expected line, error: Mismatch in lines
[00:49:13] Current block: None
[00:49:13] Actual Line: "                                         | Live variables on entry to bb3[1]: []"
[00:49:13] Expected Line: "           | Live variables on entry to bb3[1]: [_1]"
[00:49:13] Test Name: rustc.main.nll.0.mir
[00:49:13] Expected:
[00:49:13] ... (elided)
[00:49:13]    bb3: {
[00:49:13]            | Live variables on entry to bb3[0]: []
[00:49:13]        _1 = const 55usize;
[00:49:13]            | Live variables on entry to bb3[1]: [_1]
[00:49:13]        StorageLive(_3);
[00:49:13]            | Live variables on entry to bb3[2]: [_1]
[00:49:13]        StorageLive(_4);
[00:49:13]            | Live variables on entry to bb3[3]: [_1]
[00:49:13]        _4 = _1;
[00:49:13]            | Live variables on entry to bb3[4]: [_4]
[00:49:13]        _3 = const use_x(move _4) -> [return: bb4, unwind: bb1];
[00:49:13]            | Live variables on exit from bb3: [_3]
[00:49:13] Actual:
[00:49:13] | Free Region Mapping
[00:49:13] | Free Region Mapping
[00:49:13] | '_#0r    | Global   | ['_#0r, '_#1r]
[00:49:13] | '_#1r    | Local    | ['_#1r]
[00:49:13] | Inferred Region Values
[00:49:13] | Inferred Region Values
[00:49:13] | '_#0r    | {'_#0r, bb0[0..=2], bb1[0], bb2[0], bb3[0..=4], bb4[0..=1], bb5[0..=3], bb6[0..=2]}
[00:49:13] | '_#1r    | {'_#1r, bb0[0..=2], bb1[0], bb2[0], bb3[0..=4], bb4[0..=1], bb5[0..=3], bb6[0..=2]}
[00:49:13] | Inference Constraints
[00:49:13] | Inference Constraints
[00:49:13] | '_#0r live at {'_#0r, bb0[0..=2], bb1[0], bb2[0], bb3[0..=4], bb4[0..=1], bb5[0..=3], bb6[0..=2]}
[00:49:13] | '_#1r live at {'_#1r, bb0[0..=2], bb1[0], bb2[0], bb3[0..=4], bb4[0..=1], bb5[0..=3], bb6[0..=2]}
[00:49:13] fn main() -> (){
[00:49:13]     let mut _0: ();
[00:49:13]     scope 1 {
[00:49:13]     scope 2 {
[00:49:13]         let mut _1: usize;
[00:49:13]     }
[00:49:13]     }
[00:49:13]     let mut _2: ();
[00:49:13]     let mut _3: bool;
[00:49:13]     let mut _4: usize;
[00:49:13]     let mut _5: !;
[00:49:13]     bb0: {                              
[00:49:13]                                          | Live variables on entry to bb0[0]: []
[00:49:13]         StorageLive(_1);
[00:49:13]                                          | Live variables on entry to bb0[1]: []
[00:49:13]         _1 = const 22usize;
[00:49:13]                                          | Live variables on entry to bb0[2]: []
[00:49:13]         goto -> bb2;
[00:49:13]     | Live variables on exit from bb0: []
[00:49:13]     bb1: {
[00:49:13]     bb1: {
[00:49:13]                                          | Live variables on entry to bb1[0]: []
[00:49:13]         resume;
[00:49:13]     | Live variables on exit from bb1: []
[00:49:13]     }
[00:49:13]     bb2: {                              
[00:49:13]                                          | Live variables on entry to bb2[0]: []
[00:49:13]         falseUnwind -> [real: bb3, cleanup: bb1];
[00:49:13]     | Live variables on exit from bb2: []
[00:49:13]     }
[00:49:13]     bb3: {                              
[00:49:13]                                          | Live variables on entry to bb3[0]: []
[00:49:13]         _1 = const 55usize;
[00:49:13]                                          | Live variables on entry to bb3[1]: []
[00:49:13]         StorageLive(_3);
[00:49:13]                                          | Live variables on entry to bb3[2]: []
[00:49:13]         StorageLive(_4);
[00:49:13]                                          | Live variables on entry to bb3[3]: []
[00:49:13]         _4 = _1;
[00:49:13]                                          | Live variables on entry to bb3[4]: []
[00:49:13]         _3 = const use_x(move _4) -> [return: bb4, unwind: bb1];
[00:49:13]     | Live variables on exit from bb3: []
[00:49:13]     }
[00:49:13]     bb4: {                              
[00:49:13]                                          | Live variables on entry to bb4[0]: []
[00:49:13]         StorageDead(_4);
[00:49:13]                                          | Live variables on entry to bb4[1]: []
[00:49:13]         switchInt(move _3) -> [false: bb6, otherwise: bb5];
[00:49:13]     | Live variables on exit from bb4: []
[00:49:13]     }
[00:49:13]     bb5: {                              
[00:49:13]                                          | Live variables on entry to bb5[0]: []
[00:49:13]         _0 = ();
[00:49:13]                                          | Live variables on entry to bb5[1]: []
[00:49:13]         StorageDead(_3);
[00:49:13]                                          | Live variables on entry to bb5[2]: []
[00:49:13]         StorageDead(_1);
[00:49:13]                                          | Live variables on entry to bb5[3]: []
[00:49:13]         return;
[00:49:13]     | Live variables on exit from bb5: []
[00:49:13]     }
[00:49:13]     bb6: {                              
[00:49:13]                                          | Live variables on entry to bb6[0]: []
[00:49:13]         _2 = ();
[00:49:13]                                          | Live variables on entry to bb6[1]: []
[00:49:13]         StorageDead(_3);
[00:49:13]                                          | Live variables on entry to bb6[2]: []
[00:49:13]         goto -> bb2;
[00:49:13]     | Live variables on exit from bb6: []
[00:49:13] }', tools/compiletest/src/runtest.rs:2813:13
[00:49:13] 
[00:49:13] ---- [mir-opt] mir-opt/nll/liveness-interblock.rs stdout ----
[00:49:13] ---- [mir-opt] mir-opt/nll/liveness-interblock.rs stdout ----
[00:49:13] thread '[mir-opt] mir-opt/nll/liveness-interblock.rs' panicked at 'Did not find expected line, error: Mismatch in lines
[00:49:13] Current block: None
[00:49:13] Actual Line: "                                         | Live variables on entry to bb3[0]: []"
[00:49:13] Expected Line: "            | Live variables on entry to bb3[0]: [_1]"
[00:49:13] Test Name: rustc.main.nll.0.mir
[00:49:13] Expected:
[00:49:13] ... (elided)
[00:49:13]     bb3: {
[00:49:13]             | Live variables on entry to bb3[0]: [_1]
[00:49:13]         StorageLive(_4);
[00:49:13]             | Live variables on entry to bb3[1]: [_1]
[00:49:13]         _4 = _1;
[00:49:13]             | Live variables on entry to bb3[2]: [_4]
[00:49:13]         _3 = const make_live(move _4) -> [return: bb5, unwind: bb1];
[00:49:13]             | Live variables on exit from bb3: []
[00:49:13] Actual:
[00:49:13] | Free Region Mapping
[00:49:13] | Free Region Mapping
[00:49:13] | '_#0r    | Global   | ['_#0r, '_#1r]
[00:49:13] | '_#1r    | Local    | ['_#1r]
[00:49:13] | Inferred Region Values
[00:49:13] | Inferred Region Values
[00:49:13] | '_#0r    | {'_#0r, bb0[0..=3], bb1[0], bb2[0], bb3[0..=2], bb4[0], bb5[0..=2], bb6[0..=1], bb7[0..=2]}
[00:49:13] | '_#1r    | {'_#1r, bb0[0..=3], bb1[0], bb2[0], bb3[0..=2], bb4[0], bb5[0..=2], bb6[0..=1], bb7[0..=2]}
[00:49:13] | Inference Constraints
[00:49:13] | Inference Constraints
[00:49:13] | '_#0r live at {'_#0r, bb0[0..=3], bb1[0], bb2[0], bb3[0..=2], bb4[0], bb5[0..=2], bb6[0..=1], bb7[0..=2]}
[00:49:13] | '_#1r live at {'_#1r, bb0[0..=3], bb1[0], bb2[0], bb3[0..=2], bb4[0], bb5[0..=2], bb6[0..=1], bb7[0..=2]}
[00:49:13] fn main() -> (){
[00:49:13]     let mut _0: ();
[00:49:13]     scope 1 {
[00:49:13]     scope 2 {
[00:49:13]         let _1: usize;
[00:49:13]     }
[00:49:13]     }
[00:49:13]     let mut _2: bool;
[00:49:13]     let mut _3: ();
[00:49:13]     let mut _4: usize;
[00:49:13]     let mut _5: ();
[00:49:13]     bb0: {                              
[00:49:13]                                          | Live variables on entry to bb0[0]: []
[00:49:13]         StorageLive(_1);
[00:49:13]                                          | Live variables on entry to bb0[1]: []
[00:49:13]         _1 = const 5usize;
[00:49:13]                                          | Live variables on entry to bb0[2]: []
[00:49:13]         StorageLive(_2);
[00:49:13]                                          | Live variables on entry to bb0[3]: []
[00:49:13]         _2 = const cond() -> [return: bb2, unwind: bb1];
[00:49:13]     | Live variables on exit from bb0: []
[00:49:13]     bb1: {
[00:49:13]     bb1: {
[00:49:13]                                          | Live variables on entry to bb1[0]: []
[00:49:13]         resume;
[00:49:13]     | Live variables on exit from bb1: []
[00:49:13]     }
[00:49:13]     bb2: {                              
[00:49:13]                                          | Live variables on entry to bb2[0]: []
[00:49:13]         switchInt(move _2) -> [false: bb4, otherwise: bb3];
[00:49:13]     | Live variables on exit from bb2: []
[00:49:13]     }
[00:49:13]     bb3: {                              
[00:49:13]                                          | Live variables on entry to bb3[0]: []
[00:49:13]         StorageLive(_4);
[00:49:13]                                          | Live variables on entry to bb3[1]: []
[00:49:13]         _4 = _1;
[00:49:13]                                          | Live variables on entry to bb3[2]: []
[00:49:13]         _3 = const make_live(move _4) -> [return: bb5, unwind: bb1];
[00:49:13]     | Live variables on exit from bb3: []
[00:49:13]     }
[00:49:13]     bb4: {                              
[00:49:13]                                          | Live variables on entry to bb4[0]: []
[00:49:13]         _5 = const make_dead() -> [return: bb6, unwind: bb1];
[00:49:13]     | Live variables on exit from bb4: []
[00:49:13]     }
[00:49:13]     bb5: {                              
[00:49:13]                                          | Live variables on entry to bb5[0]: []
[00:49:13]         StorageDead(_4);
[00:49:13]                                          | Live variables on entry to bb5[1]: []
[00:49:13]         _0 = ();
[00:49:13]                                          | Live variables on entry to bb5[2]: []
[00:49:13]         goto -> bb7;
[00:49:13]     | Live variables on exit from bb5: []
[00:49:13]     }
[00:49:13]     bb6: {                              
[00:49:13]                                          | Live variables on entry to bb6[0]: []
[00:49:13]         _0 = ();
[00:49:13]                                          | Live variables on entry to bb6[1]: []
[00:49:13]         goto -> bb7;
[00:49:13]     | Live variables on exit from bb6: []
[00:49:13]     }
[00:49:13]     bb7: {                              
[00:49:13]                                          | Live variables on entry to bb7[0]: []
[00:49:13]         StorageDead(_2);
[00:49:13]                                          | Live variables on entry to bb7[1]: []
[00:49:13]         StorageDead(_1);
[00:49:13]                                          | Live variables on entry to bb7[2]: []
[00:49:13]         return;
[00:49:13]     | Live variables on exit from bb7: []
[00:49:13] }', tools/compiletest/src/runtest.rs:2813:13
[00:49:13] 
[00:49:13] ---- [mir-opt] mir-opt/nll/region-liveness-basic.rs stdout ----
[00:49:13] ---- [mir-opt] mir-opt/nll/region-liveness-basic.rs stdout ----
[00:49:13] thread '[mir-opt] mir-opt/nll/region-liveness-basic.rs' panicked at 'Did not find expected line, error: Mismatch in lines
[00:49:13] Current block: None
[00:49:13] Actual Line: "                                         | Live variables on entry to bb2[0]: []"
[00:49:13] Expected Line: "           | Live variables on entry to bb2[0]: [_1, _3]"
[00:49:13] Test Name: rustc.main.nll.0.mir
[00:49:13] Expected:
[00:49:13] ... (elided)
[00:49:13]    bb2: {
[00:49:13]            | Live variables on entry to bb2[0]: [_1, _3]
[00:49:13]        _2 = &'_#2r _1[_3];
[00:49:13]            | Live variables on entry to bb2[1]: [_2]
[00:49:13]        switchInt(const true) -> [false: bb4, otherwise: bb3];
[00:49:13]            | Live variables on exit from bb2: [_2]
[00:49:13] Actual:
[00:49:13] | Free Region Mapping
[00:49:13] | Free Region Mapping
[00:49:13] | '_#0r    | Global   | ['_#0r, '_#1r]
[00:49:13] | '_#1r    | Local    | ['_#1r]
[00:49:13] | Inferred Region Values
[00:49:13] | Inferred Region Values
[00:49:13] | '_#0r    | {'_#0r, bb0[0..=7], bb1[0], bb2[0..=1], bb3[0..=2], bb4[0], bb5[0..=2], bb6[0..=1], bb7[0..=3]}
[00:49:13] | '_#1r    | {'_#1r, bb0[0..=7], bb1[0], bb2[0..=1], bb3[0..=2], bb4[0], bb5[0..=2], bb6[0..=1], bb7[0..=3]}
[00:49:13] | '_#2r    | {bb2[0..=1], bb3[0..=1]}
[00:49:13] | '_#3r    | {bb2[1], bb3[0..=1]}
[00:49:13] | Inference Constraints
[00:49:13] | Inference Constraints
[00:49:13] | '_#0r live at {'_#0r, bb0[0..=7], bb1[0], bb2[0..=1], bb3[0..=2], bb4[0], bb5[0..=2], bb6[0..=1], bb7[0..=3]}
[00:49:13] | '_#1r live at {'_#1r, bb0[0..=7], bb1[0], bb2[0..=1], bb3[0..=2], bb4[0], bb5[0..=2], bb6[0..=1], bb7[0..=3]}
[00:49:13] | '_#2r live at {bb2[0]}
[00:49:13] | '_#3r live at {bb2[1], bb3[0..=1]}
[00:49:13] | '_#2r: '_#3r due to Interesting(bb2[0])
[00:49:13] fn main() -> (){
[00:49:13]     let mut _0: ();
[00:49:13]     scope 1 {
[00:49:13]         scope 3 {
[00:49:13]         scope 4 {
[00:49:13]         scope 4 {
[00:49:13]             let _2: &'_#3r usize;
[00:49:13]     }
[00:49:13]     scope 2 {
[00:49:13]     scope 2 {
[00:49:13]         let mut _1: [usize; 3];
[00:49:13]     let mut _3: usize;
[00:49:13]     let mut _4: usize;
[00:49:13]     let mut _4: usize;
[00:49:13]     let mut _5: bool;
[00:49:13]     let mut _6: bool;
[00:49:13]     let mut _7: usize;
[00:49:13]     let mut _8: bool;
[00:49:13]     bb0: {                              
[00:49:13]                                          | Live variables on entry to bb0[0]: []
[00:49:13]         StorageLive(_1);
[00:49:13]                                          | Live variables on entry to bb0[1]: []
[00:49:13]         _1 = [const 1usize, const 2usize, const 3usize];
[00:49:13]                                          | Live variables on entry to bb0[2]: []
[00:49:13]         StorageLive(_2);
[00:49:13]                                          | Live variables on entry to bb0[3]: []
[00:49:13]         StorageLive(_3);
[00:49:13]                                          | Live variables on entry to bb0[4]: []
[00:49:13]         _3 = const 0usize;
[00:49:13]                                          | Live variables on entry to bb0[5]: []
[00:49:13]         _4 = Len(_1);
[00:49:13]                                          | Live variables on entry to bb0[6]: []
[00:49:13]         _5 = Lt(_3, _4);
[00:49:13]                                          | Live variables on entry to bb0[7]: []
[00:49:13]         assert(move _5, "index out of bounds: the len is move _4 but the index is _3") -> [success: bb2, unwind: bb1];
[00:49:13]     | Live variables on exit from bb0: []
[00:49:13]     bb1: {
[00:49:13]     bb1: {
[00:49:13]                                          | Live variables on entry to bb1[0]: []
[00:49:13]         resume;
[00:49:13]     | Live variables on exit from bb1: []
[00:49:13]     }
[00:49:13]     bb2: {                              
[00:49:13]                                          | Live variables on entry to bb2[0]: []
[00:49:13]         _2 = &'_#2r _1[_3];
[00:49:13]                                          | Live variables on entry to bb2[1]: [0]
[00:49:13]         switchInt(const true) -> [false: bb4, otherwise: bb3];
[00:49:13]     | Live variables on exit from bb2: [0]
[00:49:13]     }
[00:49:13]     bb3: {                              
[00:49:13]                                          | Live variables on entry to bb3[0]: [0]
[00:49:13]         StorageLive(_7);
[00:49:13]                                          | Live variables on entry to bb3[1]: [0]
[00:49:13]         _7 = (*_2);
[00:49:13]                                          | Live variables on entry to bb3[2]: []
[00:49:13]         _6 = const use_x(move _7) -> [return: bb5, unwind: bb1];
[00:49:13]     | Live variables on exit from bb3: []
[00:49:13]     }
[00:49:13]     bb4: {                              
[00:49:13]                                          | Live variables on entry to bb4[0]: []
[00:49:13]         _8 = const use_x(const 22usize) -> [return: bb6, unwind: bb1];
[00:49:13]     | Live variables on exit from bb4: []
[00:49:13]     }
[00:49:13]     bb5: {                              
[00:49:13]                                          | Live variables on entry to bb5[0]: []
[00:49:13]         StorageDead(_7);
[00:49:13]                                          | Live variables on entry to bb5[1]: []
[00:49:13] thread 'main' panicked at 'Some tests failed', tools/compiletest/src/main.rs:498:22
[00:49:13]         _0 = ();
[00:49:13]                                          | Live variables on entry to bb5[2]: []
[00:49:13]         goto -> bb7;
[00:49:13]     | Live variables on exit from bb5: []
[00:49:13]     }
[00:49:13]     bb6: {                              
[00:49:13]                                          | Live variables on entry to bb6[0]: []
[00:49:13]         _0 = ();
[00:49:13]                                          | Live variables on entry to bb6[1]: []
[00:49:13]         goto -> bb7;
[00:49:13]     | Live variables on exit from bb6: []
[00:49:13]     }
[00:49:13]     bb7: {                              
[00:49:13]                                          | Live variables on entry to bb7[0]: []
[00:49:13]         nop;
[00:49:13]                                          | Live variables on entry to bb7[1]: []
[00:49:13]         StorageDead(_2);
[00:49:13]                                          | Live variables on entry to bb7[2]: []
[00:49:13]         StorageDead(_1);
[00:49:13]                                          | Live variables on entry to bb7[3]: []
[00:49:13]         return;
[00:49:13]     | Live variables on exit from bb7: []
[00:49:13] }', tools/compiletest/src/runtest.rs:2813:13
[00:49:13] 
[00:49:13] 
[00:49:13] failures:
---
[00:49:13] test result: FAILED. 47 passed; 4 failed; 0 ignored; 0 measured; 0 filtered out
[00:49:13] 
[00:49:13] 
[00:49:13] 
[00:49:13] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/mir-opt" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/mir-opt" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "mir-opt" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-5.0/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Zunstable-options " "--target-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "5.0.0\n" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--llvm-components" "" "--llvm-cxxflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"
[00:49:13] 
[00:49:13] 
[00:49:13] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[00:49:13] Build completed unsuccessfully in 0:09:26
[00:49:13] Build completed unsuccessfully in 0:09:26
[00:49:13] Makefile:58: recipe for target 'check' failed
[00:49:13] make: *** [check] Error 1

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:0e411493
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
---
travis_time:end:033a50fc:start=1532095423428286964,finish=1532095423434273187,duration=5986223
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:0744e790
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:02467641
travis_time:start:02467641
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:26f57118
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@nikomatsakis
Copy link
Contributor

@rust-timer build e5906f3e09c74cf6bd6fe86851a3bacd75fc1a42

@rust-timer
Copy link
Collaborator

Success: Queued e5906f3e09c74cf6bd6fe86851a3bacd75fc1a42 with parent c7cba3d, comparison URL.

@nikomatsakis
Copy link
Contributor

@Dylan-DPC those travis errors are basically a case of "working as expected". TBH, I suspect we could just remove those tests. They were early "bootstrap" tests of the liveness code but I think that the full set of ui/compile-fail tests are more interesting. The tests are failing though because the variables used in them do not have any regions in their types, and hence they no longer appear in the liveness results.

Still, I'd suggest just removing mir-opt/nll/liveness-*rs

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-5.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:start:test_mir-opt
Check compiletest suite=mir-opt mode=mir-opt (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
[00:59:51] 
[00:59:51] running 48 tests
[01:00:01] ERROR 2018-07-21T07:16:32Z: compiletest::runtest: None
01:00:10]                                          | Live variables on entry to bb0[1]: []
[01:00:10]         _1 = [const 1usize, const 2usize, const 3usize];
[01:00:10]                                          | Live variables on entry to bb0[2]: []
[01:00:10]         StorageLive(_2);
[01:00:10]                                          | Live variables on entry to bb0[3]: []
[01:00:10]         StorageLive(_3);
[01:00:10]                                          | Live variables on entry to bb0[4]: []
[01:00:10]         _3 = const 0usize;
[01:00:10]                                          | Live variables on entry to bb0[5]: []
[01:00:10]         _4 = Len(_1);
[01:00:10]                                          | Live variables on entry to bb0[6]: []
[01:00:10]         _5 = Lt(_3, _4);
[01:00:10]                                          | Live variables on entry to bb0[7]: []
[01:00:10]         assert(move _5, "index out of bounds: the len is move _4 but the index is _3") -> [success: bb2, unwind: bb1];
[01:00:10]     | Live variables on exit from bb0: []
[01:00:10]     bb1: {
[01:00:10]     bb1: {
[01:00:10]                                          | Live variables on entry to bb1[0]: []
[01:00:10]         resume;
[01:00:10]     | Live variables on exit from bb1: []
[01:00:10]     }
[01:00:10]     bb2: {                              
[01:00:10]                                          | Live variables on entry to bb2[0]: []
[01:00:10]         _2 = &'_#2r _1[_3];
[01:00:10]                                          | Live variables on entry to bb2[1]: [0]
[01:00:10]         switchInt(const true) -> [false: bb4, otherwise: bb3];
[01:00:10]     | Live variables on exit from bb2: [0]
[01:00:10]     }
[01:00:10]     bb3: {                              
[01:00:10]                                          | Live variables on entry to bb3[0]: [0]
[01:00:10]         StorageLive(_7);
[01:00:10]                                          | Live variables on entry to bb3[1]: [0]
[01:00:10]         _7 = (*_2);
[01:00:10]                                          | Live variables on entry to bb3[2]: []
[01:00:10]         _6 = const use_x(move _7) -> [return: bb5, unwind: bb1];
[01:00:10]     | Live variables on exit from bb3: []
[01:00:10]     }
[01:00:10]     bb4: {                              
[01:00:10]                                          | Live variables on entry to bb4[0]: []
[01:00:10]         _8 = const use_x(const 22usize) -> [return: bb6, unwind: bb1];
[01:00:10]     | Live variables on exit from bb4: []
[01:00:10]     }
[01:00:10]     bb5: {                              
[01:00:10]                                          | Live variables on entry to bb5[0]: []
[01:00:10]         StorageDead(_7);
[01:00:10]                                          | Live variables on entry to bb5[1]: []
[01:00:10]         _0 = ();
[01:00:10]                                          | Live variables on entry to bb5[2]: []
[01:00:10]         goto -> bb7;
[01:00:10]     | Live variables on exit from bb5: []
[01:00:10]     }
[01:00:10]     bb6: {                              
[01:00:10]                                          | Live variables on entry to bb6[0]: []
[01:00:10]         _0 = ();
travis_time:start:158c7974
---
travis_time:end:3ab7c9e0:start=1532157402585879831,finish=1532157402593163890,duration=7284059
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:00a29e00
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:03d56606
travis_time:start:03d56606
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:30d4542a
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@nikomatsakis
Copy link
Contributor

Looks like a win, perf wise =) -80% for tuple-stress :)

Copy link
Contributor

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, left a few nits (comments)

// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a module doc comment here explaining what is going on. Something like this:


For the NLL computation, we need to compute liveness, but only for those local variables whose types contain regions. The others are not of interest to us. This file defines a new index type (LocalWithRegion) that indexes into a list of "variables whose type contain regions". It also defines a map from Local to LocalWithRegion and vice versa -- this map can be given to the liveness code so that it only operates over variables with regions in their types, instead of all variables.

use rustc_data_structures::indexed_vec::Idx;
use rustc::ty::TypeFoldable;

crate struct NllLivenessMap {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add comment:

--

Map between Local and LocalWithRegion indices: this map is supplied to the liveness code so that it will only analyze those variables whose types contain regions.

use rustc::ty::TypeFoldable;

crate struct NllLivenessMap {
pub from_local: IndexVec<Local, Option<LocalWithRegion>>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment:


For each local variable, contains either None (if the type has no regions) or Some(i) with a suitable index.


crate struct NllLivenessMap {
pub from_local: IndexVec<Local, Option<LocalWithRegion>>,
pub to_local: IndexVec<LocalWithRegion, Local>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment:


For each LocalWithRegion, maps back to the original Local index.

}

impl NllLivenessMap {
pub fn compute(mir: &Mir) -> Self {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment:


Iterates over the variables in Mir and assigns each Local whose type contains regions a LocalWithRegion index. Returns a map for converting back and forth.

}
}

newtype_index!(LocalWithRegion);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline at end of file, probably, and a comment:


Index given to each local variable whose type contains a region.

@nikomatsakis
Copy link
Contributor

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-5.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:start:test_mir-opt
Check compiletest suite=mir-opt mode=mir-opt (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
[00:55:33] 
[00:55:33] running 48 tests
[00:55:43] ERROR 2018-07-21T12:50:24Z: compiletest::runtest: None
[00:55:52] thread 'main' panicked at 'Some tests failed', tools/compiletest/src/main.rs:498:22
[00:55:52] ...............................F................
[00:55:52] 
[00:55:52] ---- [mir-opt] mir-opt/nll/region-liveness-basic.rs stdout ----
[00:55:52] ---- [mir-opt] mir-opt/nll/region-liveness-basic.rs stdout ----
[00:55:52] thread '[mir-opt] mir-opt/nll/region-liveness-basic.rs' panicked at 'Did not find expected line, error: Mismatch in lines
[00:55:52] Current block: None
[00:55:52] Actual Line: "                                         | Live variables on entry to bb2[0]: []"
[00:55:52] Expected Line: "           | Live variables on entry to bb2[0]: [_1, _3]"
[00:55:52] Test Name: rustc.main.nll.0.mir
[00:55:52] Expected:
[00:55:52] ... (elided)
[00:55:52]    bb2: {
[00:55:52]            | Live variables on entry to bb2[0]: [_1, _3]
[00:55:52]        _2 = &'_#2r _1[_3];
[00:55:52]            | Live variables on entry to bb2[1]: [_2]
[00:55:52]        switchInt(const true) -> [false: bb4, otherwise: bb3];
[00:55:52]            | Live variables on exit from bb2: [_2]
[00:55:52] Actual:
[00:55:52] | Free Region Mapping
[00travis_fold:start:after_failure.1
travis_time:start:31aa95e8

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@nikomatsakis
Copy link
Contributor

@bors r+ p=1

High-priority NLL fix

@bors
Copy link
Contributor

bors commented Jul 21, 2018

📌 Commit 0770ff0 has been approved by nikomatsakis

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 21, 2018
@kennytm
Copy link
Member

kennytm commented Jul 21, 2018

@bors p=20

@bors
Copy link
Contributor

bors commented Jul 21, 2018

⌛ Testing commit 0770ff0 with merge 874dec2...

bors added a commit that referenced this pull request Jul 21, 2018
…matsakis

only compute liveness for variables whose types include regions

Closes #52034

r? @nikomatsakis
@bors
Copy link
Contributor

bors commented Jul 21, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: nikomatsakis
Pushing 874dec2 to master...

@bors bors merged commit 0770ff0 into rust-lang:master Jul 21, 2018
@Dylan-DPC-zz Dylan-DPC-zz deleted the feature/nll-liveness-regions branch July 22, 2018 06:46
@schomatis schomatis mentioned this pull request Feb 16, 2019
bors added a commit that referenced this pull request Feb 16, 2019
[NLL] Remove `LiveVar`

The `LiveVar` type (and related) made it harder to reason about the code. It seemed as an abstraction that didn't bring any useful concept to the reader (when transitioning from the RFC theory to the actual implementation code).

It achieved a compactness in the vectors storing the def/use/drop information that was related only to the `LocalUseMap`. This PR went in the other direction and favored time over memory (but this decision can be easily reverted to the other side without reintroducing `LiveVar`).

What this PR aims at is to clarify that there's no significant transformation between the MIR `Local` and the `LiveVar` (now refactored as `live_locals: Vec<Local>`): we're just filtering (not mapping) the entire group of `Local`s into a meaningful subset that we should perform the liveness analysis on.

As a side note, there is no guarantee that the liveness analysis is performed only on (what the code calls) "live" variables, if the NLL facts are requested it will be performed on *any* variable so there can't be any assumptions on that regard. (Still, this PR didn't change the general naming convention to reduce the number of changes here and streamline the review process).

**Acceptance criteria:** This PR attempts to do only a minor refactoring and not to change the logic so it can't have any performance impact, particularly, it can't lose any of the significant performance improvement achieved in the great work done in #52115.

r? @nikomatsakis
bors added a commit that referenced this pull request Mar 3, 2019
…sper

[NLL] Remove `LiveVar`

The `LiveVar` type (and related) made it harder to reason about the code. It seemed as an abstraction that didn't bring any useful concept to the reader (when transitioning from the RFC theory to the actual implementation code).

It achieved a compactness in the vectors storing the def/use/drop information that was related only to the `LocalUseMap`. This PR went in the other direction and favored time over memory (but this decision can be easily reverted to the other side without reintroducing `LiveVar`).

What this PR aims at is to clarify that there's no significant transformation between the MIR `Local` and the `LiveVar` (now refactored as `live_locals: Vec<Local>`): we're just filtering (not mapping) the entire group of `Local`s into a meaningful subset that we should perform the liveness analysis on.

As a side note, there is no guarantee that the liveness analysis is performed only on (what the code calls) "live" variables, if the NLL facts are requested it will be performed on *any* variable so there can't be any assumptions on that regard. (Still, this PR didn't change the general naming convention to reduce the number of changes here and streamline the review process).

**Acceptance criteria:** This PR attempts to do only a minor refactoring and not to change the logic so it can't have any performance impact, particularly, it can't lose any of the significant performance improvement achieved in the great work done in #52115.

r? @nikomatsakis
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants