From c68440cad49f6d0cda09f8c7d4989ff63f55a26e Mon Sep 17 00:00:00 2001 From: Songbird0 Date: Sun, 4 Mar 2018 21:59:53 +0100 Subject: [PATCH 01/15] Add a potential cause raising `ParseIntError`. Initially, I wanted to add it directly to the documentation of `str. parse()' method, I finally found that it was more relevant (I hope so?) to directly document the structure in question. I've added a scenario, in which we could all get caught at least once, to make it easier to diagnose the problem when parsing integers. --- src/libcore/num/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 59a67fff48cfe..1b51ebefb6041 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -3845,7 +3845,13 @@ fn from_str_radix(src: &str, radix: u32) -> Result Date: Sun, 4 Mar 2018 22:18:42 +0100 Subject: [PATCH 02/15] Tidy error: add a new line The error was: ``` [00:05:25] tidy error: /checkout/src/libcore/num/mod.rs:3848: trailing whitespace [00:05:25] tidy error: /checkout/src/libcore/num/mod.rs:3851: line longer than 100 chars [00:05:25] tidy error: /checkout/src/libcore/num/mod.rs:3851: trailing whitespace [00:05:26] some tidy checks failed ``` The line was truncated to 92 characters. --- src/libcore/num/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 1b51ebefb6041..00a46dca87601 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -3848,7 +3848,8 @@ fn from_str_radix(src: &str, radix: u32) -> Result Date: Mon, 5 Mar 2018 03:57:33 +0100 Subject: [PATCH 03/15] Modify wording and remove useless whitespaces. --- src/libcore/num/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 00a46dca87601..8b43aeefade5c 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -3845,11 +3845,11 @@ fn from_str_radix(src: &str, radix: u32) -> Result Date: Mon, 5 Mar 2018 14:33:37 +0100 Subject: [PATCH 04/15] Fix spelling error for `whitespaces`. --- src/libcore/num/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 8b43aeefade5c..929d6ef4c200f 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -3848,7 +3848,7 @@ fn from_str_radix(src: &str, radix: u32) -> Result Date: Sun, 18 Feb 2018 00:36:57 +0900 Subject: [PATCH 05/15] Implement FromStr for PathBuf --- src/libstd/path.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index e03a182653e5a..a41f76228a95a 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -87,6 +87,7 @@ use io; use iter::{self, FusedIterator}; use ops::{self, Deref}; use rc::Rc; +use str::FromStr; use sync::Arc; use ffi::{OsStr, OsString}; @@ -1397,6 +1398,32 @@ impl From for PathBuf { } } +/// Error returned from [`PathBuf::from_str`][`from_str`]. +/// +/// Note that parsing a path will never fail. This error is just a placeholder +/// for implementing `FromStr` for `PathBuf`. +/// +/// [`from_str`]: struct.PathBuf.html#method.from_str +#[derive(Debug, Clone, PartialEq, Eq)] +#[stable(feature = "path_from_str", since = "1.26.0")] +pub enum ParsePathError {} + +#[stable(feature = "path_from_str", since = "1.26.0")] +impl fmt::Display for ParsePathError { + fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { + match *self {} + } +} + +#[stable(feature = "path_from_str", since = "1.26.0")] +impl FromStr for PathBuf { + type Err = ParsePathError; + + fn from_str(s: &str) -> Result { + Ok(PathBuf::from(s)) + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl> iter::FromIterator

for PathBuf { fn from_iter>(iter: I) -> PathBuf { From ec761903ec37df5fe6976be1e25079d8f8cbb494 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 5 Mar 2018 19:29:05 -0300 Subject: [PATCH 06/15] Remove nll-dump-cause flag and always track causes --- src/librustc/session/config.rs | 2 -- src/librustc/session/mod.rs | 7 ------- .../borrow_check/nll/region_infer/mod.rs | 5 ----- .../borrow_check/nll/region_infer/values.rs | 9 ++------- src/test/ui/issue-45157.stderr | 7 ++++++- src/test/ui/nll/borrowed-local-error.rs | 2 -- src/test/ui/nll/borrowed-local-error.stderr | 2 +- src/test/ui/nll/borrowed-match-issue-45045.stderr | 5 +++++ .../ui/nll/borrowed-referent-issue-38899.stderr | 3 +++ src/test/ui/nll/borrowed-temporary-error.rs | 2 -- src/test/ui/nll/borrowed-temporary-error.stderr | 2 +- src/test/ui/nll/borrowed-universal-error-2.rs | 2 -- src/test/ui/nll/borrowed-universal-error-2.stderr | 6 +++--- src/test/ui/nll/borrowed-universal-error.rs | 2 -- src/test/ui/nll/borrowed-universal-error.stderr | 6 +++--- src/test/ui/nll/capture-ref-in-struct.rs | 2 -- src/test/ui/nll/capture-ref-in-struct.stderr | 2 +- .../nll/closure-requirements/escape-argument.rs | 2 +- .../closure-requirements/escape-upvar-nested.rs | 2 +- .../nll/closure-requirements/escape-upvar-ref.rs | 2 +- src/test/ui/nll/drop-no-may-dangle.rs | 2 +- src/test/ui/nll/get_default.rs | 2 +- src/test/ui/nll/guarantor-issue-46974.stderr | 2 ++ ...ybe-initialized-drop-implicit-fragment-drop.rs | 2 +- .../nll/maybe-initialized-drop-with-fragment.rs | 2 +- ...itialized-drop-with-uninitialized-fragments.rs | 2 +- src/test/ui/nll/maybe-initialized-drop.rs | 2 +- src/test/ui/nll/return-ref-mut-issue-46557.stderr | 15 ++++++++++----- 28 files changed, 46 insertions(+), 55 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 157614f847a12..194b014c97b21 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1312,8 +1312,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "choose which RELRO level to use"), nll: bool = (false, parse_bool, [UNTRACKED], "run the non-lexical lifetimes MIR pass"), - nll_dump_cause: bool = (false, parse_bool, [UNTRACKED], - "dump cause information when reporting errors from NLL"), trans_time_graph: bool = (false, parse_bool, [UNTRACKED], "generate a graphical HTML report of time spent in trans and LLVM"), thinlto: Option = (None, parse_opt_bool, [TRACKED], diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 5e9eeb973007f..067e480bd60ed 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -476,13 +476,6 @@ impl Session { *(self.features.borrow_mut()) = Some(features); } - /// If true, we should gather causal information during NLL - /// checking. This will eventually be the normal thing, but right - /// now it is too unoptimized. - pub fn nll_dump_cause(&self) -> bool { - self.opts.debugging_opts.nll_dump_cause - } - /// Calculates the flavor of LTO to use for this compilation. pub fn lto(&self) -> config::Lto { // If our target has codegen requirements ignore the command line diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index 3ffb4370359bf..2151592fd663b 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -72,8 +72,6 @@ pub struct RegionInferenceContext<'tcx> { universal_regions: UniversalRegions<'tcx>, } -struct TrackCauses(bool); - struct RegionDefinition<'tcx> { /// Why we created this variable. Mostly these will be /// `RegionVariableOrigin::NLL`, but some variables get created @@ -250,15 +248,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { .map(|origin| RegionDefinition::new(origin)) .collect(); - let nll_dump_cause = ty::tls::with(|tcx| tcx.sess.nll_dump_cause()); - let mut result = Self { definitions, elements: elements.clone(), liveness_constraints: RegionValues::new( elements, num_region_variables, - TrackCauses(nll_dump_cause), ), inferred_values: None, constraints: Vec::new(), diff --git a/src/librustc_mir/borrow_check/nll/region_infer/values.rs b/src/librustc_mir/borrow_check/nll/region_infer/values.rs index e6f2a43bfc8f7..74ee04e0fb15e 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/values.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/values.rs @@ -17,7 +17,7 @@ use rustc::mir::{BasicBlock, Location, Mir}; use rustc::ty::RegionVid; use syntax::codemap::Span; -use super::{Cause, CauseExt, TrackCauses}; +use super::{Cause, CauseExt}; /// Maps between the various kinds of elements of a region value to /// the internal indices that w use. @@ -202,7 +202,6 @@ impl RegionValues { pub(super) fn new( elements: &Rc, num_region_variables: usize, - track_causes: TrackCauses, ) -> Self { assert!( elements.num_universal_regions <= num_region_variables, @@ -215,11 +214,7 @@ impl RegionValues { RegionVid::new(num_region_variables), RegionElementIndex::new(elements.num_elements()), ), - causes: if track_causes.0 { - Some(CauseMap::default()) - } else { - None - }, + causes: Some(CauseMap::default()), } } diff --git a/src/test/ui/issue-45157.stderr b/src/test/ui/issue-45157.stderr index 3ce93da6ad550..bec91f7f70dee 100644 --- a/src/test/ui/issue-45157.stderr +++ b/src/test/ui/issue-45157.stderr @@ -6,6 +6,9 @@ LL | let mref = &mut u.s.a; ... LL | let nref = &u.z.c; | ^^^^^^ immutable borrow occurs here +LL | //~^ ERROR cannot borrow `u.z.c` as immutable because it is also borrowed as mutable [E0502] +LL | println!("{} {}", mref, nref) + | ---- borrow later used here error[E0502]: cannot borrow `u.s.a` as mutable because it is also borrowed as immutable --> $DIR/issue-45157.rs:39:27 @@ -14,7 +17,9 @@ LL | let nref = &u.z.c; | ------ immutable borrow occurs here LL | //~^ ERROR cannot borrow `u.z.c` as immutable because it is also borrowed as mutable [E0502] LL | println!("{} {}", mref, nref) - | ^^^^ mutable borrow occurs here + | ^^^^ ---- borrow later used here + | | + | mutable borrow occurs here error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/borrowed-local-error.rs b/src/test/ui/nll/borrowed-local-error.rs index 785a38da95980..084d0c159ef39 100644 --- a/src/test/ui/nll/borrowed-local-error.rs +++ b/src/test/ui/nll/borrowed-local-error.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Znll-dump-cause - #![feature(nll)] fn gimme(x: &(u32,)) -> &u32 { diff --git a/src/test/ui/nll/borrowed-local-error.stderr b/src/test/ui/nll/borrowed-local-error.stderr index 3bc1978554821..24964f651f79d 100644 --- a/src/test/ui/nll/borrowed-local-error.stderr +++ b/src/test/ui/nll/borrowed-local-error.stderr @@ -1,5 +1,5 @@ error[E0597]: `v` does not live long enough - --> $DIR/borrowed-local-error.rs:22:9 + --> $DIR/borrowed-local-error.rs:20:9 | LL | let x = gimme({ | _____________- diff --git a/src/test/ui/nll/borrowed-match-issue-45045.stderr b/src/test/ui/nll/borrowed-match-issue-45045.stderr index 144eba8cb7695..a80bc686e34aa 100644 --- a/src/test/ui/nll/borrowed-match-issue-45045.stderr +++ b/src/test/ui/nll/borrowed-match-issue-45045.stderr @@ -10,6 +10,8 @@ LL | | //~^ cannot use `e` because it was mutably borrowed [E0503] LL | | Xyz::B => println!("b"), LL | | }; | |_____^ use of borrowed `e` +LL | *g = Xyz::B; + | ----------- borrow later used here error[E0503]: cannot use `e` because it was mutably borrowed --> $DIR/borrowed-match-issue-45045.rs:25:9 @@ -19,6 +21,9 @@ LL | let f = &mut e; ... LL | Xyz::A => println!("a"), | ^^^^^^ use of borrowed `e` +... +LL | *g = Xyz::B; + | ----------- borrow later used here error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/borrowed-referent-issue-38899.stderr b/src/test/ui/nll/borrowed-referent-issue-38899.stderr index 91f8178329751..675f85ecb4dd2 100644 --- a/src/test/ui/nll/borrowed-referent-issue-38899.stderr +++ b/src/test/ui/nll/borrowed-referent-issue-38899.stderr @@ -6,6 +6,9 @@ LL | let x = &mut block; LL | println!("{}", x.current); LL | let p: &'a u8 = &*block.current; | ^^^^^^^^^^^^^^^ immutable borrow occurs here +LL | //~^ ERROR cannot borrow `*block.current` as immutable because it is also borrowed as mutable +LL | drop(x); + | - borrow later used here error: aborting due to previous error diff --git a/src/test/ui/nll/borrowed-temporary-error.rs b/src/test/ui/nll/borrowed-temporary-error.rs index e1a6112d173f9..7aad7205a52a1 100644 --- a/src/test/ui/nll/borrowed-temporary-error.rs +++ b/src/test/ui/nll/borrowed-temporary-error.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Znll-dump-cause - #![feature(nll)] fn gimme(x: &(u32,)) -> &u32 { diff --git a/src/test/ui/nll/borrowed-temporary-error.stderr b/src/test/ui/nll/borrowed-temporary-error.stderr index f5cb1dccc3786..575d9b5a62d71 100644 --- a/src/test/ui/nll/borrowed-temporary-error.stderr +++ b/src/test/ui/nll/borrowed-temporary-error.stderr @@ -1,5 +1,5 @@ error[E0597]: borrowed value does not live long enough - --> $DIR/borrowed-temporary-error.rs:22:10 + --> $DIR/borrowed-temporary-error.rs:20:10 | LL | &(v,) | ^^^^ temporary value does not live long enough diff --git a/src/test/ui/nll/borrowed-universal-error-2.rs b/src/test/ui/nll/borrowed-universal-error-2.rs index da03a9fc39b63..9a59cebfccbe2 100644 --- a/src/test/ui/nll/borrowed-universal-error-2.rs +++ b/src/test/ui/nll/borrowed-universal-error-2.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Znll-dump-cause - #![feature(nll)] #![allow(warnings)] diff --git a/src/test/ui/nll/borrowed-universal-error-2.stderr b/src/test/ui/nll/borrowed-universal-error-2.stderr index ff999a71e0f92..2e4d7cc8f818d 100644 --- a/src/test/ui/nll/borrowed-universal-error-2.stderr +++ b/src/test/ui/nll/borrowed-universal-error-2.stderr @@ -1,5 +1,5 @@ error[E0597]: `v` does not live long enough - --> $DIR/borrowed-universal-error-2.rs:18:5 + --> $DIR/borrowed-universal-error-2.rs:16:5 | LL | &v | ^^ borrowed value does not live long enough @@ -7,8 +7,8 @@ LL | //~^ ERROR `v` does not live long enough [E0597] LL | } | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the function body at 16:1... - --> $DIR/borrowed-universal-error-2.rs:16:1 +note: borrowed value must be valid for the lifetime 'a as defined on the function body at 14:1... + --> $DIR/borrowed-universal-error-2.rs:14:1 | LL | fn foo<'a>(x: &'a (u32,)) -> &'a u32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/nll/borrowed-universal-error.rs b/src/test/ui/nll/borrowed-universal-error.rs index fdc4c29071ee9..9482b9b140002 100644 --- a/src/test/ui/nll/borrowed-universal-error.rs +++ b/src/test/ui/nll/borrowed-universal-error.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Znll-dump-cause - #![feature(nll)] #![allow(warnings)] diff --git a/src/test/ui/nll/borrowed-universal-error.stderr b/src/test/ui/nll/borrowed-universal-error.stderr index 4a3d0c6d959fc..3e9a3ceb1dba4 100644 --- a/src/test/ui/nll/borrowed-universal-error.stderr +++ b/src/test/ui/nll/borrowed-universal-error.stderr @@ -1,5 +1,5 @@ error[E0597]: borrowed value does not live long enough - --> $DIR/borrowed-universal-error.rs:22:12 + --> $DIR/borrowed-universal-error.rs:20:12 | LL | gimme(&(v,)) | ^^^^ temporary value does not live long enough @@ -7,8 +7,8 @@ LL | //~^ ERROR borrowed value does not live long enough [E0597] LL | } | - temporary value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the function body at 20:1... - --> $DIR/borrowed-universal-error.rs:20:1 +note: borrowed value must be valid for the lifetime 'a as defined on the function body at 18:1... + --> $DIR/borrowed-universal-error.rs:18:1 | LL | fn foo<'a>(x: &'a (u32,)) -> &'a u32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/nll/capture-ref-in-struct.rs b/src/test/ui/nll/capture-ref-in-struct.rs index 74b086ab18a58..f49e06bd9e8c8 100644 --- a/src/test/ui/nll/capture-ref-in-struct.rs +++ b/src/test/ui/nll/capture-ref-in-struct.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags:-Znll-dump-cause - // Test that a structure which tries to store a pointer to `y` into // `p` (indirectly) fails to compile. diff --git a/src/test/ui/nll/capture-ref-in-struct.stderr b/src/test/ui/nll/capture-ref-in-struct.stderr index 1c545906893a2..0fb718075849c 100644 --- a/src/test/ui/nll/capture-ref-in-struct.stderr +++ b/src/test/ui/nll/capture-ref-in-struct.stderr @@ -1,5 +1,5 @@ error[E0597]: `y` does not live long enough - --> $DIR/capture-ref-in-struct.rs:33:16 + --> $DIR/capture-ref-in-struct.rs:31:16 | LL | y: &y, | ^^ borrowed value does not live long enough diff --git a/src/test/ui/nll/closure-requirements/escape-argument.rs b/src/test/ui/nll/closure-requirements/escape-argument.rs index 17fadf0a2978b..7e918c6431de4 100644 --- a/src/test/ui/nll/closure-requirements/escape-argument.rs +++ b/src/test/ui/nll/closure-requirements/escape-argument.rs @@ -22,7 +22,7 @@ // basically checking that the MIR type checker correctly enforces the // closure signature. -// compile-flags:-Znll -Zborrowck=mir -Znll-dump-cause -Zverbose +// compile-flags:-Znll -Zborrowck=mir -Zverbose #![feature(rustc_attrs)] diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-nested.rs b/src/test/ui/nll/closure-requirements/escape-upvar-nested.rs index 984c9fe7c34bd..05700ae00ad4f 100644 --- a/src/test/ui/nll/closure-requirements/escape-upvar-nested.rs +++ b/src/test/ui/nll/closure-requirements/escape-upvar-nested.rs @@ -15,7 +15,7 @@ // // except that the closure does so via a second closure. -// compile-flags:-Znll -Zborrowck=mir -Znll-dump-cause -Zverbose +// compile-flags:-Znll -Zborrowck=mir -Zverbose #![feature(rustc_attrs)] diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-ref.rs b/src/test/ui/nll/closure-requirements/escape-upvar-ref.rs index 499ebd659556c..93d8bfafcbaa4 100644 --- a/src/test/ui/nll/closure-requirements/escape-upvar-ref.rs +++ b/src/test/ui/nll/closure-requirements/escape-upvar-ref.rs @@ -19,7 +19,7 @@ // `'b`. This relationship is propagated to the closure creator, // which reports an error. -// compile-flags:-Znll -Zborrowck=mir -Znll-dump-cause -Zverbose +// compile-flags:-Znll -Zborrowck=mir -Zverbose #![feature(rustc_attrs)] diff --git a/src/test/ui/nll/drop-no-may-dangle.rs b/src/test/ui/nll/drop-no-may-dangle.rs index 0220858a0d59e..3d9a5456cbb36 100644 --- a/src/test/ui/nll/drop-no-may-dangle.rs +++ b/src/test/ui/nll/drop-no-may-dangle.rs @@ -13,7 +13,7 @@ // because of destructor. (Note that the stderr also identifies this // destructor in the error message.) -// compile-flags:-Znll -Zborrowck=mir -Znll-dump-cause +// compile-flags:-Znll -Zborrowck=mir #![allow(warnings)] #![feature(dropck_eyepatch)] diff --git a/src/test/ui/nll/get_default.rs b/src/test/ui/nll/get_default.rs index 7c52a0c87af95..e5944e75e4241 100644 --- a/src/test/ui/nll/get_default.rs +++ b/src/test/ui/nll/get_default.rs @@ -13,7 +13,7 @@ // a variety of errors from the older, AST-based machinery (notably // borrowck), and then we get the NLL error at the end. -// compile-flags:-Znll -Zborrowck=compare -Znll-dump-cause +// compile-flags:-Znll -Zborrowck=compare struct Map { } diff --git a/src/test/ui/nll/guarantor-issue-46974.stderr b/src/test/ui/nll/guarantor-issue-46974.stderr index 4bcbb596e5c4b..82c5e8dafdced 100644 --- a/src/test/ui/nll/guarantor-issue-46974.stderr +++ b/src/test/ui/nll/guarantor-issue-46974.stderr @@ -6,6 +6,8 @@ LL | let t = &mut *s; // this borrow should last for the entire function LL | let x = &t.0; LL | *s = (2,); //~ ERROR cannot assign to `*s` | ^^^^^^^^^ assignment to borrowed `*s` occurs here +LL | *x + | -- borrow later used here error[E0621]: explicit lifetime required in the type of `s` --> $DIR/guarantor-issue-46974.rs:25:5 diff --git a/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.rs b/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.rs index 184dfe320d33d..d4df2a01c8143 100644 --- a/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.rs +++ b/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//compile-flags: -Z emit-end-regions -Zborrowck=mir -Z nll -Znll-dump-cause +//compile-flags: -Z emit-end-regions -Zborrowck=mir -Znll #![allow(warnings)] diff --git a/src/test/ui/nll/maybe-initialized-drop-with-fragment.rs b/src/test/ui/nll/maybe-initialized-drop-with-fragment.rs index beb2c87f8f3bd..2eb90dca7026e 100644 --- a/src/test/ui/nll/maybe-initialized-drop-with-fragment.rs +++ b/src/test/ui/nll/maybe-initialized-drop-with-fragment.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//compile-flags: -Z emit-end-regions -Zborrowck=mir -Znll -Znll-dump-cause +//compile-flags: -Z emit-end-regions -Zborrowck=mir -Znll #![allow(warnings)] diff --git a/src/test/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.rs b/src/test/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.rs index 39cad8acee181..f639d8f243f14 100644 --- a/src/test/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.rs +++ b/src/test/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//compile-flags: -Z emit-end-regions -Zborrowck=mir -Znll -Znll-dump-cause +//compile-flags: -Z emit-end-regions -Zborrowck=mir -Znll #![allow(warnings)] diff --git a/src/test/ui/nll/maybe-initialized-drop.rs b/src/test/ui/nll/maybe-initialized-drop.rs index 767c5b9b8be8d..c2cc479d28e3e 100644 --- a/src/test/ui/nll/maybe-initialized-drop.rs +++ b/src/test/ui/nll/maybe-initialized-drop.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//compile-flags: -Z emit-end-regions -Zborrowck=mir -Znll -Znll-dump-cause +//compile-flags: -Z emit-end-regions -Zborrowck=mir -Znll #![allow(warnings)] diff --git a/src/test/ui/nll/return-ref-mut-issue-46557.stderr b/src/test/ui/nll/return-ref-mut-issue-46557.stderr index c77e0772ce962..2184beac99b66 100644 --- a/src/test/ui/nll/return-ref-mut-issue-46557.stderr +++ b/src/test/ui/nll/return-ref-mut-issue-46557.stderr @@ -1,11 +1,16 @@ error[E0597]: borrowed value does not live long enough --> $DIR/return-ref-mut-issue-46557.rs:17:21 | -LL | let ref mut x = 1234543; //~ ERROR borrowed value does not live long enough [E0597] - | ^^^^^^^ temporary value does not live long enough -LL | x -LL | } - | - temporary value only lives until here +LL | fn gimme_static_mut() -> &'static mut u32 { + | ___________________________________________- +LL | | let ref mut x = 1234543; //~ ERROR borrowed value does not live long enough [E0597] + | | ^^^^^^^ temporary value does not live long enough +LL | | x +LL | | } + | | - + | | | + | |_temporary value only lives until here + | borrow later used here error: aborting due to previous error From b26f108b6a213f5bf9f153f0a105ea367905f8c9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 6 Mar 2018 20:45:57 +0100 Subject: [PATCH 07/15] Fix sidebar horizontal scroll --- src/librustdoc/html/static/rustdoc.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index b70dc37fdd55e..791136fa28044 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -183,7 +183,7 @@ nav.sub { } .sidebar .block > ul > li { - margin-right: -20px; + margin-right: -10px; } .content, nav { From c85c5a0423dd77a955fe865b15da95ac768de271 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 5 Mar 2018 16:12:19 -0300 Subject: [PATCH 08/15] Make causal tracking lazy --- src/librustc/infer/error_reporting/mod.rs | 19 ++++++-- .../borrow_check/error_reporting.rs | 44 +++++++++-------- src/librustc_mir/borrow_check/mod.rs | 4 +- .../borrow_check/nll/explain_borrow/mod.rs | 16 +++++-- .../borrow_check/nll/region_infer/mod.rs | 47 +++++++++++++------ .../borrow_check/nll/region_infer/values.rs | 24 +++++++++- ...er-to-static-comparing-against-free.stderr | 2 + 7 files changed, 113 insertions(+), 43 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 559b2720076f4..630d87c6098ed 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -138,9 +138,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.explain_span(scope_decorated_tag, span) } - ty::ReEarlyBound(_) | ty::ReFree(_) => self.msg_span_from_free_region(region), - - ty::ReStatic => ("the static lifetime".to_owned(), None), + ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic => { + self.msg_span_from_free_region(region) + } ty::ReEmpty => ("the empty lifetime".to_owned(), None), @@ -175,6 +175,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } fn msg_span_from_free_region(self, region: ty::Region<'tcx>) -> (String, Option) { + match *region { + ty::ReEarlyBound(_) | ty::ReFree(_) => { + self.msg_span_from_early_bound_and_free_regions(region) + }, + ty::ReStatic => ("the static lifetime".to_owned(), None), + _ => bug!(), + } + } + + fn msg_span_from_early_bound_and_free_regions( + self, + region: ty::Region<'tcx>, + ) -> (String, Option) { let scope = region.free_region_binding_scope(self); let node = self.hir.as_local_node_id(scope).unwrap_or(DUMMY_NODE_ID); let unknown; diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index b77e7cf2ec8b5..cfa1890e182ea 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -124,6 +124,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { (place, span): (&Place<'tcx>, Span), borrow: &BorrowData<'tcx>, ) { + let tcx = self.tcx; let value_msg = match self.describe_place(place) { Some(name) => format!("`{}`", name), None => "value".to_owned(), @@ -132,7 +133,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Some(name) => format!("`{}`", name), None => "value".to_owned(), }; - let mut err = self.tcx.cannot_move_when_borrowed( + let mut err = tcx.cannot_move_when_borrowed( span, &self.describe_place(place).unwrap_or("_".to_owned()), Origin::Mir, @@ -152,7 +153,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { (place, span): (&Place<'tcx>, Span), borrow: &BorrowData<'tcx>, ) { - let mut err = self.tcx.cannot_use_when_mutably_borrowed( + let tcx = self.tcx; + let mut err = tcx.cannot_use_when_mutably_borrowed( span, &self.describe_place(place).unwrap_or("_".to_owned()), self.retrieve_borrow_span(borrow), @@ -254,6 +256,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { .unwrap_or(issued_span); let desc_place = self.describe_place(place).unwrap_or("_".to_owned()); + let tcx = self.tcx; // FIXME: supply non-"" `opt_via` when appropriate let mut err = match ( @@ -265,7 +268,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { "mutable", ) { (BorrowKind::Shared, lft, _, BorrowKind::Mut { .. }, _, rgt) - | (BorrowKind::Mut { .. }, _, lft, BorrowKind::Shared, rgt, _) => self.tcx + | (BorrowKind::Mut { .. }, _, lft, BorrowKind::Shared, rgt, _) => tcx .cannot_reborrow_already_borrowed( span, &desc_place, @@ -279,7 +282,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Origin::Mir, ), - (BorrowKind::Mut { .. }, _, _, BorrowKind::Mut { .. }, _, _) => self.tcx + (BorrowKind::Mut { .. }, _, _, BorrowKind::Mut { .. }, _, _) => tcx .cannot_mutably_borrow_multiply( span, &desc_place, @@ -290,7 +293,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Origin::Mir, ), - (BorrowKind::Unique, _, _, BorrowKind::Unique, _, _) => self.tcx + (BorrowKind::Unique, _, _, BorrowKind::Unique, _, _) => tcx .cannot_uniquely_borrow_by_two_closures( span, &desc_place, @@ -299,7 +302,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Origin::Mir, ), - (BorrowKind::Unique, _, _, _, _, _) => self.tcx.cannot_uniquely_borrow_by_one_closure( + (BorrowKind::Unique, _, _, _, _, _) => tcx.cannot_uniquely_borrow_by_one_closure( span, &desc_place, "", @@ -310,7 +313,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Origin::Mir, ), - (BorrowKind::Shared, lft, _, BorrowKind::Unique, _, _) => self.tcx + (BorrowKind::Shared, lft, _, BorrowKind::Unique, _, _) => tcx .cannot_reborrow_already_uniquely_borrowed( span, &desc_place, @@ -322,7 +325,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Origin::Mir, ), - (BorrowKind::Mut { .. }, _, lft, BorrowKind::Unique, _, _) => self.tcx + (BorrowKind::Mut { .. }, _, lft, BorrowKind::Unique, _, _) => tcx .cannot_reborrow_already_uniquely_borrowed( span, &desc_place, @@ -466,7 +469,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { _proper_span: Span, end_span: Option, ) { - let mut err = self.tcx.path_does_not_live_long_enough( + let tcx = self.tcx; + let mut err = tcx.path_does_not_live_long_enough( borrow_span, &format!("`{}`", name), Origin::Mir, @@ -493,9 +497,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { proper_span: Span, end_span: Option, ) { + let tcx = self.tcx; let mut err = - self.tcx - .path_does_not_live_long_enough(proper_span, "borrowed value", Origin::Mir); + tcx.path_does_not_live_long_enough(proper_span, "borrowed value", Origin::Mir); err.span_label(proper_span, "temporary value does not live long enough"); err.span_label( drop_span, @@ -527,7 +531,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { context, name, scope_tree, borrow, drop_span, borrow_span ); - let mut err = self.tcx.path_does_not_live_long_enough( + let tcx = self.tcx; + let mut err = tcx.path_does_not_live_long_enough( borrow_span, &format!("`{}`", name), Origin::Mir, @@ -535,8 +540,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { err.span_label(borrow_span, "borrowed value does not live long enough"); err.span_label(drop_span, "borrowed value only lives until here"); - if !self.tcx.nll() { - self.tcx.note_and_explain_region( + if !tcx.nll() { + tcx.note_and_explain_region( scope_tree, &mut err, "borrowed value must be valid for ", @@ -566,14 +571,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { context, scope_tree, borrow, drop_span, proper_span ); + let tcx = self.tcx; let mut err = - self.tcx - .path_does_not_live_long_enough(proper_span, "borrowed value", Origin::Mir); + tcx.path_does_not_live_long_enough(proper_span, "borrowed value", Origin::Mir); err.span_label(proper_span, "temporary value does not live long enough"); err.span_label(drop_span, "temporary value only lives until here"); - if !self.tcx.nll() { - self.tcx.note_and_explain_region( + if !tcx.nll() { + tcx.note_and_explain_region( scope_tree, &mut err, "borrowed value must be valid for ", @@ -592,7 +597,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { (place, span): (&Place<'tcx>, Span), loan: &BorrowData<'tcx>, ) { - let mut err = self.tcx.cannot_assign_to_borrowed( + let tcx = self.tcx; + let mut err = tcx.cannot_assign_to_borrowed( span, self.retrieve_borrow_span(loan), &self.describe_place(place).unwrap_or("_".to_owned()), diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 1ff0ffaaa68b3..06412a386e84a 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -10,7 +10,7 @@ //! This query borrow-checks the MIR to (further) ensure it is not broken. -use borrow_check::nll::region_infer::RegionInferenceContext; +use borrow_check::nll::region_infer::{RegionInferenceContext, RegionCausalInfo}; use rustc::hir; use rustc::hir::def_id::DefId; use rustc::hir::map::definitions::DefPathData; @@ -231,6 +231,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( access_place_error_reported: FxHashSet(), reservation_error_reported: FxHashSet(), nonlexical_regioncx: opt_regioncx.clone(), + nonlexical_cause_info: None, }; let borrows = Borrows::new(tcx, mir, opt_regioncx, def_id, body_id); @@ -311,6 +312,7 @@ pub struct MirBorrowckCtxt<'cx, 'gcx: 'tcx, 'tcx: 'cx> { /// contains the results from region inference and lets us e.g. /// find out which CFG points are contained in each borrow region. nonlexical_regioncx: Option>>, + nonlexical_cause_info: Option, } // Check that: diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index 19f95aeec7095..843407d0810f5 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -18,16 +18,26 @@ use rustc_errors::DiagnosticBuilder; use util::liveness::{self, DefUse, LivenessMode}; impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { + /// Adds annotations to `err` explaining *why* the borrow contains the + /// point from `context`. This is key for the "3-point errors" + /// [described in the NLL RFC][d]. + /// + /// [d]: https://rust-lang.github.io/rfcs/2094-nll.html#leveraging-intuition-framing-errors-in-terms-of-points pub(in borrow_check) fn explain_why_borrow_contains_point( - &self, + &mut self, context: Context, borrow: &BorrowData<'tcx>, err: &mut DiagnosticBuilder<'_>, ) { if let Some(regioncx) = &self.nonlexical_regioncx { - if let Some(cause) = regioncx.why_region_contains_point(borrow.region, context.loc) { - let mir = self.mir; + let mir = self.mir; + if self.nonlexical_cause_info.is_none() { + self.nonlexical_cause_info = Some(regioncx.compute_causal_info(mir)); + } + + let cause_info = self.nonlexical_cause_info.as_ref().unwrap(); + if let Some(cause) = cause_info.why_region_contains_point(borrow.region, context.loc) { match *cause.root_cause() { Cause::LiveVar(local, location) => { match find_regular_use(&mir, regioncx, borrow, location, local) { diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index 2151592fd663b..9b598b8dd5d11 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -72,6 +72,8 @@ pub struct RegionInferenceContext<'tcx> { universal_regions: UniversalRegions<'tcx>, } +struct TrackCauses(bool); + struct RegionDefinition<'tcx> { /// Why we created this variable. Mostly these will be /// `RegionVariableOrigin::NLL`, but some variables get created @@ -122,6 +124,10 @@ pub(crate) enum Cause { }, } +pub(crate) struct RegionCausalInfo { + inferred_values: RegionValues, +} + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Constraint { // NB. The ordering here is not significant for correctness, but @@ -343,17 +349,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { inferred_values.contains(r.to_region_vid(), p) } - /// Returns the *reason* that the region `r` contains the given point. - pub(crate) fn why_region_contains_point(&self, r: R, p: Location) -> Option> - where - R: ToRegionVid, - { - let inferred_values = self.inferred_values - .as_ref() - .expect("region values not yet inferred"); - inferred_values.cause(r.to_region_vid(), p) - } - /// Returns access to the value of `r` for debugging purposes. pub(super) fn region_value_str(&self, r: RegionVid) -> String { let inferred_values = self.inferred_values @@ -444,13 +439,25 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } + /// Re-execute the region inference, this time tracking causal information. + /// This is significantly slower, so it is done only when an error is being reported. + pub(super) fn compute_causal_info(&self, mir: &Mir<'tcx>) -> RegionCausalInfo { + let inferred_values = self.compute_region_values(mir, TrackCauses(true)); + RegionCausalInfo { inferred_values } + } + /// Propagate the region constraints: this will grow the values /// for each region variable until all the constraints are /// satisfied. Note that some values may grow **too** large to be /// feasible, but we check this later. fn propagate_constraints(&mut self, mir: &Mir<'tcx>) { - debug!("propagate_constraints()"); - debug!("propagate_constraints: constraints={:#?}", { + let inferred_values = self.compute_region_values(mir, TrackCauses(false)); + self.inferred_values = Some(inferred_values); + } + + fn compute_region_values(&self, mir: &Mir<'tcx>, track_causes: TrackCauses) -> RegionValues { + debug!("compute_region_values()"); + debug!("compute_region_values: constraints={:#?}", { let mut constraints: Vec<_> = self.constraints.iter().collect(); constraints.sort(); constraints @@ -458,7 +465,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // The initial values for each region are derived from the liveness // constraints we have accumulated. - let mut inferred_values = self.liveness_constraints.clone(); + let mut inferred_values = self.liveness_constraints.duplicate(track_causes); let dependency_map = self.build_dependency_map(); @@ -502,7 +509,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { debug!("\n"); } - self.inferred_values = Some(inferred_values); + inferred_values } /// Builds up a map from each region variable X to a vector with the @@ -1092,6 +1099,16 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } +impl RegionCausalInfo { + /// Returns the *reason* that the region `r` contains the given point. + pub(super) fn why_region_contains_point(&self, r: R, p: Location) -> Option> + where + R: ToRegionVid, + { + self.inferred_values.cause(r.to_region_vid(), p) + } +} + impl<'tcx> RegionDefinition<'tcx> { fn new(origin: RegionVariableOrigin) -> Self { // Create a new region definition. Note that, for free diff --git a/src/librustc_mir/borrow_check/nll/region_infer/values.rs b/src/librustc_mir/borrow_check/nll/region_infer/values.rs index 74ee04e0fb15e..eb2756e2245d4 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/values.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/values.rs @@ -17,7 +17,7 @@ use rustc::mir::{BasicBlock, Location, Mir}; use rustc::ty::RegionVid; use syntax::codemap::Span; -use super::{Cause, CauseExt}; +use super::{Cause, CauseExt, TrackCauses}; /// Maps between the various kinds of elements of a region value to /// the internal indices that w use. @@ -184,7 +184,6 @@ impl ToElementIndex for RegionElementIndex { /// compact `SparseBitMatrix` representation, with one row per region /// variable. The columns consist of either universal regions or /// points in the CFG. -#[derive(Clone)] pub(super) struct RegionValues { elements: Rc, matrix: SparseBitMatrix, @@ -199,6 +198,9 @@ pub(super) struct RegionValues { type CauseMap = FxHashMap<(RegionVid, RegionElementIndex), Rc>; impl RegionValues { + /// Creates a new set of "region values" that tracks causal information. + /// Each of the regions in num_region_variables will be initialized with an + /// empty set of points and no causal information. pub(super) fn new( elements: &Rc, num_region_variables: usize, @@ -218,6 +220,24 @@ impl RegionValues { } } + /// Duplicates the region values. If track_causes is false, then the + /// resulting value will not track causal information (and any existing + /// causal information is dropped). Otherwise, the causal information is + /// preserved and maintained. Tracking the causal information makes region + /// propagation significantly slower, so we prefer not to do it until an + /// error is reported. + pub(super) fn duplicate(&self, track_causes: TrackCauses) -> Self { + Self { + elements: self.elements.clone(), + matrix: self.matrix.clone(), + causes: if track_causes.0 { + self.causes.clone() + } else { + None + }, + } + } + /// Adds the given element to the value for the given region. Returns true if /// the element is newly added (i.e., was not already present). pub(super) fn add(&mut self, r: RegionVid, elem: E, cause: &Cause) -> bool { diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index 21ed421fe96ca..86653138a185f 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -78,6 +78,8 @@ LL | let cell = Cell::new(&a); ... LL | } | - borrowed value only lives until here + | + = note: borrowed value must be valid for the static lifetime... error: aborting due to 2 previous errors From 4b12ded889864e4186693ca92f4d5771a87bb5ee Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 5 Mar 2018 14:34:24 -0300 Subject: [PATCH 09/15] mir is already a reference --- src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index 843407d0810f5..4031bd5369da6 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -40,7 +40,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { if let Some(cause) = cause_info.why_region_contains_point(borrow.region, context.loc) { match *cause.root_cause() { Cause::LiveVar(local, location) => { - match find_regular_use(&mir, regioncx, borrow, location, local) { + match find_regular_use(mir, regioncx, borrow, location, local) { Some(p) => { err.span_label( mir.source_info(p).span, @@ -58,9 +58,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } Cause::DropVar(local, location) => { - match find_drop_use(&mir, regioncx, borrow, location, local) { + match find_drop_use(mir, regioncx, borrow, location, local) { Some(p) => { - let local_name = &mir.local_decls[local].name.unwrap(); + let local_name = mir.local_decls[local].name.unwrap(); err.span_label( mir.source_info(p).span, From 52a47d4c0299e8dc2293f8ba6ff81e16a462bdd4 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 6 Mar 2018 02:29:03 -0300 Subject: [PATCH 10/15] Run rustfmt over modified files --- src/librustc/session/config.rs | 1058 ++++++++++------- src/librustc/session/mod.rs | 637 ++++++---- .../borrow_check/error_reporting.rs | 49 +- src/librustc_mir/borrow_check/mod.rs | 130 +- .../borrow_check/nll/region_infer/mod.rs | 5 +- .../borrow_check/nll/region_infer/values.rs | 5 +- 6 files changed, 1109 insertions(+), 775 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 194b014c97b21..e6ff01a0a52c6 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -27,7 +27,7 @@ use lint; use middle::cstore; use syntax::ast::{self, IntTy, UintTy}; -use syntax::codemap::{FilePathMapping, FileName}; +use syntax::codemap::{FileName, FilePathMapping}; use syntax::parse::token; use syntax::parse; use syntax::symbol::Symbol; @@ -64,12 +64,12 @@ pub enum Sanitizer { #[derive(Clone, Copy, PartialEq, Hash)] pub enum OptLevel { - No, // -O0 - Less, // -O1 - Default, // -O2 + No, // -O0 + Less, // -O1 + Default, // -O2 Aggressive, // -O3 - Size, // -Os - SizeMin, // -Oz + Size, // -Os + SizeMin, // -Oz } #[derive(Clone, Copy, PartialEq, Hash)] @@ -99,8 +99,7 @@ pub enum DebugInfoLevel { FullDebugInfo, } -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, - RustcEncodable, RustcDecodable)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, RustcEncodable, RustcDecodable)] pub enum OutputType { Bitcode, Assembly, @@ -117,12 +116,10 @@ pub enum OutputType { #[non_exhaustive] pub enum Epoch { // epochs must be kept in order, newest to oldest - /// The 2015 epoch Epoch2015, /// The 2018 epoch Epoch2018, - // when adding new epochs, be sure to update: // // - the list in the `parse_epoch` static @@ -163,7 +160,7 @@ impl str::FromStr for Epoch { match s { "2015" => Ok(Epoch::Epoch2015), "2018" => Ok(Epoch::Epoch2018), - _ => Err(()) + _ => Err(()), } } } @@ -190,14 +187,13 @@ impl<'tcx> ToStableHashKey> for OutputType { impl OutputType { fn is_compatible_with_codegen_units_and_single_output_file(&self) -> bool { match *self { - OutputType::Exe | - OutputType::DepInfo => true, - OutputType::Bitcode | - OutputType::Assembly | - OutputType::LlvmAssembly | - OutputType::Mir | - OutputType::Object | - OutputType::Metadata => false, + OutputType::Exe | OutputType::DepInfo => true, + OutputType::Bitcode + | OutputType::Assembly + | OutputType::LlvmAssembly + | OutputType::Mir + | OutputType::Object + | OutputType::Metadata => false, } } @@ -216,14 +212,14 @@ impl OutputType { fn from_shorthand(shorthand: &str) -> Option { Some(match shorthand { - "asm" => OutputType::Assembly, - "llvm-ir" => OutputType::LlvmAssembly, - "mir" => OutputType::Mir, - "llvm-bc" => OutputType::Bitcode, - "obj" => OutputType::Object, - "metadata" => OutputType::Metadata, - "link" => OutputType::Exe, - "dep-info" => OutputType::DepInfo, + "asm" => OutputType::Assembly, + "llvm-ir" => OutputType::LlvmAssembly, + "mir" => OutputType::Mir, + "llvm-bc" => OutputType::Bitcode, + "obj" => OutputType::Object, + "metadata" => OutputType::Metadata, + "link" => OutputType::Exe, + "dep-info" => OutputType::DepInfo, _ => return None, }) } @@ -281,8 +277,9 @@ impl_stable_hash_for!(tuple_struct self::OutputTypes { impl OutputTypes { pub fn new(entries: &[(OutputType, Option)]) -> OutputTypes { - OutputTypes(BTreeMap::from_iter(entries.iter() - .map(|&(k, ref v)| (k, v.clone())))) + OutputTypes(BTreeMap::from_iter( + entries.iter().map(|&(k, ref v)| (k, v.clone())), + )) } pub fn get(&self, key: &OutputType) -> Option<&Option> { @@ -304,19 +301,17 @@ impl OutputTypes { // True if any of the output types require codegen or linking. pub fn should_trans(&self) -> bool { self.0.keys().any(|k| match *k { - OutputType::Bitcode | - OutputType::Assembly | - OutputType::LlvmAssembly | - OutputType::Mir | - OutputType::Object | - OutputType::Exe => true, - OutputType::Metadata | - OutputType::DepInfo => false, + OutputType::Bitcode + | OutputType::Assembly + | OutputType::LlvmAssembly + | OutputType::Mir + | OutputType::Object + | OutputType::Exe => true, + OutputType::Metadata | OutputType::DepInfo => false, }) } } - // Use tree-based collections to cheaply get a deterministic Hash implementation. // DO NOT switch BTreeMap or BTreeSet out for an unsorted container type! That // would break dependency tracking for commandline arguments. @@ -522,8 +517,7 @@ pub enum Input { impl Input { pub fn filestem(&self) -> String { match *self { - Input::File(ref ifile) => ifile.file_stem().unwrap() - .to_str().unwrap().to_string(), + Input::File(ref ifile) => ifile.file_stem().unwrap().to_str().unwrap().to_string(), Input::Str { .. } => "rust_out".to_string(), } } @@ -550,7 +544,9 @@ pub const RUST_CGU_EXT: &str = "rcgu"; impl OutputFilenames { pub fn path(&self, flavor: OutputType) -> PathBuf { - self.outputs.get(&flavor).and_then(|p| p.to_owned()) + self.outputs + .get(&flavor) + .and_then(|p| p.to_owned()) .or_else(|| self.single_output_file.clone()) .unwrap_or_else(|| self.temp_path(flavor, None)) } @@ -558,20 +554,14 @@ impl OutputFilenames { /// Get the path where a compilation artifact of the given type for the /// given codegen unit should be placed on disk. If codegen_unit_name is /// None, a path distinct from those of any codegen unit will be generated. - pub fn temp_path(&self, - flavor: OutputType, - codegen_unit_name: Option<&str>) - -> PathBuf { + pub fn temp_path(&self, flavor: OutputType, codegen_unit_name: Option<&str>) -> PathBuf { let extension = flavor.extension(); self.temp_path_ext(extension, codegen_unit_name) } /// Like temp_path, but also supports things where there is no corresponding /// OutputType, like no-opt-bitcode or lto-bitcode. - pub fn temp_path_ext(&self, - ext: &str, - codegen_unit_name: Option<&str>) - -> PathBuf { + pub fn temp_path_ext(&self, ext: &str, codegen_unit_name: Option<&str>) -> PathBuf { let base = self.out_directory.join(&self.filestem()); let mut extension = String::new(); @@ -595,7 +585,9 @@ impl OutputFilenames { } pub fn with_extension(&self, extension: &str) -> PathBuf { - self.out_directory.join(&self.filestem()).with_extension(extension) + self.out_directory + .join(&self.filestem()) + .with_extension(extension) } pub fn filestem(&self) -> String { @@ -612,8 +604,7 @@ pub fn host_triple() -> &'static str { // Instead of grabbing the host triple (for the current host), we grab (at // compile time) the target triple that this rustc is built with and // calling that (at runtime) the host triple. - (option_env!("CFG_COMPILER_HOST_TRIPLE")). - expect("CFG_COMPILER_HOST_TRIPLE") + (option_env!("CFG_COMPILER_HOST_TRIPLE")).expect("CFG_COMPILER_HOST_TRIPLE") } /// Some reasonable defaults @@ -652,15 +643,14 @@ pub fn basic_options() -> Options { impl Options { /// True if there is a reason to build the dep graph. pub fn build_dep_graph(&self) -> bool { - self.incremental.is_some() || - self.debugging_opts.dump_dep_graph || - self.debugging_opts.query_dep_graph + self.incremental.is_some() || self.debugging_opts.dump_dep_graph + || self.debugging_opts.query_dep_graph } #[inline(always)] pub fn enable_dep_node_debug_strs(&self) -> bool { - cfg!(debug_assertions) && - (self.debugging_opts.query_dep_graph || self.debugging_opts.incremental_info) + cfg!(debug_assertions) + && (self.debugging_opts.query_dep_graph || self.debugging_opts.incremental_info) } pub fn file_path_mapping(&self) -> FilePathMapping { @@ -1376,18 +1366,30 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig { } ret.insert((Symbol::intern("target_arch"), Some(Symbol::intern(arch)))); ret.insert((Symbol::intern("target_endian"), Some(Symbol::intern(end)))); - ret.insert((Symbol::intern("target_pointer_width"), Some(Symbol::intern(wordsz)))); + ret.insert(( + Symbol::intern("target_pointer_width"), + Some(Symbol::intern(wordsz)), + )); ret.insert((Symbol::intern("target_env"), Some(Symbol::intern(env)))); - ret.insert((Symbol::intern("target_vendor"), Some(Symbol::intern(vendor)))); + ret.insert(( + Symbol::intern("target_vendor"), + Some(Symbol::intern(vendor)), + )); if sess.target.target.options.has_elf_tls { ret.insert((Symbol::intern("target_thread_local"), None)); } for &i in &[8, 16, 32, 64, 128] { if i >= min_atomic_width && i <= max_atomic_width { let s = i.to_string(); - ret.insert((Symbol::intern("target_has_atomic"), Some(Symbol::intern(&s)))); + ret.insert(( + Symbol::intern("target_has_atomic"), + Some(Symbol::intern(&s)), + )); if &s == wordsz { - ret.insert((Symbol::intern("target_has_atomic"), Some(Symbol::intern("ptr")))); + ret.insert(( + Symbol::intern("target_has_atomic"), + Some(Symbol::intern("ptr")), + )); } } } @@ -1400,9 +1402,7 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig { return ret; } -pub fn build_configuration(sess: &Session, - mut user_cfg: ast::CrateConfig) - -> ast::CrateConfig { +pub fn build_configuration(sess: &Session, mut user_cfg: ast::CrateConfig) -> ast::CrateConfig { // Combine the configuration requested by the session (command line) with // some default and generated configuration items let default_cfg = default_configuration(sess); @@ -1429,8 +1429,11 @@ pub fn build_target_config(opts: &Options, sp: &Handler) -> Config { "16" => (ast::IntTy::I16, ast::UintTy::U16), "32" => (ast::IntTy::I32, ast::UintTy::U32), "64" => (ast::IntTy::I64, ast::UintTy::U64), - w => sp.fatal(&format!("target specification was invalid: \ - unrecognized target-pointer-width {}", w)).raise(), + w => sp.fatal(&format!( + "target specification was invalid: \ + unrecognized target-pointer-width {}", + w + )).raise(), }; Config { @@ -1459,7 +1462,8 @@ impl RustcOptGroup { } pub fn stable(name: &'static str, f: F) -> RustcOptGroup - where F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static, + where + F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static, { RustcOptGroup { name, @@ -1469,7 +1473,8 @@ impl RustcOptGroup { } pub fn unstable(name: &'static str, f: F) -> RustcOptGroup - where F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static, + where + F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static, { RustcOptGroup { name, @@ -1497,13 +1502,15 @@ mod opt { pub type S = &'static str; fn stable(name: S, f: F) -> R - where F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static + where + F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static, { RustcOptGroup::stable(name, f) } fn unstable(name: S, f: F) -> R - where F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static + where + F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static, { RustcOptGroup::unstable(name, f) } @@ -1556,42 +1563,88 @@ pub fn rustc_short_optgroups() -> Vec { vec![ opt::flag_s("h", "help", "Display this message"), opt::multi_s("", "cfg", "Configure the compilation environment", "SPEC"), - opt::multi_s("L", "", "Add a directory to the library search path. The + opt::multi_s( + "L", + "", + "Add a directory to the library search path. The optional KIND can be one of dependency, crate, native, - framework or all (the default).", "[KIND=]PATH"), - opt::multi_s("l", "", "Link the generated crate(s) to the specified native + framework or all (the default).", + "[KIND=]PATH", + ), + opt::multi_s( + "l", + "", + "Link the generated crate(s) to the specified native library NAME. The optional KIND can be one of static, dylib, or framework. If omitted, dylib is - assumed.", "[KIND=]NAME"), - opt::multi_s("", "crate-type", "Comma separated list of types of crates + assumed.", + "[KIND=]NAME", + ), + opt::multi_s( + "", + "crate-type", + "Comma separated list of types of crates for the compiler to emit", - "[bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]"), - opt::opt_s("", "crate-name", "Specify the name of the crate being built", - "NAME"), - opt::multi_s("", "emit", "Comma separated list of types of output for \ - the compiler to emit", - "[asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]"), - opt::multi_s("", "print", "Comma separated list of compiler information to \ - print on stdout", - "[crate-name|file-names|sysroot|cfg|target-list|\ - target-cpus|target-features|relocation-models|\ - code-models|tls-models|target-spec-json|native-static-libs]"), - opt::flagmulti_s("g", "", "Equivalent to -C debuginfo=2"), + "[bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]", + ), + opt::opt_s( + "", + "crate-name", + "Specify the name of the crate being built", + "NAME", + ), + opt::multi_s( + "", + "emit", + "Comma separated list of types of output for \ + the compiler to emit", + "[asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]", + ), + opt::multi_s( + "", + "print", + "Comma separated list of compiler information to \ + print on stdout", + "[crate-name|file-names|sysroot|cfg|target-list|\ + target-cpus|target-features|relocation-models|\ + code-models|tls-models|target-spec-json|native-static-libs]", + ), + opt::flagmulti_s("g", "", "Equivalent to -C debuginfo=2"), opt::flagmulti_s("O", "", "Equivalent to -C opt-level=2"), opt::opt_s("o", "", "Write output to ", "FILENAME"), - opt::opt_s("", "out-dir", "Write output to compiler-chosen filename \ - in

", "DIR"), - opt::opt_s("", "explain", "Provide a detailed explanation of an error \ - message", "OPT"), + opt::opt_s( + "", + "out-dir", + "Write output to compiler-chosen filename \ + in ", + "DIR", + ), + opt::opt_s( + "", + "explain", + "Provide a detailed explanation of an error \ + message", + "OPT", + ), opt::flag_s("", "test", "Build a test harness"), - opt::opt_s("", "target", "Target triple for which the code is compiled", "TARGET"), + opt::opt_s( + "", + "target", + "Target triple for which the code is compiled", + "TARGET", + ), opt::multi_s("W", "warn", "Set lint warnings", "OPT"), opt::multi_s("A", "allow", "Set lint allowed", "OPT"), opt::multi_s("D", "deny", "Set lint denied", "OPT"), opt::multi_s("F", "forbid", "Set lint forbidden", "OPT"), - opt::multi_s("", "cap-lints", "Set the most restrictive lint level. \ - More restrictive lints are capped at this \ - level", "LEVEL"), + opt::multi_s( + "", + "cap-lints", + "Set the most restrictive lint level. \ + More restrictive lints are capped at this \ + level", + "LEVEL", + ), opt::multi_s("C", "codegen", "Set a codegen option", "OPT[=VALUE]"), opt::flag_s("V", "version", "Print version info and exit"), opt::flag_s("v", "verbose", "Use verbose output"), @@ -1604,64 +1657,95 @@ pub fn rustc_short_optgroups() -> Vec { pub fn rustc_optgroups() -> Vec { let mut opts = rustc_short_optgroups(); opts.extend(vec![ - opt::multi_s("", "extern", "Specify where an external rust library is located", - "NAME=PATH"), + opt::multi_s( + "", + "extern", + "Specify where an external rust library is located", + "NAME=PATH", + ), opt::opt_s("", "sysroot", "Override the system root", "PATH"), opt::multi("Z", "", "Set internal debugging options", "FLAG"), - opt::opt_s("", "error-format", - "How errors and other messages are produced", - "human|json|short"), - opt::opt_s("", "color", "Configure coloring of output: + opt::opt_s( + "", + "error-format", + "How errors and other messages are produced", + "human|json|short", + ), + opt::opt_s( + "", + "color", + "Configure coloring of output: auto = colorize, if output goes to a tty (default); always = always colorize output; - never = never colorize output", "auto|always|never"), - - opt::opt("", "pretty", - "Pretty-print the input instead of compiling; + never = never colorize output", + "auto|always|never", + ), + opt::opt( + "", + "pretty", + "Pretty-print the input instead of compiling; valid types are: `normal` (un-annotated source), `expanded` (crates expanded), or `expanded,identified` (fully parenthesized, AST nodes with IDs).", - "TYPE"), - opt::multi_s("", "remap-path-prefix", "remap source names in output", "FROM=TO"), + "TYPE", + ), + opt::multi_s( + "", + "remap-path-prefix", + "remap source names in output", + "FROM=TO", + ), ]); opts } // Convert strings provided as --cfg [cfgspec] into a crate_cfg -pub fn parse_cfgspecs(cfgspecs: Vec ) -> ast::CrateConfig { - cfgspecs.into_iter().map(|s| { - let sess = parse::ParseSess::new(FilePathMapping::empty()); - let mut parser = - parse::new_parser_from_source_str(&sess, FileName::CfgSpec, s.to_string()); - - let meta_item = panictry!(parser.parse_meta_item()); - - if parser.token != token::Eof { - early_error(ErrorOutputType::default(), &format!("invalid --cfg argument: {}", s)) - } else if meta_item.is_meta_item_list() { - let msg = - format!("invalid predicate in --cfg command line argument: `{}`", meta_item.name()); - early_error(ErrorOutputType::default(), &msg) - } +pub fn parse_cfgspecs(cfgspecs: Vec) -> ast::CrateConfig { + cfgspecs + .into_iter() + .map(|s| { + let sess = parse::ParseSess::new(FilePathMapping::empty()); + let mut parser = + parse::new_parser_from_source_str(&sess, FileName::CfgSpec, s.to_string()); + + let meta_item = panictry!(parser.parse_meta_item()); + + if parser.token != token::Eof { + early_error( + ErrorOutputType::default(), + &format!("invalid --cfg argument: {}", s), + ) + } else if meta_item.is_meta_item_list() { + let msg = format!( + "invalid predicate in --cfg command line argument: `{}`", + meta_item.name() + ); + early_error(ErrorOutputType::default(), &msg) + } - (meta_item.name(), meta_item.value_str()) - }).collect::() + (meta_item.name(), meta_item.value_str()) + }) + .collect::() } -pub fn build_session_options_and_crate_config(matches: &getopts::Matches) - -> (Options, ast::CrateConfig) { +pub fn build_session_options_and_crate_config( + matches: &getopts::Matches, +) -> (Options, ast::CrateConfig) { let color = match matches.opt_str("color").as_ref().map(|s| &s[..]) { - Some("auto") => ColorConfig::Auto, + Some("auto") => ColorConfig::Auto, Some("always") => ColorConfig::Always, - Some("never") => ColorConfig::Never, + Some("never") => ColorConfig::Never, None => ColorConfig::Auto, - Some(arg) => { - early_error(ErrorOutputType::default(), &format!("argument for --color must be auto, \ - always or never (instead was `{}`)", - arg)) - } + Some(arg) => early_error( + ErrorOutputType::default(), + &format!( + "argument for --color must be auto, \ + always or never (instead was `{}`)", + arg + ), + ), }; // We need the opts_present check because the driver will send us Matches @@ -1671,25 +1755,31 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) let error_format = if matches.opts_present(&["error-format".to_owned()]) { match matches.opt_str("error-format").as_ref().map(|s| &s[..]) { Some("human") => ErrorOutputType::HumanReadable(color), - Some("json") => ErrorOutputType::Json(false), + Some("json") => ErrorOutputType::Json(false), Some("pretty-json") => ErrorOutputType::Json(true), Some("short") => { if nightly_options::is_unstable_enabled(matches) { ErrorOutputType::Short(color) } else { - early_error(ErrorOutputType::default(), - &format!("the `-Z unstable-options` flag must also be passed to \ - enable the short error message option")); + early_error( + ErrorOutputType::default(), + &format!( + "the `-Z unstable-options` flag must also be passed to \ + enable the short error message option" + ), + ); } } None => ErrorOutputType::HumanReadable(color), - Some(arg) => { - early_error(ErrorOutputType::HumanReadable(color), - &format!("argument for --error-format must be `human`, `json` or \ - `short` (instead was `{}`)", - arg)) - } + Some(arg) => early_error( + ErrorOutputType::HumanReadable(color), + &format!( + "argument for --error-format must be `human`, `json` or \ + `short` (instead was `{}`)", + arg + ), + ), } } else { ErrorOutputType::HumanReadable(color) @@ -1713,15 +1803,17 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) } let lint_cap = matches.opt_str("cap-lints").map(|cap| { - lint::Level::from_str(&cap).unwrap_or_else(|| { - early_error(error_format, &format!("unknown lint level: `{}`", cap)) - }) + lint::Level::from_str(&cap) + .unwrap_or_else(|| early_error(error_format, &format!("unknown lint level: `{}`", cap))) }); let mut debugging_opts = build_debugging_options(matches, error_format); if !debugging_opts.unstable_options && error_format == ErrorOutputType::Json(true) { - early_error(ErrorOutputType::Json(false), "--error-format=pretty-json is unstable"); + early_error( + ErrorOutputType::Json(false), + "--error-format=pretty-json is unstable", + ); } let mut output_types = BTreeMap::new(); @@ -1732,10 +1824,14 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) let shorthand = parts.next().unwrap(); let output_type = match OutputType::from_shorthand(shorthand) { Some(output_type) => output_type, - None => early_error(error_format, &format!( - "unknown emission type: `{}` - expected one of: {}", - shorthand, OutputType::shorthands_display(), - )), + None => early_error( + error_format, + &format!( + "unknown emission type: `{}` - expected one of: {}", + shorthand, + OutputType::shorthands_display(), + ), + ), }; let path = parts.next().map(PathBuf::from); output_types.insert(output_type, path); @@ -1752,11 +1848,10 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) // Issue #30063: if user requests llvm-related output to one // particular path, disable codegen-units. - let incompatible: Vec<_> = output_types.iter() + let incompatible: Vec<_> = output_types + .iter() .map(|ot_path| ot_path.0) - .filter(|ot| { - !ot.is_compatible_with_codegen_units_and_single_output_file() - }) + .filter(|ot| !ot.is_compatible_with_codegen_units_and_single_output_file()) .map(|ot| ot.shorthand()) .collect(); if !incompatible.is_empty() { @@ -1764,9 +1859,14 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) Some(n) if n > 1 => { if matches.opt_present("o") { for ot in &incompatible { - early_warn(error_format, &format!("--emit={} with -o incompatible with \ - -C codegen-units=N for N > 1", - ot)); + early_warn( + error_format, + &format!( + "--emit={} with -o incompatible with \ + -C codegen-units=N for N > 1", + ot + ), + ); } early_warn(error_format, "resetting to default -C codegen-units=1"); codegen_units = Some(1); @@ -1781,21 +1881,30 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) } if debugging_opts.query_threads == Some(0) { - early_error(error_format, "Value for query threads must be a positive nonzero integer"); + early_error( + error_format, + "Value for query threads must be a positive nonzero integer", + ); } if codegen_units == Some(0) { - early_error(error_format, "Value for codegen units must be a positive nonzero integer"); + early_error( + error_format, + "Value for codegen units must be a positive nonzero integer", + ); } let incremental = match (&debugging_opts.incremental, &cg.incremental) { (&Some(ref path1), &Some(ref path2)) => { if path1 != path2 { - early_error(error_format, - &format!("conflicting paths for `-Z incremental` and \ - `-C incremental` specified: {} versus {}", - path1, - path2)); + early_error( + error_format, + &format!( + "conflicting paths for `-Z incremental` and \ + `-C incremental` specified: {} versus {}", + path1, path2 + ), + ); } else { Some(path1) } @@ -1806,7 +1915,10 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) }.map(|m| PathBuf::from(m)); if cg.lto != Lto::No && incremental.is_some() { - early_error(error_format, "can't perform LTO when compiling incrementally"); + early_error( + error_format, + "can't perform LTO when compiling incrementally", + ); } let mut prints = Vec::::new(); @@ -1826,7 +1938,11 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) prints.push(PrintRequest::CodeModels); cg.code_model = None; } - if debugging_opts.tls_model.as_ref().map_or(false, |s| s == "help") { + if debugging_opts + .tls_model + .as_ref() + .map_or(false, |s| s == "help") + { prints.push(PrintRequest::TlsModels); debugging_opts.tls_model = None; } @@ -1834,8 +1950,9 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) let cg = cg; let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m)); - let target = matches.opt_str("target").unwrap_or( - host_triple().to_string()); + let target = matches + .opt_str("target") + .unwrap_or(host_triple().to_string()); let opt_level = { if matches.opt_present("O") { if cg.opt_level.is_some() { @@ -1843,8 +1960,10 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) } OptLevel::Default } else { - match (cg.opt_level.as_ref().map(String::as_ref), - nightly_options::is_nightly_build()) { + match ( + cg.opt_level.as_ref().map(String::as_ref), + nightly_options::is_nightly_build(), + ) { (None, _) => OptLevel::No, (Some("0"), _) => OptLevel::No, (Some("1"), _) => OptLevel::Less, @@ -1853,13 +1972,23 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) (Some("s"), true) => OptLevel::Size, (Some("z"), true) => OptLevel::SizeMin, (Some("s"), false) | (Some("z"), false) => { - early_error(error_format, &format!("the optimizations s or z are only \ - accepted on the nightly compiler")); - }, + early_error( + error_format, + &format!( + "the optimizations s or z are only \ + accepted on the nightly compiler" + ), + ); + } (Some(arg), _) => { - early_error(error_format, &format!("optimization level needs to be \ - between 0-3 (instead was `{}`)", - arg)); + early_error( + error_format, + &format!( + "optimization level needs to be \ + between 0-3 (instead was `{}`)", + arg + ), + ); } } } @@ -1876,9 +2005,14 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) Some(1) => LimitedDebugInfo, Some(2) => FullDebugInfo, Some(arg) => { - early_error(error_format, &format!("debug info level needs to be between \ - 0-2 (instead was `{}`)", - arg)); + early_error( + error_format, + &format!( + "debug info level needs to be between \ + 0-2 (instead was `{}`)", + arg + ), + ); } } }; @@ -1888,76 +2022,91 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) search_paths.add_path(&s[..], error_format); } - let libs = matches.opt_strs("l").into_iter().map(|s| { - // Parse string of the form "[KIND=]lib[:new_name]", - // where KIND is one of "dylib", "framework", "static". - let mut parts = s.splitn(2, '='); - let kind = parts.next().unwrap(); - let (name, kind) = match (parts.next(), kind) { - (None, name) => (name, None), - (Some(name), "dylib") => (name, Some(cstore::NativeUnknown)), - (Some(name), "framework") => (name, Some(cstore::NativeFramework)), - (Some(name), "static") => (name, Some(cstore::NativeStatic)), - (Some(name), "static-nobundle") => (name, Some(cstore::NativeStaticNobundle)), - (_, s) => { - early_error(error_format, &format!("unknown library kind `{}`, expected \ - one of dylib, framework, or static", - s)); + let libs = matches + .opt_strs("l") + .into_iter() + .map(|s| { + // Parse string of the form "[KIND=]lib[:new_name]", + // where KIND is one of "dylib", "framework", "static". + let mut parts = s.splitn(2, '='); + let kind = parts.next().unwrap(); + let (name, kind) = match (parts.next(), kind) { + (None, name) => (name, None), + (Some(name), "dylib") => (name, Some(cstore::NativeUnknown)), + (Some(name), "framework") => (name, Some(cstore::NativeFramework)), + (Some(name), "static") => (name, Some(cstore::NativeStatic)), + (Some(name), "static-nobundle") => (name, Some(cstore::NativeStaticNobundle)), + (_, s) => { + early_error( + error_format, + &format!( + "unknown library kind `{}`, expected \ + one of dylib, framework, or static", + s + ), + ); + } + }; + if kind == Some(cstore::NativeStaticNobundle) && !nightly_options::is_nightly_build() { + early_error( + error_format, + &format!( + "the library kind 'static-nobundle' is only \ + accepted on the nightly compiler" + ), + ); } - }; - if kind == Some(cstore::NativeStaticNobundle) && !nightly_options::is_nightly_build() { - early_error(error_format, &format!("the library kind 'static-nobundle' is only \ - accepted on the nightly compiler")); - } - let mut name_parts = name.splitn(2, ':'); - let name = name_parts.next().unwrap(); - let new_name = name_parts.next(); - (name.to_string(), new_name.map(|n| n.to_string()), kind) - }).collect(); + let mut name_parts = name.splitn(2, ':'); + let name = name_parts.next().unwrap(); + let new_name = name_parts.next(); + (name.to_string(), new_name.map(|n| n.to_string()), kind) + }) + .collect(); let cfg = parse_cfgspecs(matches.opt_strs("cfg")); let test = matches.opt_present("test"); - prints.extend(matches.opt_strs("print").into_iter().map(|s| { - match &*s { - "crate-name" => PrintRequest::CrateName, - "file-names" => PrintRequest::FileNames, - "sysroot" => PrintRequest::Sysroot, - "cfg" => PrintRequest::Cfg, - "target-list" => PrintRequest::TargetList, - "target-cpus" => PrintRequest::TargetCPUs, - "target-features" => PrintRequest::TargetFeatures, - "relocation-models" => PrintRequest::RelocationModels, - "code-models" => PrintRequest::CodeModels, - "tls-models" => PrintRequest::TlsModels, - "native-static-libs" => PrintRequest::NativeStaticLibs, - "target-spec-json" => { - if nightly_options::is_unstable_enabled(matches) { - PrintRequest::TargetSpec - } else { - early_error(error_format, - &format!("the `-Z unstable-options` flag must also be passed to \ - enable the target-spec-json print option")); - } - }, - req => { - early_error(error_format, &format!("unknown print request `{}`", req)) + prints.extend(matches.opt_strs("print").into_iter().map(|s| match &*s { + "crate-name" => PrintRequest::CrateName, + "file-names" => PrintRequest::FileNames, + "sysroot" => PrintRequest::Sysroot, + "cfg" => PrintRequest::Cfg, + "target-list" => PrintRequest::TargetList, + "target-cpus" => PrintRequest::TargetCPUs, + "target-features" => PrintRequest::TargetFeatures, + "relocation-models" => PrintRequest::RelocationModels, + "code-models" => PrintRequest::CodeModels, + "tls-models" => PrintRequest::TlsModels, + "native-static-libs" => PrintRequest::NativeStaticLibs, + "target-spec-json" => { + if nightly_options::is_unstable_enabled(matches) { + PrintRequest::TargetSpec + } else { + early_error( + error_format, + &format!( + "the `-Z unstable-options` flag must also be passed to \ + enable the target-spec-json print option" + ), + ); } } + req => early_error(error_format, &format!("unknown print request `{}`", req)), })); let borrowck_mode = match debugging_opts.borrowck.as_ref().map(|s| &s[..]) { None | Some("ast") => BorrowckMode::Ast, Some("mir") => BorrowckMode::Mir, Some("compare") => BorrowckMode::Compare, - Some(m) => { - early_error(error_format, &format!("unknown borrowck mode `{}`", m)) - }, + Some(m) => early_error(error_format, &format!("unknown borrowck mode `{}`", m)), }; if !cg.remark.is_empty() && debuginfo == NoDebugInfo { - early_warn(error_format, "-C remark will not show source locations without \ - --debuginfo"); + early_warn( + error_format, + "-C remark will not show source locations without \ + --debuginfo", + ); } let mut externs = BTreeMap::new(); @@ -1969,17 +2118,22 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) }; let location = match parts.next() { Some(s) => s, - None => early_error(error_format, "--extern value must be of the format `foo=bar`"), + None => early_error( + error_format, + "--extern value must be of the format `foo=bar`", + ), }; - externs.entry(name.to_string()) - .or_insert_with(BTreeSet::new) - .insert(location.to_string()); + externs + .entry(name.to_string()) + .or_insert_with(BTreeSet::new) + .insert(location.to_string()); } let crate_name = matches.opt_str("crate-name"); - let remap_path_prefix = matches.opt_strs("remap-path-prefix") + let remap_path_prefix = matches + .opt_strs("remap-path-prefix") .into_iter() .map(|remap| { let mut parts = remap.rsplitn(2, '='); // reverse iterator @@ -1987,60 +2141,62 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) let from = parts.next(); match (from, to) { (Some(from), Some(to)) => (PathBuf::from(from), PathBuf::from(to)), - _ => early_error(error_format, - "--remap-path-prefix must contain '=' between FROM and TO"), + _ => early_error( + error_format, + "--remap-path-prefix must contain '=' between FROM and TO", + ), } }) .collect(); - (Options { - crate_types, - optimize: opt_level, - debuginfo, - lint_opts, - lint_cap, - describe_lints, - output_types: OutputTypes(output_types), - search_paths, - maybe_sysroot: sysroot_opt, - target_triple: target, - test, - incremental, - debugging_opts, - prints, - borrowck_mode, - cg, - error_format, - externs: Externs(externs), - crate_name, - alt_std_name: None, - libs, - unstable_features: UnstableFeatures::from_environment(), - debug_assertions, - actually_rustdoc: false, - cli_forced_codegen_units: codegen_units, - cli_forced_thinlto_off: disable_thinlto, - remap_path_prefix, - }, - cfg) + ( + Options { + crate_types, + optimize: opt_level, + debuginfo, + lint_opts, + lint_cap, + describe_lints, + output_types: OutputTypes(output_types), + search_paths, + maybe_sysroot: sysroot_opt, + target_triple: target, + test, + incremental, + debugging_opts, + prints, + borrowck_mode, + cg, + error_format, + externs: Externs(externs), + crate_name, + alt_std_name: None, + libs, + unstable_features: UnstableFeatures::from_environment(), + debug_assertions, + actually_rustdoc: false, + cli_forced_codegen_units: codegen_units, + cli_forced_thinlto_off: disable_thinlto, + remap_path_prefix, + }, + cfg, + ) } -pub fn parse_crate_types_from_list(list_list: Vec) - -> Result, String> { +pub fn parse_crate_types_from_list(list_list: Vec) -> Result, String> { let mut crate_types: Vec = Vec::new(); for unparsed_crate_type in &list_list { for part in unparsed_crate_type.split(',') { let new_part = match part { - "lib" => default_lib_output(), - "rlib" => CrateTypeRlib, + "lib" => default_lib_output(), + "rlib" => CrateTypeRlib, "staticlib" => CrateTypeStaticlib, - "dylib" => CrateTypeDylib, - "cdylib" => CrateTypeCdylib, - "bin" => CrateTypeExecutable, + "dylib" => CrateTypeDylib, + "cdylib" => CrateTypeCdylib, + "bin" => CrateTypeExecutable, "proc-macro" => CrateTypeProcMacro, _ => { - return Err(format!("unknown crate type: `{}`", - part)); + return Err(format!("unknown crate type: `{}`", part)); } }; if !crate_types.contains(&new_part) { @@ -2059,7 +2215,11 @@ pub mod nightly_options { use session::early_error; pub fn is_unstable_enabled(matches: &getopts::Matches) -> bool { - is_nightly_build() && matches.opt_strs("Z").iter().any(|x| *x == "unstable-options") + is_nightly_build() + && matches + .opt_strs("Z") + .iter() + .any(|x| *x == "unstable-options") } pub fn is_nightly_build() -> bool { @@ -2067,30 +2227,40 @@ pub mod nightly_options { } pub fn check_nightly_options(matches: &getopts::Matches, flags: &[RustcOptGroup]) { - let has_z_unstable_option = matches.opt_strs("Z").iter().any(|x| *x == "unstable-options"); - let really_allows_unstable_options = UnstableFeatures::from_environment() - .is_nightly_build(); + let has_z_unstable_option = matches + .opt_strs("Z") + .iter() + .any(|x| *x == "unstable-options"); + let really_allows_unstable_options = + UnstableFeatures::from_environment().is_nightly_build(); for opt in flags.iter() { if opt.stability == OptionStability::Stable { - continue + continue; } if !matches.opt_present(opt.name) { - continue + continue; } if opt.name != "Z" && !has_z_unstable_option { - early_error(ErrorOutputType::default(), - &format!("the `-Z unstable-options` flag must also be passed to enable \ - the flag `{}`", - opt.name)); + early_error( + ErrorOutputType::default(), + &format!( + "the `-Z unstable-options` flag must also be passed to enable \ + the flag `{}`", + opt.name + ), + ); } if really_allows_unstable_options { - continue + continue; } match opt.stability { OptionStability::Unstable => { - let msg = format!("the option `{}` is only accepted on the \ - nightly compiler", opt.name); + let msg = format!( + "the option `{}` is only accepted on the \ + nightly compiler", + opt.name + ); early_error(ErrorOutputType::default(), &msg); } OptionStability::Stable => {} @@ -2137,8 +2307,8 @@ mod dep_tracking { use std::hash::Hash; use std::path::PathBuf; use std::collections::hash_map::DefaultHasher; - use super::{Passes, CrateType, OptLevel, DebugInfoLevel, Lto, - OutputTypes, ErrorOutputType, Sanitizer, Epoch}; + use super::{CrateType, DebugInfoLevel, Epoch, ErrorOutputType, Lto, OptLevel, OutputTypes, + Passes, Sanitizer}; use syntax::feature_gate::UnstableFeatures; use rustc_back::{PanicStrategy, RelroLevel}; @@ -2205,13 +2375,17 @@ mod dep_tracking { impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf); impl_dep_tracking_hash_for_sortable_vec_of!(CrateType); impl_dep_tracking_hash_for_sortable_vec_of!((String, lint::Level)); - impl_dep_tracking_hash_for_sortable_vec_of!((String, Option, - Option)); + impl_dep_tracking_hash_for_sortable_vec_of!(( + String, + Option, + Option + )); impl_dep_tracking_hash_for_sortable_vec_of!((String, u64)); impl DepTrackingHash for (T1, T2) - where T1: DepTrackingHash, - T2: DepTrackingHash + where + T1: DepTrackingHash, + T2: DepTrackingHash, { fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) { Hash::hash(&0, hasher); @@ -2222,9 +2396,10 @@ mod dep_tracking { } impl DepTrackingHash for (T1, T2, T3) - where T1: DepTrackingHash, - T2: DepTrackingHash, - T3: DepTrackingHash + where + T1: DepTrackingHash, + T2: DepTrackingHash, + T3: DepTrackingHash, { fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) { Hash::hash(&0, hasher); @@ -2237,9 +2412,11 @@ mod dep_tracking { } // This is a stable hash because BTreeMap is a sorted container - pub fn stable_hash(sub_hashes: BTreeMap<&'static str, &dyn DepTrackingHash>, - hasher: &mut DefaultHasher, - error_format: ErrorOutputType) { + pub fn stable_hash( + sub_hashes: BTreeMap<&'static str, &dyn DepTrackingHash>, + hasher: &mut DefaultHasher, + error_format: ErrorOutputType, + ) { for (key, sub_hash) in sub_hashes { // Using Hash::hash() instead of DepTrackingHash::hash() is fine for // the keys, as they are just plain strings @@ -2262,7 +2439,7 @@ mod tests { use std::collections::{BTreeMap, BTreeSet}; use std::iter::FromIterator; use std::path::PathBuf; - use super::{OutputType, OutputTypes, Externs}; + use super::{Externs, OutputType, OutputTypes}; use rustc_back::{PanicStrategy, RelroLevel}; use syntax::symbol::Symbol; @@ -2271,7 +2448,7 @@ mod tests { for group in super::rustc_optgroups() { (group.apply)(&mut opts); } - return opts + return opts; } fn mk_map(entries: Vec<(K, V)>) -> BTreeMap { @@ -2285,11 +2462,10 @@ mod tests { // When the user supplies --test we should implicitly supply --cfg test #[test] fn test_switch_implies_cfg_test() { - let matches = - &match optgroups().parse(&["--test".to_string()]) { - Ok(m) => m, - Err(f) => panic!("test_switch_implies_cfg_test: {}", f) - }; + let matches = &match optgroups().parse(&["--test".to_string()]) { + Ok(m) => m, + Err(f) => panic!("test_switch_implies_cfg_test: {}", f), + }; let registry = errors::registry::Registry::new(&[]); let (sessopts, cfg) = build_session_options_and_crate_config(matches); let sess = build_session(sessopts, None, registry); @@ -2301,13 +2477,10 @@ mod tests { // another --cfg test #[test] fn test_switch_implies_cfg_test_unless_cfg_test() { - let matches = - &match optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]) { - Ok(m) => m, - Err(f) => { - panic!("test_switch_implies_cfg_test_unless_cfg_test: {}", f) - } - }; + let matches = &match optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]) { + Ok(m) => m, + Err(f) => panic!("test_switch_implies_cfg_test_unless_cfg_test: {}", f), + }; let registry = errors::registry::Registry::new(&[]); let (sessopts, cfg) = build_session_options_and_crate_config(matches); let sess = build_session(sessopts, None, registry); @@ -2320,9 +2493,7 @@ mod tests { #[test] fn test_can_print_warnings() { { - let matches = optgroups().parse(&[ - "-Awarnings".to_string() - ]).unwrap(); + let matches = optgroups().parse(&["-Awarnings".to_string()]).unwrap(); let registry = errors::registry::Registry::new(&[]); let (sessopts, _) = build_session_options_and_crate_config(&matches); let sess = build_session(sessopts, None, registry); @@ -2330,10 +2501,9 @@ mod tests { } { - let matches = optgroups().parse(&[ - "-Awarnings".to_string(), - "-Dwarnings".to_string() - ]).unwrap(); + let matches = optgroups() + .parse(&["-Awarnings".to_string(), "-Dwarnings".to_string()]) + .unwrap(); let registry = errors::registry::Registry::new(&[]); let (sessopts, _) = build_session_options_and_crate_config(&matches); let sess = build_session(sessopts, None, registry); @@ -2341,9 +2511,7 @@ mod tests { } { - let matches = optgroups().parse(&[ - "-Adead_code".to_string() - ]).unwrap(); + let matches = optgroups().parse(&["-Adead_code".to_string()]).unwrap(); let registry = errors::registry::Registry::new(&[]); let (sessopts, _) = build_session_options_and_crate_config(&matches); let sess = build_session(sessopts, None, registry); @@ -2357,10 +2525,10 @@ mod tests { let mut v2 = super::basic_options(); let mut v3 = super::basic_options(); - v1.output_types = OutputTypes::new(&[(OutputType::Exe, - Some(PathBuf::from("./some/thing")))]); - v2.output_types = OutputTypes::new(&[(OutputType::Exe, - Some(PathBuf::from("/some/thing")))]); + v1.output_types = + OutputTypes::new(&[(OutputType::Exe, Some(PathBuf::from("./some/thing")))]); + v2.output_types = + OutputTypes::new(&[(OutputType::Exe, Some(PathBuf::from("/some/thing")))]); v3.output_types = OutputTypes::new(&[(OutputType::Exe, None)]); assert!(v1.dep_tracking_hash() != v2.dep_tracking_hash()); @@ -2401,24 +2569,36 @@ mod tests { let mut v3 = super::basic_options(); v1.externs = Externs::new(mk_map(vec![ - (String::from("a"), mk_set(vec![String::from("b"), - String::from("c")])), - (String::from("d"), mk_set(vec![String::from("e"), - String::from("f")])), + ( + String::from("a"), + mk_set(vec![String::from("b"), String::from("c")]), + ), + ( + String::from("d"), + mk_set(vec![String::from("e"), String::from("f")]), + ), ])); v2.externs = Externs::new(mk_map(vec![ - (String::from("d"), mk_set(vec![String::from("e"), - String::from("f")])), - (String::from("a"), mk_set(vec![String::from("b"), - String::from("c")])), + ( + String::from("d"), + mk_set(vec![String::from("e"), String::from("f")]), + ), + ( + String::from("a"), + mk_set(vec![String::from("b"), String::from("c")]), + ), ])); v3.externs = Externs::new(mk_map(vec![ - (String::from("a"), mk_set(vec![String::from("b"), - String::from("c")])), - (String::from("d"), mk_set(vec![String::from("f"), - String::from("e")])), + ( + String::from("a"), + mk_set(vec![String::from("b"), String::from("c")]), + ), + ( + String::from("d"), + mk_set(vec![String::from("f"), String::from("e")]), + ), ])); assert_eq!(v1.dep_tracking_hash(), v2.dep_tracking_hash()); @@ -2437,20 +2617,26 @@ mod tests { let mut v2 = super::basic_options(); let mut v3 = super::basic_options(); - v1.lint_opts = vec![(String::from("a"), lint::Allow), - (String::from("b"), lint::Warn), - (String::from("c"), lint::Deny), - (String::from("d"), lint::Forbid)]; - - v2.lint_opts = vec![(String::from("a"), lint::Allow), - (String::from("b"), lint::Warn), - (String::from("X"), lint::Deny), - (String::from("d"), lint::Forbid)]; - - v3.lint_opts = vec![(String::from("a"), lint::Allow), - (String::from("b"), lint::Warn), - (String::from("c"), lint::Forbid), - (String::from("d"), lint::Deny)]; + v1.lint_opts = vec![ + (String::from("a"), lint::Allow), + (String::from("b"), lint::Warn), + (String::from("c"), lint::Deny), + (String::from("d"), lint::Forbid), + ]; + + v2.lint_opts = vec![ + (String::from("a"), lint::Allow), + (String::from("b"), lint::Warn), + (String::from("X"), lint::Deny), + (String::from("d"), lint::Forbid), + ]; + + v3.lint_opts = vec![ + (String::from("a"), lint::Allow), + (String::from("b"), lint::Warn), + (String::from("c"), lint::Forbid), + (String::from("d"), lint::Deny), + ]; assert!(v1.dep_tracking_hash() != v2.dep_tracking_hash()); assert!(v1.dep_tracking_hash() != v3.dep_tracking_hash()); @@ -2467,15 +2653,19 @@ mod tests { let mut v1 = super::basic_options(); let mut v2 = super::basic_options(); - v1.lint_opts = vec![(String::from("a"), lint::Allow), - (String::from("b"), lint::Warn), - (String::from("c"), lint::Deny), - (String::from("d"), lint::Forbid)]; + v1.lint_opts = vec![ + (String::from("a"), lint::Allow), + (String::from("b"), lint::Warn), + (String::from("c"), lint::Deny), + (String::from("d"), lint::Forbid), + ]; - v2.lint_opts = vec![(String::from("a"), lint::Allow), - (String::from("c"), lint::Deny), - (String::from("b"), lint::Warn), - (String::from("d"), lint::Forbid)]; + v2.lint_opts = vec![ + (String::from("a"), lint::Allow), + (String::from("c"), lint::Deny), + (String::from("b"), lint::Warn), + (String::from("d"), lint::Forbid), + ]; assert_eq!(v1.dep_tracking_hash(), v2.dep_tracking_hash()); @@ -2492,29 +2682,49 @@ mod tests { let mut v4 = super::basic_options(); // Reference - v1.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false)); - v1.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false)); - v1.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false)); - v1.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false)); - v1.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false)); - - v2.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false)); - v2.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false)); - v2.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false)); - v2.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false)); - v2.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false)); - - v3.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false)); - v3.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false)); - v3.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false)); - v3.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false)); - v3.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false)); - - v4.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false)); - v4.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false)); - v4.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false)); - v4.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false)); - v4.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false)); + v1.search_paths + .add_path("native=abc", super::ErrorOutputType::Json(false)); + v1.search_paths + .add_path("crate=def", super::ErrorOutputType::Json(false)); + v1.search_paths + .add_path("dependency=ghi", super::ErrorOutputType::Json(false)); + v1.search_paths + .add_path("framework=jkl", super::ErrorOutputType::Json(false)); + v1.search_paths + .add_path("all=mno", super::ErrorOutputType::Json(false)); + + v2.search_paths + .add_path("native=abc", super::ErrorOutputType::Json(false)); + v2.search_paths + .add_path("dependency=ghi", super::ErrorOutputType::Json(false)); + v2.search_paths + .add_path("crate=def", super::ErrorOutputType::Json(false)); + v2.search_paths + .add_path("framework=jkl", super::ErrorOutputType::Json(false)); + v2.search_paths + .add_path("all=mno", super::ErrorOutputType::Json(false)); + + v3.search_paths + .add_path("crate=def", super::ErrorOutputType::Json(false)); + v3.search_paths + .add_path("framework=jkl", super::ErrorOutputType::Json(false)); + v3.search_paths + .add_path("native=abc", super::ErrorOutputType::Json(false)); + v3.search_paths + .add_path("dependency=ghi", super::ErrorOutputType::Json(false)); + v3.search_paths + .add_path("all=mno", super::ErrorOutputType::Json(false)); + + v4.search_paths + .add_path("all=mno", super::ErrorOutputType::Json(false)); + v4.search_paths + .add_path("native=abc", super::ErrorOutputType::Json(false)); + v4.search_paths + .add_path("crate=def", super::ErrorOutputType::Json(false)); + v4.search_paths + .add_path("dependency=ghi", super::ErrorOutputType::Json(false)); + v4.search_paths + .add_path("framework=jkl", super::ErrorOutputType::Json(false)); assert!(v1.dep_tracking_hash() == v2.dep_tracking_hash()); assert!(v1.dep_tracking_hash() == v3.dep_tracking_hash()); @@ -2535,24 +2745,36 @@ mod tests { let mut v4 = super::basic_options(); // Reference - v1.libs = vec![(String::from("a"), None, Some(cstore::NativeStatic)), - (String::from("b"), None, Some(cstore::NativeFramework)), - (String::from("c"), None, Some(cstore::NativeUnknown))]; + v1.libs = vec![ + (String::from("a"), None, Some(cstore::NativeStatic)), + (String::from("b"), None, Some(cstore::NativeFramework)), + (String::from("c"), None, Some(cstore::NativeUnknown)), + ]; // Change label - v2.libs = vec![(String::from("a"), None, Some(cstore::NativeStatic)), - (String::from("X"), None, Some(cstore::NativeFramework)), - (String::from("c"), None, Some(cstore::NativeUnknown))]; + v2.libs = vec![ + (String::from("a"), None, Some(cstore::NativeStatic)), + (String::from("X"), None, Some(cstore::NativeFramework)), + (String::from("c"), None, Some(cstore::NativeUnknown)), + ]; // Change kind - v3.libs = vec![(String::from("a"), None, Some(cstore::NativeStatic)), - (String::from("b"), None, Some(cstore::NativeStatic)), - (String::from("c"), None, Some(cstore::NativeUnknown))]; + v3.libs = vec![ + (String::from("a"), None, Some(cstore::NativeStatic)), + (String::from("b"), None, Some(cstore::NativeStatic)), + (String::from("c"), None, Some(cstore::NativeUnknown)), + ]; // Change new-name - v4.libs = vec![(String::from("a"), None, Some(cstore::NativeStatic)), - (String::from("b"), Some(String::from("X")), Some(cstore::NativeFramework)), - (String::from("c"), None, Some(cstore::NativeUnknown))]; + v4.libs = vec![ + (String::from("a"), None, Some(cstore::NativeStatic)), + ( + String::from("b"), + Some(String::from("X")), + Some(cstore::NativeFramework), + ), + (String::from("c"), None, Some(cstore::NativeUnknown)), + ]; assert!(v1.dep_tracking_hash() != v2.dep_tracking_hash()); assert!(v1.dep_tracking_hash() != v3.dep_tracking_hash()); @@ -2572,17 +2794,23 @@ mod tests { let mut v3 = super::basic_options(); // Reference - v1.libs = vec![(String::from("a"), None, Some(cstore::NativeStatic)), - (String::from("b"), None, Some(cstore::NativeFramework)), - (String::from("c"), None, Some(cstore::NativeUnknown))]; - - v2.libs = vec![(String::from("b"), None, Some(cstore::NativeFramework)), - (String::from("a"), None, Some(cstore::NativeStatic)), - (String::from("c"), None, Some(cstore::NativeUnknown))]; - - v3.libs = vec![(String::from("c"), None, Some(cstore::NativeUnknown)), - (String::from("a"), None, Some(cstore::NativeStatic)), - (String::from("b"), None, Some(cstore::NativeFramework))]; + v1.libs = vec![ + (String::from("a"), None, Some(cstore::NativeStatic)), + (String::from("b"), None, Some(cstore::NativeFramework)), + (String::from("c"), None, Some(cstore::NativeUnknown)), + ]; + + v2.libs = vec![ + (String::from("b"), None, Some(cstore::NativeFramework)), + (String::from("a"), None, Some(cstore::NativeStatic)), + (String::from("c"), None, Some(cstore::NativeUnknown)), + ]; + + v3.libs = vec![ + (String::from("c"), None, Some(cstore::NativeUnknown)), + (String::from("a"), None, Some(cstore::NativeStatic)), + (String::from("b"), None, Some(cstore::NativeFramework)), + ]; assert!(v1.dep_tracking_hash() == v2.dep_tracking_hash()); assert!(v1.dep_tracking_hash() == v3.dep_tracking_hash()); @@ -2621,8 +2849,7 @@ mod tests { opts.cg.codegen_units = Some(42); assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); - opts.cg.remark = super::SomePasses(vec![String::from("pass1"), - String::from("pass2")]); + opts.cg.remark = super::SomePasses(vec![String::from("pass1"), String::from("pass2")]); assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); opts.cg.save_temps = true; @@ -2631,7 +2858,6 @@ mod tests { opts.cg.incremental = Some(String::from("abc")); assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); - // Make sure changing a [TRACKED] option changes the hash opts = reference.clone(); opts.cg.lto = Lto::Fat; diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 067e480bd60ed..fe095e3f2d606 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -20,7 +20,7 @@ use lint::builtin::BuiltinLintDiagnostics; use middle::allocator::AllocatorKind; use middle::dependency_format; use session::search_paths::PathKind; -use session::config::{DebugInfoLevel, OutputType, Epoch}; +use session::config::{DebugInfoLevel, Epoch, OutputType}; use ty::tls; use util::nodemap::{FxHashMap, FxHashSet}; use util::common::{duration_to_secs_str, ErrorReported}; @@ -37,7 +37,7 @@ use syntax::parse; use syntax::parse::ParseSess; use syntax::{ast, codemap}; use syntax::feature_gate::AttributeType; -use syntax_pos::{Span, MultiSpan}; +use syntax_pos::{MultiSpan, Span}; use rustc_back::{LinkerFlavor, PanicStrategy}; use rustc_back::target::Target; @@ -87,7 +87,7 @@ pub struct Session { pub plugin_attributes: RefCell>, pub crate_types: RefCell>, pub dependency_formats: RefCell, - /// The crate_disambiguator is constructed out of all the `-C metadata` + /// The crate_disambiguator is constructed out of all the `-C metadata` /// arguments passed to the compiler. Its value together with the crate-name /// forms a unique global identifier for the crate. It is used to allow /// multiple crates with the same name to coexist. See the @@ -136,7 +136,6 @@ pub struct Session { out_of_fuel: Cell, // The next two are public because the driver needs to read them. - /// If -zprint-fuel=crate, Some(crate). pub print_fuel_crate: Option, /// Always set to zero and incremented so that we can print fuel expended by a crate. @@ -170,7 +169,7 @@ enum DiagnosticBuilderMethod { Note, SpanNote, SpanSuggestion(String), // suggestion - // add more variants as needed to support one-time diagnostics + // add more variants as needed to support one-time diagnostics } /// Diagnostic message ID—used by `Session.one_time_diagnostics` to avoid @@ -179,7 +178,7 @@ enum DiagnosticBuilderMethod { pub enum DiagnosticMessageId { ErrorId(u16), // EXXXX error code as integer LintId(lint::LintId), - StabilityId(u32) // issue number + StabilityId(u32), // issue number } impl From<&'static lint::Lint> for DiagnosticMessageId { @@ -196,33 +195,37 @@ impl Session { } } - pub fn struct_span_warn<'a, S: Into>(&'a self, - sp: S, - msg: &str) - -> DiagnosticBuilder<'a> { + pub fn struct_span_warn<'a, S: Into>( + &'a self, + sp: S, + msg: &str, + ) -> DiagnosticBuilder<'a> { self.diagnostic().struct_span_warn(sp, msg) } - pub fn struct_span_warn_with_code<'a, S: Into>(&'a self, - sp: S, - msg: &str, - code: DiagnosticId) - -> DiagnosticBuilder<'a> { + pub fn struct_span_warn_with_code<'a, S: Into>( + &'a self, + sp: S, + msg: &str, + code: DiagnosticId, + ) -> DiagnosticBuilder<'a> { self.diagnostic().struct_span_warn_with_code(sp, msg, code) } - pub fn struct_warn<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { + pub fn struct_warn<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { self.diagnostic().struct_warn(msg) } - pub fn struct_span_err<'a, S: Into>(&'a self, - sp: S, - msg: &str) - -> DiagnosticBuilder<'a> { + pub fn struct_span_err<'a, S: Into>( + &'a self, + sp: S, + msg: &str, + ) -> DiagnosticBuilder<'a> { self.diagnostic().struct_span_err(sp, msg) } - pub fn struct_span_err_with_code<'a, S: Into>(&'a self, - sp: S, - msg: &str, - code: DiagnosticId) - -> DiagnosticBuilder<'a> { + pub fn struct_span_err_with_code<'a, S: Into>( + &'a self, + sp: S, + msg: &str, + code: DiagnosticId, + ) -> DiagnosticBuilder<'a> { self.diagnostic().struct_span_err_with_code(sp, msg, code) } // FIXME: This method should be removed (every error should have an associated error code). @@ -236,20 +239,22 @@ impl Session { ) -> DiagnosticBuilder<'a> { self.diagnostic().struct_err_with_code(msg, code) } - pub fn struct_span_fatal<'a, S: Into>(&'a self, - sp: S, - msg: &str) - -> DiagnosticBuilder<'a> { + pub fn struct_span_fatal<'a, S: Into>( + &'a self, + sp: S, + msg: &str, + ) -> DiagnosticBuilder<'a> { self.diagnostic().struct_span_fatal(sp, msg) } - pub fn struct_span_fatal_with_code<'a, S: Into>(&'a self, - sp: S, - msg: &str, - code: DiagnosticId) - -> DiagnosticBuilder<'a> { + pub fn struct_span_fatal_with_code<'a, S: Into>( + &'a self, + sp: S, + msg: &str, + code: DiagnosticId, + ) -> DiagnosticBuilder<'a> { self.diagnostic().struct_span_fatal_with_code(sp, msg, code) } - pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { + pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { self.diagnostic().struct_fatal(msg) } @@ -262,7 +267,9 @@ impl Session { msg: &str, code: DiagnosticId, ) -> ! { - self.diagnostic().span_fatal_with_code(sp, msg, code).raise() + self.diagnostic() + .span_fatal_with_code(sp, msg, code) + .raise() } pub fn fatal(&self, msg: &str) -> ! { self.diagnostic().fatal(msg).raise() @@ -296,7 +303,8 @@ impl Session { compile_result_from_err_count(self.err_count()) } pub fn track_errors(&self, f: F) -> Result - where F: FnOnce() -> T + where + F: FnOnce() -> T, { let old_count = self.err_count(); let result = f(); @@ -339,24 +347,31 @@ impl Session { self.diagnostic().unimpl(msg) } - pub fn buffer_lint>(&self, - lint: &'static lint::Lint, - id: ast::NodeId, - sp: S, - msg: &str) { + pub fn buffer_lint>( + &self, + lint: &'static lint::Lint, + id: ast::NodeId, + sp: S, + msg: &str, + ) { match *self.buffered_lints.borrow_mut() { - Some(ref mut buffer) => buffer.add_lint(lint, id, sp.into(), - msg, BuiltinLintDiagnostics::Normal), + Some(ref mut buffer) => { + buffer.add_lint(lint, id, sp.into(), msg, BuiltinLintDiagnostics::Normal) + } None => bug!("can't buffer lints after HIR lowering"), } } - pub fn buffer_lint_with_diagnostic>(&self, - lint: &'static lint::Lint, id: ast::NodeId, sp: S, - msg: &str, diagnostic: BuiltinLintDiagnostics) { + pub fn buffer_lint_with_diagnostic>( + &self, + lint: &'static lint::Lint, + id: ast::NodeId, + sp: S, + msg: &str, + diagnostic: BuiltinLintDiagnostics, + ) { match *self.buffered_lints.borrow_mut() { - Some(ref mut buffer) => buffer.add_lint(lint, id, sp.into(), - msg, diagnostic), + Some(ref mut buffer) => buffer.add_lint(lint, id, sp.into(), msg, diagnostic), None => bug!("can't buffer lints after HIR lowering"), } } @@ -368,7 +383,7 @@ impl Session { Some(next) => { self.next_node_id.set(ast::NodeId::new(next)); } - None => bug!("Input too large, ran out of node ids!") + None => bug!("Input too large, ran out of node ids!"), } id @@ -382,24 +397,27 @@ impl Session { /// Analogous to calling methods on the given `DiagnosticBuilder`, but /// deduplicates on lint ID, span (if any), and message for this `Session` - fn diag_once<'a, 'b>(&'a self, - diag_builder: &'b mut DiagnosticBuilder<'a>, - method: DiagnosticBuilderMethod, - msg_id: DiagnosticMessageId, - message: &str, - span_maybe: Option) { - + fn diag_once<'a, 'b>( + &'a self, + diag_builder: &'b mut DiagnosticBuilder<'a>, + method: DiagnosticBuilderMethod, + msg_id: DiagnosticMessageId, + message: &str, + span_maybe: Option, + ) { let id_span_message = (msg_id, span_maybe, message.to_owned()); - let fresh = self.one_time_diagnostics.borrow_mut().insert(id_span_message); + let fresh = self.one_time_diagnostics + .borrow_mut() + .insert(id_span_message); if fresh { match method { DiagnosticBuilderMethod::Note => { diag_builder.note(message); - }, + } DiagnosticBuilderMethod::SpanNote => { let span = span_maybe.expect("span_note needs a span"); diag_builder.span_note(span, message); - }, + } DiagnosticBuilderMethod::SpanSuggestion(suggestion) => { let span = span_maybe.expect("span_suggestion needs a span"); diag_builder.span_suggestion(span, message, suggestion); @@ -408,37 +426,66 @@ impl Session { } } - pub fn diag_span_note_once<'a, 'b>(&'a self, - diag_builder: &'b mut DiagnosticBuilder<'a>, - msg_id: DiagnosticMessageId, span: Span, message: &str) { - self.diag_once(diag_builder, DiagnosticBuilderMethod::SpanNote, - msg_id, message, Some(span)); - } - - pub fn diag_note_once<'a, 'b>(&'a self, - diag_builder: &'b mut DiagnosticBuilder<'a>, - msg_id: DiagnosticMessageId, message: &str) { - self.diag_once(diag_builder, DiagnosticBuilderMethod::Note, msg_id, message, None); - } - - pub fn diag_span_suggestion_once<'a, 'b>(&'a self, - diag_builder: &'b mut DiagnosticBuilder<'a>, - msg_id: DiagnosticMessageId, - span: Span, - message: &str, - suggestion: String) { - self.diag_once(diag_builder, DiagnosticBuilderMethod::SpanSuggestion(suggestion), - msg_id, message, Some(span)); + pub fn diag_span_note_once<'a, 'b>( + &'a self, + diag_builder: &'b mut DiagnosticBuilder<'a>, + msg_id: DiagnosticMessageId, + span: Span, + message: &str, + ) { + self.diag_once( + diag_builder, + DiagnosticBuilderMethod::SpanNote, + msg_id, + message, + Some(span), + ); + } + + pub fn diag_note_once<'a, 'b>( + &'a self, + diag_builder: &'b mut DiagnosticBuilder<'a>, + msg_id: DiagnosticMessageId, + message: &str, + ) { + self.diag_once( + diag_builder, + DiagnosticBuilderMethod::Note, + msg_id, + message, + None, + ); + } + + pub fn diag_span_suggestion_once<'a, 'b>( + &'a self, + diag_builder: &'b mut DiagnosticBuilder<'a>, + msg_id: DiagnosticMessageId, + span: Span, + message: &str, + suggestion: String, + ) { + self.diag_once( + diag_builder, + DiagnosticBuilderMethod::SpanSuggestion(suggestion), + msg_id, + message, + Some(span), + ); } pub fn codemap<'a>(&'a self) -> &'a codemap::CodeMap { self.parse_sess.codemap() } - pub fn verbose(&self) -> bool { self.opts.debugging_opts.verbose } - pub fn time_passes(&self) -> bool { self.opts.debugging_opts.time_passes } + pub fn verbose(&self) -> bool { + self.opts.debugging_opts.verbose + } + pub fn time_passes(&self) -> bool { + self.opts.debugging_opts.time_passes + } pub fn profile_queries(&self) -> bool { - self.opts.debugging_opts.profile_queries || - self.opts.debugging_opts.profile_queries_and_keys + self.opts.debugging_opts.profile_queries + || self.opts.debugging_opts.profile_queries_and_keys } pub fn profile_queries_and_keys(&self) -> bool { self.opts.debugging_opts.profile_queries_and_keys @@ -449,11 +496,21 @@ impl Session { pub fn time_llvm_passes(&self) -> bool { self.opts.debugging_opts.time_llvm_passes } - pub fn trans_stats(&self) -> bool { self.opts.debugging_opts.trans_stats } - pub fn meta_stats(&self) -> bool { self.opts.debugging_opts.meta_stats } - pub fn asm_comments(&self) -> bool { self.opts.debugging_opts.asm_comments } - pub fn no_verify(&self) -> bool { self.opts.debugging_opts.no_verify } - pub fn borrowck_stats(&self) -> bool { self.opts.debugging_opts.borrowck_stats } + pub fn trans_stats(&self) -> bool { + self.opts.debugging_opts.trans_stats + } + pub fn meta_stats(&self) -> bool { + self.opts.debugging_opts.meta_stats + } + pub fn asm_comments(&self) -> bool { + self.opts.debugging_opts.asm_comments + } + pub fn no_verify(&self) -> bool { + self.opts.debugging_opts.no_verify + } + pub fn borrowck_stats(&self) -> bool { + self.opts.debugging_opts.borrowck_stats + } pub fn print_llvm_passes(&self) -> bool { self.opts.debugging_opts.print_llvm_passes } @@ -480,7 +537,7 @@ impl Session { pub fn lto(&self) -> config::Lto { // If our target has codegen requirements ignore the command line if self.target.target.options.requires_lto { - return config::Lto::Fat + return config::Lto::Fat; } // If the user specified something, return that. If they only said `-C @@ -488,9 +545,7 @@ impl Session { // then ensure we can't use a ThinLTO. match self.opts.cg.lto { config::Lto::No => {} - config::Lto::Yes if self.opts.cli_forced_thinlto_off => { - return config::Lto::Fat - } + config::Lto::Yes if self.opts.cli_forced_thinlto_off => return config::Lto::Fat, other => return other, } @@ -503,28 +558,28 @@ impl Session { // If processing command line options determined that we're incompatible // with ThinLTO (e.g. `-C lto --emit llvm-ir`) then return that option. if self.opts.cli_forced_thinlto_off { - return config::Lto::No + return config::Lto::No; } // If `-Z thinlto` specified process that, but note that this is mostly // a deprecated option now that `-C lto=thin` exists. if let Some(enabled) = self.opts.debugging_opts.thinlto { if enabled { - return config::Lto::ThinLocal + return config::Lto::ThinLocal; } else { - return config::Lto::No + return config::Lto::No; } } // If there's only one codegen unit and LTO isn't enabled then there's // no need for ThinLTO so just return false. if self.codegen_units() == 1 { - return config::Lto::No + return config::Lto::No; } // Right now ThinLTO isn't compatible with incremental compilation. if self.opts.incremental.is_some() { - return config::Lto::No + return config::Lto::No; } // Now we're in "defaults" territory. By default we enable ThinLTO for @@ -538,15 +593,23 @@ impl Session { /// Returns the panic strategy for this compile session. If the user explicitly selected one /// using '-C panic', use that, otherwise use the panic strategy defined by the target. pub fn panic_strategy(&self) -> PanicStrategy { - self.opts.cg.panic.unwrap_or(self.target.target.options.panic_strategy) + self.opts + .cg + .panic + .unwrap_or(self.target.target.options.panic_strategy) } pub fn linker_flavor(&self) -> LinkerFlavor { - self.opts.debugging_opts.linker_flavor.unwrap_or(self.target.target.linker_flavor) + self.opts + .debugging_opts + .linker_flavor + .unwrap_or(self.target.target.linker_flavor) } pub fn fewer_names(&self) -> bool { - let more_names = self.opts.output_types.contains_key(&OutputType::LlvmAssembly) || - self.opts.output_types.contains_key(&OutputType::Bitcode); + let more_names = self.opts + .output_types + .contains_key(&OutputType::LlvmAssembly) + || self.opts.output_types.contains_key(&OutputType::Bitcode); self.opts.debugging_opts.fewer_names || !more_names } @@ -560,7 +623,9 @@ impl Session { self.opts.debugging_opts.enable_nonzeroing_move_hints } pub fn overflow_checks(&self) -> bool { - self.opts.cg.overflow_checks + self.opts + .cg + .overflow_checks .or(self.opts.debugging_opts.force_overflow_checks) .unwrap_or(self.opts.debug_assertions) } @@ -591,50 +656,59 @@ impl Session { } pub fn must_not_eliminate_frame_pointers(&self) -> bool { - self.opts.debuginfo != DebugInfoLevel::NoDebugInfo || - !self.target.target.options.eliminate_frame_pointer + self.opts.debuginfo != DebugInfoLevel::NoDebugInfo + || !self.target.target.options.eliminate_frame_pointer } /// Returns the symbol name for the registrar function, /// given the crate Svh and the function DefIndex. - pub fn generate_plugin_registrar_symbol(&self, - disambiguator: CrateDisambiguator) - -> String { - format!("__rustc_plugin_registrar_{}__", disambiguator.to_fingerprint().to_hex()) + pub fn generate_plugin_registrar_symbol(&self, disambiguator: CrateDisambiguator) -> String { + format!( + "__rustc_plugin_registrar_{}__", + disambiguator.to_fingerprint().to_hex() + ) } - pub fn generate_derive_registrar_symbol(&self, - disambiguator: CrateDisambiguator) - -> String { - format!("__rustc_derive_registrar_{}__", disambiguator.to_fingerprint().to_hex()) + pub fn generate_derive_registrar_symbol(&self, disambiguator: CrateDisambiguator) -> String { + format!( + "__rustc_derive_registrar_{}__", + disambiguator.to_fingerprint().to_hex() + ) } pub fn sysroot<'a>(&'a self) -> &'a Path { match self.opts.maybe_sysroot { - Some (ref sysroot) => sysroot, - None => self.default_sysroot.as_ref() - .expect("missing sysroot and default_sysroot in Session") + Some(ref sysroot) => sysroot, + None => self.default_sysroot + .as_ref() + .expect("missing sysroot and default_sysroot in Session"), } } pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch { - filesearch::FileSearch::new(self.sysroot(), - &self.opts.target_triple, - &self.opts.search_paths, - kind) + filesearch::FileSearch::new( + self.sysroot(), + &self.opts.target_triple, + &self.opts.search_paths, + kind, + ) } pub fn host_filesearch(&self, kind: PathKind) -> filesearch::FileSearch { filesearch::FileSearch::new( self.sysroot(), config::host_triple(), &self.opts.search_paths, - kind) + kind, + ) } pub fn set_incr_session_load_dep_graph(&self, load: bool) { let mut incr_comp_session = self.incr_comp_session.borrow_mut(); match *incr_comp_session { - IncrCompSession::Active { ref mut load_dep_graph, .. } => { + IncrCompSession::Active { + ref mut load_dep_graph, + .. + } => { *load_dep_graph = load; } _ => {} @@ -649,14 +723,20 @@ impl Session { } } - pub fn init_incr_comp_session(&self, - session_dir: PathBuf, - lock_file: flock::Lock, - load_dep_graph: bool) { + pub fn init_incr_comp_session( + &self, + session_dir: PathBuf, + lock_file: flock::Lock, + load_dep_graph: bool, + ) { let mut incr_comp_session = self.incr_comp_session.borrow_mut(); - if let IncrCompSession::NotInitialized = *incr_comp_session { } else { - bug!("Trying to initialize IncrCompSession `{:?}`", *incr_comp_session) + if let IncrCompSession::NotInitialized = *incr_comp_session { + } else { + bug!( + "Trying to initialize IncrCompSession `{:?}`", + *incr_comp_session + ) } *incr_comp_session = IncrCompSession::Active { @@ -669,8 +749,12 @@ impl Session { pub fn finalize_incr_comp_session(&self, new_directory_path: PathBuf) { let mut incr_comp_session = self.incr_comp_session.borrow_mut(); - if let IncrCompSession::Active { .. } = *incr_comp_session { } else { - bug!("Trying to finalize IncrCompSession `{:?}`", *incr_comp_session) + if let IncrCompSession::Active { .. } = *incr_comp_session { + } else { + bug!( + "Trying to finalize IncrCompSession `{:?}`", + *incr_comp_session + ) } // Note: This will also drop the lock file, thus unlocking the directory @@ -683,35 +767,42 @@ impl Session { let mut incr_comp_session = self.incr_comp_session.borrow_mut(); let session_directory = match *incr_comp_session { - IncrCompSession::Active { ref session_directory, .. } => { - session_directory.clone() - } + IncrCompSession::Active { + ref session_directory, + .. + } => session_directory.clone(), IncrCompSession::InvalidBecauseOfErrors { .. } => return, - _ => bug!("Trying to invalidate IncrCompSession `{:?}`", - *incr_comp_session), + _ => bug!( + "Trying to invalidate IncrCompSession `{:?}`", + *incr_comp_session + ), }; // Note: This will also drop the lock file, thus unlocking the directory - *incr_comp_session = IncrCompSession::InvalidBecauseOfErrors { - session_directory, - }; + *incr_comp_session = IncrCompSession::InvalidBecauseOfErrors { session_directory }; } pub fn incr_comp_session_dir(&self) -> cell::Ref { let incr_comp_session = self.incr_comp_session.borrow(); - cell::Ref::map(incr_comp_session, |incr_comp_session| { - match *incr_comp_session { - IncrCompSession::NotInitialized => { - bug!("Trying to get session directory from IncrCompSession `{:?}`", - *incr_comp_session) + cell::Ref::map( + incr_comp_session, + |incr_comp_session| match *incr_comp_session { + IncrCompSession::NotInitialized => bug!( + "Trying to get session directory from IncrCompSession `{:?}`", + *incr_comp_session + ), + IncrCompSession::Active { + ref session_directory, + .. } - IncrCompSession::Active { ref session_directory, .. } | - IncrCompSession::Finalized { ref session_directory } | - IncrCompSession::InvalidBecauseOfErrors { ref session_directory } => { - session_directory + | IncrCompSession::Finalized { + ref session_directory, } - } - }) + | IncrCompSession::InvalidBecauseOfErrors { + ref session_directory, + } => session_directory, + }, + ) } pub fn incr_comp_session_dir_opt(&self) -> Option> { @@ -723,25 +814,39 @@ impl Session { } pub fn print_perf_stats(&self) { - println!("Total time spent computing SVHs: {}", - duration_to_secs_str(self.perf_stats.svh_time.get())); - println!("Total time spent computing incr. comp. hashes: {}", - duration_to_secs_str(self.perf_stats.incr_comp_hashes_time.get())); - println!("Total number of incr. comp. hashes computed: {}", - self.perf_stats.incr_comp_hashes_count.get()); - println!("Total number of bytes hashed for incr. comp.: {}", - self.perf_stats.incr_comp_bytes_hashed.get()); + println!( + "Total time spent computing SVHs: {}", + duration_to_secs_str(self.perf_stats.svh_time.get()) + ); + println!( + "Total time spent computing incr. comp. hashes: {}", + duration_to_secs_str(self.perf_stats.incr_comp_hashes_time.get()) + ); + println!( + "Total number of incr. comp. hashes computed: {}", + self.perf_stats.incr_comp_hashes_count.get() + ); + println!( + "Total number of bytes hashed for incr. comp.: {}", + self.perf_stats.incr_comp_bytes_hashed.get() + ); if self.perf_stats.incr_comp_hashes_count.get() != 0 { - println!("Average bytes hashed per incr. comp. HIR node: {}", - self.perf_stats.incr_comp_bytes_hashed.get() / - self.perf_stats.incr_comp_hashes_count.get()); + println!( + "Average bytes hashed per incr. comp. HIR node: {}", + self.perf_stats.incr_comp_bytes_hashed.get() + / self.perf_stats.incr_comp_hashes_count.get() + ); } else { println!("Average bytes hashed per incr. comp. HIR node: N/A"); } - println!("Total time spent computing symbol hashes: {}", - duration_to_secs_str(self.perf_stats.symbol_hash_time.get())); - println!("Total time spent decoding DefPath tables: {}", - duration_to_secs_str(self.perf_stats.decode_def_path_tables_time.get())); + println!( + "Total time spent computing symbol hashes: {}", + duration_to_secs_str(self.perf_stats.symbol_hash_time.get()) + ); + println!( + "Total time spent decoding DefPath tables: {}", + duration_to_secs_str(self.perf_stats.decode_def_path_tables_time.get()) + ); } /// We want to know if we're allowed to do an optimization for crate foo from -z fuel=foo=n. @@ -756,15 +861,15 @@ impl Session { println!("optimization-fuel-exhausted: {}", msg()); self.out_of_fuel.set(true); } else if fuel > 0 { - self.optimization_fuel_limit.set(fuel-1); + self.optimization_fuel_limit.set(fuel - 1); } } _ => {} } match self.print_fuel_crate { - Some(ref c) if c == crate_name=> { - self.print_fuel.set(self.print_fuel.get()+1); - }, + Some(ref c) if c == crate_name => { + self.print_fuel.set(self.print_fuel.get() + 1); + } _ => {} } ret @@ -780,10 +885,10 @@ impl Session { /// compilation pub fn codegen_units(&self) -> usize { if let Some(n) = self.opts.cli_forced_codegen_units { - return n + return n; } if let Some(n) = self.target.target.options.default_codegen_units { - return n as usize + return n as usize; } // Why is 16 codegen units the default all the time? @@ -853,29 +958,34 @@ impl Session { } } -pub fn build_session(sopts: config::Options, - local_crate_source_file: Option, - registry: errors::registry::Registry) - -> Session { +pub fn build_session( + sopts: config::Options, + local_crate_source_file: Option, + registry: errors::registry::Registry, +) -> Session { let file_path_mapping = sopts.file_path_mapping(); - build_session_with_codemap(sopts, - local_crate_source_file, - registry, - Lrc::new(codemap::CodeMap::new(file_path_mapping)), - None) + build_session_with_codemap( + sopts, + local_crate_source_file, + registry, + Lrc::new(codemap::CodeMap::new(file_path_mapping)), + None, + ) } -pub fn build_session_with_codemap(sopts: config::Options, - local_crate_source_file: Option, - registry: errors::registry::Registry, - codemap: Lrc, - emitter_dest: Option>) - -> Session { +pub fn build_session_with_codemap( + sopts: config::Options, + local_crate_source_file: Option, + registry: errors::registry::Registry, + codemap: Lrc, + emitter_dest: Option>, +) -> Session { // FIXME: This is not general enough to make the warning lint completely override // normal diagnostic warnings, since the warning lint can also be denied and changed // later via the source code. - let warnings_allow = sopts.lint_opts + let warnings_allow = sopts + .lint_opts .iter() .filter(|&&(ref key, _)| *key == "warnings") .map(|&(_, ref level)| *level == lint::Allow) @@ -889,60 +999,70 @@ pub fn build_session_with_codemap(sopts: config::Options, let external_macro_backtrace = sopts.debugging_opts.external_macro_backtrace; - let emitter: Box = match (sopts.error_format, emitter_dest) { - (config::ErrorOutputType::HumanReadable(color_config), None) => { - Box::new(EmitterWriter::stderr(color_config, Some(codemap.clone()), - false, sopts.debugging_opts.teach) - .ui_testing(sopts.debugging_opts.ui_testing)) - } - (config::ErrorOutputType::HumanReadable(_), Some(dst)) => { - Box::new(EmitterWriter::new(dst, Some(codemap.clone()), - false, false) - .ui_testing(sopts.debugging_opts.ui_testing)) - } - (config::ErrorOutputType::Json(pretty), None) => { - Box::new(JsonEmitter::stderr(Some(registry), codemap.clone(), - pretty, sopts.debugging_opts.approximate_suggestions) - .ui_testing(sopts.debugging_opts.ui_testing)) - } - (config::ErrorOutputType::Json(pretty), Some(dst)) => { - Box::new(JsonEmitter::new(dst, Some(registry), codemap.clone(), - pretty, sopts.debugging_opts.approximate_suggestions) - .ui_testing(sopts.debugging_opts.ui_testing)) - } - (config::ErrorOutputType::Short(color_config), None) => { - Box::new(EmitterWriter::stderr(color_config, Some(codemap.clone()), true, false)) - } - (config::ErrorOutputType::Short(_), Some(dst)) => { - Box::new(EmitterWriter::new(dst, Some(codemap.clone()), true, false)) - } - }; + let emitter: Box = + match (sopts.error_format, emitter_dest) { + (config::ErrorOutputType::HumanReadable(color_config), None) => Box::new( + EmitterWriter::stderr( + color_config, + Some(codemap.clone()), + false, + sopts.debugging_opts.teach, + ).ui_testing(sopts.debugging_opts.ui_testing), + ), + (config::ErrorOutputType::HumanReadable(_), Some(dst)) => Box::new( + EmitterWriter::new(dst, Some(codemap.clone()), false, false) + .ui_testing(sopts.debugging_opts.ui_testing), + ), + (config::ErrorOutputType::Json(pretty), None) => Box::new( + JsonEmitter::stderr( + Some(registry), + codemap.clone(), + pretty, + sopts.debugging_opts.approximate_suggestions, + ).ui_testing(sopts.debugging_opts.ui_testing), + ), + (config::ErrorOutputType::Json(pretty), Some(dst)) => Box::new( + JsonEmitter::new( + dst, + Some(registry), + codemap.clone(), + pretty, + sopts.debugging_opts.approximate_suggestions, + ).ui_testing(sopts.debugging_opts.ui_testing), + ), + (config::ErrorOutputType::Short(color_config), None) => Box::new( + EmitterWriter::stderr(color_config, Some(codemap.clone()), true, false), + ), + (config::ErrorOutputType::Short(_), Some(dst)) => { + Box::new(EmitterWriter::new(dst, Some(codemap.clone()), true, false)) + } + }; - let diagnostic_handler = - errors::Handler::with_emitter_and_flags( - emitter, - errors::HandlerFlags { - can_emit_warnings, - treat_err_as_bug, - external_macro_backtrace, - .. Default::default() - }); + let diagnostic_handler = errors::Handler::with_emitter_and_flags( + emitter, + errors::HandlerFlags { + can_emit_warnings, + treat_err_as_bug, + external_macro_backtrace, + ..Default::default() + }, + ); - build_session_(sopts, - local_crate_source_file, - diagnostic_handler, - codemap) + build_session_(sopts, local_crate_source_file, diagnostic_handler, codemap) } -pub fn build_session_(sopts: config::Options, - local_crate_source_file: Option, - span_diagnostic: errors::Handler, - codemap: Lrc) - -> Session { +pub fn build_session_( + sopts: config::Options, + local_crate_source_file: Option, + span_diagnostic: errors::Handler, + codemap: Lrc, +) -> Session { let host = match Target::search(config::host_triple()) { Ok(t) => t, Err(e) => { - span_diagnostic.fatal(&format!("Error loading host specification: {}", e)).raise(); + span_diagnostic + .fatal(&format!("Error loading host specification: {}", e)) + .raise(); } }; let target_cfg = config::build_target_config(&sopts, &span_diagnostic); @@ -950,26 +1070,25 @@ pub fn build_session_(sopts: config::Options, let p_s = parse::ParseSess::with_span_handler(span_diagnostic, codemap); let default_sysroot = match sopts.maybe_sysroot { Some(_) => None, - None => Some(filesearch::get_or_default_sysroot()) + None => Some(filesearch::get_or_default_sysroot()), }; let file_path_mapping = sopts.file_path_mapping(); - let local_crate_source_file = local_crate_source_file.map(|path| { - file_path_mapping.map_prefix(path).0 - }); + let local_crate_source_file = + local_crate_source_file.map(|path| file_path_mapping.map_prefix(path).0); let optimization_fuel_crate = sopts.debugging_opts.fuel.as_ref().map(|i| i.0.clone()); - let optimization_fuel_limit = Cell::new(sopts.debugging_opts.fuel.as_ref() - .map(|i| i.1).unwrap_or(0)); + let optimization_fuel_limit = + Cell::new(sopts.debugging_opts.fuel.as_ref().map(|i| i.1).unwrap_or(0)); let print_fuel_crate = sopts.debugging_opts.print_fuel.clone(); let print_fuel = Cell::new(0); let working_dir = match env::current_dir() { Ok(dir) => dir, - Err(e) => { - p_s.span_diagnostic.fatal(&format!("Current directory is invalid: {}", e)).raise() - } + Err(e) => p_s.span_diagnostic + .fatal(&format!("Current directory is invalid: {}", e)) + .raise(), }; let working_dir = file_path_mapping.map_prefix(working_dir); @@ -1076,15 +1195,11 @@ pub enum IncrCompSession { }, /// This is the state after the session directory has been finalized. In this /// state, the contents of the directory must not be modified any more. - Finalized { - session_directory: PathBuf, - }, + Finalized { session_directory: PathBuf }, /// This is an error state that is reached when some compilation error has /// occurred. It indicates that the contents of the session directory must /// not be used, since they might be invalid. - InvalidBecauseOfErrors { - session_directory: PathBuf, - } + InvalidBecauseOfErrors { session_directory: PathBuf }, } pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! { @@ -1119,7 +1234,7 @@ pub fn early_warn(output: config::ErrorOutputType, msg: &str) { #[derive(Copy, Clone, Debug)] pub enum CompileIncomplete { Stopped, - Errored(ErrorReported) + Errored(ErrorReported), } impl From for CompileIncomplete { fn from(err: ErrorReported) -> CompileIncomplete { @@ -1146,23 +1261,27 @@ pub fn bug_fmt(file: &'static str, line: u32, args: fmt::Arguments) -> ! { #[cold] #[inline(never)] -pub fn span_bug_fmt>(file: &'static str, - line: u32, - span: S, - args: fmt::Arguments) -> ! { +pub fn span_bug_fmt>( + file: &'static str, + line: u32, + span: S, + args: fmt::Arguments, +) -> ! { opt_span_bug_fmt(file, line, Some(span), args); } -fn opt_span_bug_fmt>(file: &'static str, - line: u32, - span: Option, - args: fmt::Arguments) -> ! { +fn opt_span_bug_fmt>( + file: &'static str, + line: u32, + span: Option, + args: fmt::Arguments, +) -> ! { tls::with_opt(move |tcx| { let msg = format!("{}:{}: {}", file, line, args); match (tcx, span) { (Some(tcx), Some(span)) => tcx.sess.diagnostic().span_bug(span, &msg), (Some(tcx), None) => tcx.sess.diagnostic().bug(&msg), - (None, _) => panic!(msg) + (None, _) => panic!(msg), } }); unreachable!(); diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index cfa1890e182ea..77a3f138fe590 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -268,8 +268,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { "mutable", ) { (BorrowKind::Shared, lft, _, BorrowKind::Mut { .. }, _, rgt) - | (BorrowKind::Mut { .. }, _, lft, BorrowKind::Shared, rgt, _) => tcx - .cannot_reborrow_already_borrowed( + | (BorrowKind::Mut { .. }, _, lft, BorrowKind::Shared, rgt, _) => { + tcx.cannot_reborrow_already_borrowed( span, &desc_place, "", @@ -280,10 +280,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { "", end_issued_loan_span, Origin::Mir, - ), + ) + } - (BorrowKind::Mut { .. }, _, _, BorrowKind::Mut { .. }, _, _) => tcx - .cannot_mutably_borrow_multiply( + (BorrowKind::Mut { .. }, _, _, BorrowKind::Mut { .. }, _, _) => { + tcx.cannot_mutably_borrow_multiply( span, &desc_place, "", @@ -291,16 +292,18 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { "", end_issued_loan_span, Origin::Mir, - ), + ) + } - (BorrowKind::Unique, _, _, BorrowKind::Unique, _, _) => tcx - .cannot_uniquely_borrow_by_two_closures( + (BorrowKind::Unique, _, _, BorrowKind::Unique, _, _) => { + tcx.cannot_uniquely_borrow_by_two_closures( span, &desc_place, issued_span, end_issued_loan_span, Origin::Mir, - ), + ) + } (BorrowKind::Unique, _, _, _, _, _) => tcx.cannot_uniquely_borrow_by_one_closure( span, @@ -313,8 +316,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Origin::Mir, ), - (BorrowKind::Shared, lft, _, BorrowKind::Unique, _, _) => tcx - .cannot_reborrow_already_uniquely_borrowed( + (BorrowKind::Shared, lft, _, BorrowKind::Unique, _, _) => { + tcx.cannot_reborrow_already_uniquely_borrowed( span, &desc_place, "", @@ -323,10 +326,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { "", end_issued_loan_span, Origin::Mir, - ), + ) + } - (BorrowKind::Mut { .. }, _, lft, BorrowKind::Unique, _, _) => tcx - .cannot_reborrow_already_uniquely_borrowed( + (BorrowKind::Mut { .. }, _, lft, BorrowKind::Unique, _, _) => { + tcx.cannot_reborrow_already_uniquely_borrowed( span, &desc_place, "", @@ -335,7 +339,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { "", end_issued_loan_span, Origin::Mir, - ), + ) + } (BorrowKind::Shared, _, _, BorrowKind::Shared, _, _) => unreachable!(), }; @@ -470,11 +475,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { end_span: Option, ) { let tcx = self.tcx; - let mut err = tcx.path_does_not_live_long_enough( - borrow_span, - &format!("`{}`", name), - Origin::Mir, - ); + let mut err = + tcx.path_does_not_live_long_enough(borrow_span, &format!("`{}`", name), Origin::Mir); err.span_label(borrow_span, "borrowed value does not live long enough"); err.span_label( drop_span, @@ -532,11 +534,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ); let tcx = self.tcx; - let mut err = tcx.path_does_not_live_long_enough( - borrow_span, - &format!("`{}`", name), - Origin::Mir, - ); + let mut err = + tcx.path_does_not_live_long_enough(borrow_span, &format!("`{}`", name), Origin::Mir); err.span_label(borrow_span, "borrowed value does not live long enough"); err.span_label(drop_span, "borrowed value only lives until here"); diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 06412a386e84a..56a4b44ac75ac 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -10,7 +10,7 @@ //! This query borrow-checks the MIR to (further) ensure it is not broken. -use borrow_check::nll::region_infer::{RegionInferenceContext, RegionCausalInfo}; +use borrow_check::nll::region_infer::{RegionCausalInfo, RegionInferenceContext}; use rustc::hir; use rustc::hir::def_id::DefId; use rustc::hir::map::definitions::DefPathData; @@ -339,9 +339,7 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx ) { debug!( "MirBorrowckCtxt::process_statement({:?}, {:?}): {}", - location, - stmt, - flow_state + location, stmt, flow_state ); let span = stmt.source_info.span; @@ -443,9 +441,7 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx let loc = location; debug!( "MirBorrowckCtxt::process_terminator({:?}, {:?}): {}", - location, - term, - flow_state + location, term, flow_state ); let span = term.source_info.span; @@ -584,8 +580,14 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx TerminatorKind::Goto { target: _ } | TerminatorKind::Abort | TerminatorKind::Unreachable - | TerminatorKind::FalseEdges { real_target: _, imaginary_targets: _ } - | TerminatorKind::FalseUnwind { real_target: _, unwind: _ } => { + | TerminatorKind::FalseEdges { + real_target: _, + imaginary_targets: _, + } + | TerminatorKind::FalseUnwind { + real_target: _, + unwind: _, + } => { // no data used, thus irrelevant to borrowck } } @@ -685,7 +687,8 @@ enum LocalMutationIsAllowed { struct AccessErrorsReported { mutability_error: bool, - #[allow(dead_code)] conflict_error: bool, + #[allow(dead_code)] + conflict_error: bool, } #[derive(Copy, Clone)] @@ -721,9 +724,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { /// allowed to be split into separate Reservation and /// Activation phases. fn allow_two_phase_borrow(&self, kind: BorrowKind) -> bool { - self.tcx.two_phase_borrows() && - (kind.allows_two_phase_borrow() || - self.tcx.sess.opts.debugging_opts.two_phase_beyond_autoref) + self.tcx.two_phase_borrows() + && (kind.allows_two_phase_borrow() + || self.tcx.sess.opts.debugging_opts.two_phase_beyond_autoref) } /// Invokes `access_place` as appropriate for dropping the value @@ -755,16 +758,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let field_ty = gcx.normalize_associated_type_in_env(&field_ty, self.param_env); let place = drop_place.clone().field(Field::new(index), field_ty); - self.visit_terminator_drop( - loc, - term, - flow_state, - &place, - field_ty, - span, - ); + self.visit_terminator_drop(loc, term, flow_state, &place, field_ty, span); } - }, + } _ => { // We have now refined the type of the value being // dropped (potentially) to just the type of a @@ -781,7 +777,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { flow_state, ); } - }, + } } } @@ -803,8 +799,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { if let Activation(_, borrow_index) = rw { if self.reservation_error_reported.contains(&place_span.0) { - debug!("skipping access_place for activation of invalid reservation \ - place: {:?} borrow_index: {:?}", place_span.0, borrow_index); + debug!( + "skipping access_place for activation of invalid reservation \ + place: {:?} borrow_index: {:?}", + place_span.0, borrow_index + ); return AccessErrorsReported { mutability_error: false, conflict_error: true, @@ -812,9 +811,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } } - if self.access_place_error_reported.contains(&(place_span.0.clone(), place_span.1)) { - debug!("access_place: suppressing error place_span=`{:?}` kind=`{:?}`", - place_span, kind); + if self.access_place_error_reported + .contains(&(place_span.0.clone(), place_span.1)) + { + debug!( + "access_place: suppressing error place_span=`{:?}` kind=`{:?}`", + place_span, kind + ); return AccessErrorsReported { mutability_error: false, conflict_error: true, @@ -827,9 +830,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { self.check_access_for_conflict(context, place_span, sd, rw, flow_state); if conflict_error || mutability_error { - debug!("access_place: logging error place_span=`{:?}` kind=`{:?}`", - place_span, kind); - self.access_place_error_reported.insert((place_span.0.clone(), place_span.1)); + debug!( + "access_place: logging error place_span=`{:?}` kind=`{:?}`", + place_span, kind + ); + self.access_place_error_reported + .insert((place_span.0.clone(), place_span.1)); } AccessErrorsReported { @@ -877,8 +883,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { (Read(kind), BorrowKind::Unique) | (Read(kind), BorrowKind::Mut { .. }) => { // Reading from mere reservations of mutable-borrows is OK. - if this.allow_two_phase_borrow(borrow.kind) && index.is_reservation() - { + if this.allow_two_phase_borrow(borrow.kind) && index.is_reservation() { return Control::Continue; } @@ -917,15 +922,15 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { place_span.0 ); this.reservation_error_reported.insert(place_span.0.clone()); - }, + } Activation(_, activating) => { debug!( "observing check_place for activation of \ borrow_index: {:?}", activating ); - }, - Read(..) | Write(..) => {}, + } + Read(..) | Write(..) => {} } match kind { @@ -1212,11 +1217,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { /// Reports an error if this is a borrow of local data. /// This is called for all Yield statements on movable generators - fn check_for_local_borrow( - &mut self, - borrow: &BorrowData<'tcx>, - yield_span: Span) - { + fn check_for_local_borrow(&mut self, borrow: &BorrowData<'tcx>, yield_span: Span) { fn borrow_of_local_data<'tcx>(place: &Place<'tcx>) -> bool { match place { Place::Static(..) => false, @@ -1228,13 +1229,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ProjectionElem::Deref => false, // For interior references and downcasts, find out if the base is local - ProjectionElem::Field(..) | - ProjectionElem::Index(..) | - ProjectionElem::ConstantIndex { .. } | - ProjectionElem::Subslice { .. } | - ProjectionElem::Downcast(..) => { - borrow_of_local_data(&proj.base) - } + ProjectionElem::Field(..) + | ProjectionElem::Index(..) + | ProjectionElem::ConstantIndex { .. } + | ProjectionElem::Subslice { .. } + | ProjectionElem::Downcast(..) => borrow_of_local_data(&proj.base), } } } @@ -1243,9 +1242,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { debug!("check_for_local_borrow({:?})", borrow); if borrow_of_local_data(&borrow.borrowed_place) { - self.tcx.cannot_borrow_across_generator_yield(self.retrieve_borrow_span(borrow), - yield_span, - Origin::Mir).emit(); + self.tcx + .cannot_borrow_across_generator_yield( + self.retrieve_borrow_span(borrow), + yield_span, + Origin::Mir, + ) + .emit(); } } @@ -1533,9 +1536,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ) -> bool { debug!( "check_access_permissions({:?}, {:?}, {:?})", - place, - kind, - is_local_mutation_allowed + place, kind, is_local_mutation_allowed ); let mut error_reported = false; match kind { @@ -1600,8 +1601,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { span, &format!( "Accessing `{:?}` with the kind `{:?}` shouldn't be possible", - place, - kind + place, kind ), ); } @@ -1700,9 +1700,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let decl = &self.mir.upvar_decls[field.index()]; debug!( "decl.mutability={:?} local_mutation_is_allowed={:?} place={:?}", - decl, - is_local_mutation_allowed, - place + decl, is_local_mutation_allowed, place ); match (decl.mutability, is_local_mutation_allowed) { (Mutability::Not, LocalMutationIsAllowed::No) @@ -1723,7 +1721,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } } - /// If this is a field projection, and the field is being projected from a closure type, /// then returns the index of the field being projected. Note that this closure will always /// be `self` in the current MIR, because that is the only time we directly access the fields @@ -1927,9 +1924,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ) -> bool { debug!( "places_conflict({:?},{:?},{:?})", - borrow_place, - access_place, - access + borrow_place, access_place, access ); // Return all the prefixes of `place` in reverse order, including @@ -1955,8 +1950,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let access_components = place_elements(access_place); debug!( "places_conflict: components {:?} / {:?}", - borrow_components, - access_components + borrow_components, access_components ); let borrow_components = borrow_components @@ -2162,8 +2156,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let borrowed = &data[i.borrow_index()]; if self.places_conflict(&borrowed.borrowed_place, place, access) { - debug!("each_borrow_involving_path: {:?} @ {:?} vs. {:?}/{:?}", - i, borrowed, place, access); + debug!( + "each_borrow_involving_path: {:?} @ {:?} vs. {:?}/{:?}", + i, borrowed, place, access + ); let ctrl = op(self, i, borrowed); if ctrl == Control::Break { return; diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index 9b598b8dd5d11..66776a94ff01f 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -257,10 +257,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let mut result = Self { definitions, elements: elements.clone(), - liveness_constraints: RegionValues::new( - elements, - num_region_variables, - ), + liveness_constraints: RegionValues::new(elements, num_region_variables), inferred_values: None, constraints: Vec::new(), type_tests: Vec::new(), diff --git a/src/librustc_mir/borrow_check/nll/region_infer/values.rs b/src/librustc_mir/borrow_check/nll/region_infer/values.rs index eb2756e2245d4..2f0b4c24bd6f1 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/values.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/values.rs @@ -201,10 +201,7 @@ impl RegionValues { /// Creates a new set of "region values" that tracks causal information. /// Each of the regions in num_region_variables will be initialized with an /// empty set of points and no causal information. - pub(super) fn new( - elements: &Rc, - num_region_variables: usize, - ) -> Self { + pub(super) fn new(elements: &Rc, num_region_variables: usize) -> Self { assert!( elements.num_universal_regions <= num_region_variables, "universal regions are a subset of the region variables" From 4bde92c17674ba5ac8de4123e0c1023d1e29a60f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 5 Mar 2018 08:12:13 -0800 Subject: [PATCH 11/15] rustc: Fix ICE with `#[target_feature]` on module This commit fixes an ICE in rustc when `#[target_feature]` was applied to items other than functions due to the way the feature was validated. --- src/librustc/hir/check_attr.rs | 8 +++++++- src/librustc_typeck/collect.rs | 1 + src/test/ui/target-feature-wrong.rs | 4 ++++ src/test/ui/target-feature-wrong.stderr | 11 ++++++++++- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index d22703452605b..d7194e9c2cabb 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -47,7 +47,13 @@ struct CheckAttrVisitor<'a, 'tcx: 'a> { impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { /// Check any attribute. fn check_attributes(&self, item: &hir::Item, target: Target) { - self.tcx.trans_fn_attrs(self.tcx.hir.local_def_id(item.id)); + if target == Target::Fn { + self.tcx.trans_fn_attrs(self.tcx.hir.local_def_id(item.id)); + } else if let Some(a) = item.attrs.iter().find(|a| a.check_name("target_feature")) { + self.tcx.sess.struct_span_err(a.span, "attribute should be applied to a function") + .span_label(item.span, "not a function") + .emit(); + } for attr in &item.attrs { if let Some(name) = attr.name() { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 1a7d8bb56780e..5fc69035db039 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1883,6 +1883,7 @@ fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAt .emit(); } } else if attr.check_name("target_feature") { + // handle deprecated #[target_feature = "..."] if let Some(val) = attr.value_str() { for feat in val.as_str().split(",").map(|f| f.trim()) { if !feat.is_empty() && !feat.contains('\0') { diff --git a/src/test/ui/target-feature-wrong.rs b/src/test/ui/target-feature-wrong.rs index e70d549ed573a..c1e6245d24be8 100644 --- a/src/test/ui/target-feature-wrong.rs +++ b/src/test/ui/target-feature-wrong.rs @@ -29,6 +29,10 @@ unsafe fn foo() {} //~^ ERROR: can only be applied to `unsafe` function fn bar() {} +#[target_feature(enable = "sse2")] +//~^ ERROR: should be applied to a function +mod another {} + fn main() { unsafe { foo(); diff --git a/src/test/ui/target-feature-wrong.stderr b/src/test/ui/target-feature-wrong.stderr index 07bad48259111..0fa6910f2bb3f 100644 --- a/src/test/ui/target-feature-wrong.stderr +++ b/src/test/ui/target-feature-wrong.stderr @@ -28,5 +28,14 @@ error: #[target_feature(..)] can only be applied to `unsafe` function LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: attribute should be applied to a function + --> $DIR/target-feature-wrong.rs:32:1 + | +LL | #[target_feature(enable = "sse2")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | //~^ ERROR: should be applied to a function +LL | mod another {} + | -------------- not a function + +error: aborting due to 5 previous errors From 3e60d996a00c6151b635994820edeb43ffd12e6c Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 3 Mar 2018 10:22:07 -0500 Subject: [PATCH 12/15] Replace iterator structures with `impl Trait`. --- src/librustc_data_structures/graph/mod.rs | 102 ++++++---------------- src/librustc_data_structures/lib.rs | 1 + 2 files changed, 26 insertions(+), 77 deletions(-) diff --git a/src/librustc_data_structures/graph/mod.rs b/src/librustc_data_structures/graph/mod.rs index 56d5f5ffa3f6c..9ce9c738b169c 100644 --- a/src/librustc_data_structures/graph/mod.rs +++ b/src/librustc_data_structures/graph/mod.rs @@ -196,27 +196,27 @@ impl Graph { // # Iterating over nodes, edges - pub fn enumerated_nodes(&self) -> EnumeratedNodes { - EnumeratedNodes { - iter: self.nodes.iter().enumerate() - } + pub fn enumerated_nodes(&self) -> impl Iterator)> { + self.nodes + .iter() + .enumerate() + .map(|(idx, n)| (NodeIndex(idx), n)) } - pub fn enumerated_edges(&self) -> EnumeratedEdges { - EnumeratedEdges { - iter: self.edges.iter().enumerate() - } + pub fn enumerated_edges(&self) -> impl Iterator)> { + self.edges + .iter() + .enumerate() + .map(|(idx, e)| (EdgeIndex(idx), e)) } - pub fn each_node<'a, F>(&'a self, mut f: F) -> bool - where F: FnMut(NodeIndex, &'a Node) -> bool + pub fn each_node<'a>(&'a self, mut f: impl FnMut(NodeIndex, &'a Node) -> bool) -> bool { //! Iterates over all edges defined in the graph. self.enumerated_nodes().all(|(node_idx, node)| f(node_idx, node)) } - pub fn each_edge<'a, F>(&'a self, mut f: F) -> bool - where F: FnMut(EdgeIndex, &'a Edge) -> bool + pub fn each_edge<'a>(&'a self, mut f: impl FnMut(EdgeIndex, &'a Edge) -> bool) -> bool { //! Iterates over all edges defined in the graph self.enumerated_edges().all(|(edge_idx, edge)| f(edge_idx, edge)) @@ -239,11 +239,17 @@ impl Graph { } } - pub fn successor_nodes(&self, source: NodeIndex) -> AdjacentTargets { + pub fn successor_nodes<'a>( + &'a self, + source: NodeIndex, + ) -> impl Iterator + 'a { self.outgoing_edges(source).targets() } - pub fn predecessor_nodes(&self, target: NodeIndex) -> AdjacentSources { + pub fn predecessor_nodes<'a>( + &'a self, + target: NodeIndex, + ) -> impl Iterator + 'a { self.incoming_edges(target).sources() } @@ -293,34 +299,6 @@ impl Graph { // # Iterators -pub struct EnumeratedNodes<'g, N> - where N: 'g, -{ - iter: ::std::iter::Enumerate<::std::slice::Iter<'g, Node>> -} - -impl<'g, N: Debug> Iterator for EnumeratedNodes<'g, N> { - type Item = (NodeIndex, &'g Node); - - fn next(&mut self) -> Option<(NodeIndex, &'g Node)> { - self.iter.next().map(|(idx, n)| (NodeIndex(idx), n)) - } -} - -pub struct EnumeratedEdges<'g, E> - where E: 'g, -{ - iter: ::std::iter::Enumerate<::std::slice::Iter<'g, Edge>> -} - -impl<'g, E: Debug> Iterator for EnumeratedEdges<'g, E> { - type Item = (EdgeIndex, &'g Edge); - - fn next(&mut self) -> Option<(EdgeIndex, &'g Edge)> { - self.iter.next().map(|(idx, e)| (EdgeIndex(idx), e)) - } -} - pub struct AdjacentEdges<'g, N, E> where N: 'g, E: 'g @@ -330,13 +308,13 @@ pub struct AdjacentEdges<'g, N, E> next: EdgeIndex, } -impl<'g, N, E> AdjacentEdges<'g, N, E> { - fn targets(self) -> AdjacentTargets<'g, N, E> { - AdjacentTargets { edges: self } +impl<'g, N: Debug, E: Debug> AdjacentEdges<'g, N, E> { + fn targets(self) -> impl Iterator + 'g { + self.into_iter().map(|(_, edge)| edge.target) } - fn sources(self) -> AdjacentSources<'g, N, E> { - AdjacentSources { edges: self } + fn sources(self) -> impl Iterator + 'g { + self.into_iter().map(|(_, edge)| edge.source) } } @@ -355,36 +333,6 @@ impl<'g, N: Debug, E: Debug> Iterator for AdjacentEdges<'g, N, E> { } } -pub struct AdjacentTargets<'g, N, E> - where N: 'g, - E: 'g -{ - edges: AdjacentEdges<'g, N, E>, -} - -impl<'g, N: Debug, E: Debug> Iterator for AdjacentTargets<'g, N, E> { - type Item = NodeIndex; - - fn next(&mut self) -> Option { - self.edges.next().map(|(_, edge)| edge.target) - } -} - -pub struct AdjacentSources<'g, N, E> - where N: 'g, - E: 'g -{ - edges: AdjacentEdges<'g, N, E>, -} - -impl<'g, N: Debug, E: Debug> Iterator for AdjacentSources<'g, N, E> { - type Item = NodeIndex; - - fn next(&mut self) -> Option { - self.edges.next().map(|(_, edge)| edge.source) - } -} - pub struct DepthFirstTraversal<'g, N, E> where N: 'g, E: 'g diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 265c64858300b..81246aea1b56e 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -34,6 +34,7 @@ #![feature(underscore_lifetimes)] #![feature(macro_vis_matcher)] #![feature(allow_internal_unstable)] +#![feature(universal_impl_trait)] #![cfg_attr(unix, feature(libc))] #![cfg_attr(test, feature(test))] From 08a01825364c429675d28b326e047ce4bc56ff7f Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 3 Mar 2018 10:24:29 -0500 Subject: [PATCH 13/15] Run rustfmt on `src/librustc_data_structures/graph/mod.rs`. --- src/librustc_data_structures/graph/mod.rs | 53 +++++++++++++---------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/src/librustc_data_structures/graph/mod.rs b/src/librustc_data_structures/graph/mod.rs index 9ce9c738b169c..1945b82c03145 100644 --- a/src/librustc_data_structures/graph/mod.rs +++ b/src/librustc_data_structures/graph/mod.rs @@ -210,16 +210,16 @@ impl Graph { .map(|(idx, e)| (EdgeIndex(idx), e)) } - pub fn each_node<'a>(&'a self, mut f: impl FnMut(NodeIndex, &'a Node) -> bool) -> bool - { + pub fn each_node<'a>(&'a self, mut f: impl FnMut(NodeIndex, &'a Node) -> bool) -> bool { //! Iterates over all edges defined in the graph. - self.enumerated_nodes().all(|(node_idx, node)| f(node_idx, node)) + self.enumerated_nodes() + .all(|(node_idx, node)| f(node_idx, node)) } - pub fn each_edge<'a>(&'a self, mut f: impl FnMut(EdgeIndex, &'a Edge) -> bool) -> bool - { + pub fn each_edge<'a>(&'a self, mut f: impl FnMut(EdgeIndex, &'a Edge) -> bool) -> bool { //! Iterates over all edges defined in the graph - self.enumerated_edges().all(|(edge_idx, edge)| f(edge_idx, edge)) + self.enumerated_edges() + .all(|(edge_idx, edge)| f(edge_idx, edge)) } pub fn outgoing_edges(&self, source: NodeIndex) -> AdjacentEdges { @@ -253,18 +253,19 @@ impl Graph { self.incoming_edges(target).sources() } - pub fn depth_traverse<'a>(&'a self, - start: NodeIndex, - direction: Direction) - -> DepthFirstTraversal<'a, N, E> { + pub fn depth_traverse<'a>( + &'a self, + start: NodeIndex, + direction: Direction, + ) -> DepthFirstTraversal<'a, N, E> { DepthFirstTraversal::with_start_node(self, start, direction) } - pub fn nodes_in_postorder<'a>(&'a self, - direction: Direction, - entry_node: NodeIndex) - -> Vec - { + pub fn nodes_in_postorder<'a>( + &'a self, + direction: Direction, + entry_node: NodeIndex, + ) -> Vec { let mut visited = BitVector::new(self.len_nodes()); let mut stack = vec![]; let mut result = Vec::with_capacity(self.len_nodes()); @@ -274,7 +275,8 @@ impl Graph { } }; - for node in Some(entry_node).into_iter() + for node in Some(entry_node) + .into_iter() .chain(self.enumerated_nodes().map(|(node, _)| node)) { push_node(&mut stack, node); @@ -300,8 +302,9 @@ impl Graph { // # Iterators pub struct AdjacentEdges<'g, N, E> - where N: 'g, - E: 'g +where + N: 'g, + E: 'g, { graph: &'g Graph, direction: Direction, @@ -334,8 +337,9 @@ impl<'g, N: Debug, E: Debug> Iterator for AdjacentEdges<'g, N, E> { } pub struct DepthFirstTraversal<'g, N, E> - where N: 'g, - E: 'g +where + N: 'g, + E: 'g, { graph: &'g Graph, stack: Vec, @@ -344,10 +348,11 @@ pub struct DepthFirstTraversal<'g, N, E> } impl<'g, N: Debug, E: Debug> DepthFirstTraversal<'g, N, E> { - pub fn with_start_node(graph: &'g Graph, - start_node: NodeIndex, - direction: Direction) - -> Self { + pub fn with_start_node( + graph: &'g Graph, + start_node: NodeIndex, + direction: Direction, + ) -> Self { let mut visited = BitVector::new(graph.len_nodes()); visited.insert(start_node.node_id()); DepthFirstTraversal { From 2aa19feeb988710e6e9ca9e1c8a77f99e3fe7213 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 8 Mar 2018 04:50:43 +0100 Subject: [PATCH 14/15] Add with_lock, with_read_lock and with_write_lock --- src/librustc_data_structures/sync.rs | 126 ++++++++++++++++++--------- 1 file changed, 87 insertions(+), 39 deletions(-) diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index b1ab4eaa06924..f17ab264bffbb 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -62,7 +62,7 @@ cfg_if! { pub use std::cell::RefMut as WriteGuard; pub use std::cell::RefMut as LockGuard; - pub use std::cell::RefCell as RwLock; + use std::cell::RefCell as InnerRwLock; use std::cell::RefCell as InnerLock; use std::cell::Cell; @@ -159,13 +159,12 @@ cfg_if! { pub use parking_lot::MutexGuard as LockGuard; - use parking_lot; - pub use std::sync::Arc as Lrc; pub use self::Lock as MTLock; use parking_lot::Mutex as InnerLock; + use parking_lot::RwLock as InnerRwLock; pub type MetadataRef = OwningRef, [u8]>; @@ -222,42 +221,6 @@ cfg_if! { self.0.lock().take() } } - - #[derive(Debug)] - pub struct RwLock(parking_lot::RwLock); - - impl RwLock { - #[inline(always)] - pub fn new(inner: T) -> Self { - RwLock(parking_lot::RwLock::new(inner)) - } - - #[inline(always)] - pub fn borrow(&self) -> ReadGuard { - if ERROR_CHECKING { - self.0.try_read().expect("lock was already held") - } else { - self.0.read() - } - } - - #[inline(always)] - pub fn borrow_mut(&self) -> WriteGuard { - if ERROR_CHECKING { - self.0.try_write().expect("lock was already held") - } else { - self.0.write() - } - } - } - - // FIXME: Probably a bad idea - impl Clone for RwLock { - #[inline] - fn clone(&self) -> Self { - RwLock::new(self.borrow().clone()) - } - } } } @@ -383,6 +346,11 @@ impl Lock { self.0.borrow_mut() } + #[inline(always)] + pub fn with_lock R, R>(&self, f: F) -> R { + f(&mut *self.lock()) + } + #[inline(always)] pub fn borrow(&self) -> LockGuard { self.lock() @@ -401,3 +369,83 @@ impl Clone for Lock { Lock::new(self.borrow().clone()) } } + +#[derive(Debug)] +pub struct RwLock(InnerRwLock); + +impl RwLock { + #[inline(always)] + pub fn new(inner: T) -> Self { + RwLock(InnerRwLock::new(inner)) + } + + #[inline(always)] + pub fn into_inner(self) -> T { + self.0.into_inner() + } + + #[inline(always)] + pub fn get_mut(&mut self) -> &mut T { + self.0.get_mut() + } + + #[cfg(not(parallel_queries))] + #[inline(always)] + pub fn read(&self) -> ReadGuard { + self.0.borrow() + } + + #[cfg(parallel_queries)] + #[inline(always)] + pub fn read(&self) -> ReadGuard { + if ERROR_CHECKING { + self.0.try_read().expect("lock was already held") + } else { + self.0.read() + } + } + + #[inline(always)] + pub fn with_read_lock R, R>(&self, f: F) -> R { + f(&*self.read()) + } + + #[cfg(not(parallel_queries))] + #[inline(always)] + pub fn write(&self) -> WriteGuard { + self.0.borrow_mut() + } + + #[cfg(parallel_queries)] + #[inline(always)] + pub fn write(&self) -> WriteGuard { + if ERROR_CHECKING { + self.0.try_write().expect("lock was already held") + } else { + self.0.write() + } + } + + #[inline(always)] + pub fn with_write_lock R, R>(&self, f: F) -> R { + f(&mut *self.write()) + } + + #[inline(always)] + pub fn borrow(&self) -> ReadGuard { + self.read() + } + + #[inline(always)] + pub fn borrow_mut(&self) -> WriteGuard { + self.write() + } +} + +// FIXME: Probably a bad idea +impl Clone for RwLock { + #[inline] + fn clone(&self) -> Self { + RwLock::new(self.borrow().clone()) + } +} From 728c16c88f8db0c914cecc8b20b7f851d936fd5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 7 Mar 2018 02:43:33 +0100 Subject: [PATCH 15/15] Move REGISTERED_DIAGNOSTICS to a ParseSess field --- src/libsyntax/diagnostics/plugin.rs | 23 ++++------------------- src/libsyntax/parse/lexer/mod.rs | 3 +++ src/libsyntax/parse/mod.rs | 6 +++++- 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index dd27dea4f0d97..e8c2d325bd653 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::cell::RefCell; use std::collections::BTreeMap; use std::env; @@ -31,12 +30,6 @@ pub use errors::*; // Maximum width of any line in an extended error description (inclusive). const MAX_DESCRIPTION_WIDTH: usize = 80; -thread_local! { - static REGISTERED_DIAGNOSTICS: RefCell = { - RefCell::new(BTreeMap::new()) - } -} - /// Error information type. pub struct ErrorInfo { pub description: Option, @@ -46,14 +39,6 @@ pub struct ErrorInfo { /// Mapping from error codes to metadata. pub type ErrorMap = BTreeMap; -fn with_registered_diagnostics(f: F) -> T where - F: FnOnce(&mut ErrorMap) -> T, -{ - REGISTERED_DIAGNOSTICS.with(move |slot| { - f(&mut *slot.borrow_mut()) - }) -} - pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt, span: Span, token_tree: &[TokenTree]) @@ -63,7 +48,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt, _ => unreachable!() }; - with_registered_diagnostics(|diagnostics| { + ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| { match diagnostics.get_mut(&code.name) { // Previously used errors. Some(&mut ErrorInfo { description: _, use_site: Some(previous_span) }) => { @@ -132,7 +117,7 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt, } }); // Add the error to the map. - with_registered_diagnostics(|diagnostics| { + ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| { let info = ErrorInfo { description, use_site: None @@ -174,7 +159,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, // Output error metadata to `tmp/extended-errors//.json` if let Ok(target_triple) = env::var("CFG_COMPILER_HOST_TRIPLE") { - with_registered_diagnostics(|diagnostics| { + ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| { if let Err(e) = output_metadata(ecx, &target_triple, &crate_name.name.as_str(), @@ -194,7 +179,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, // Construct the output expression. let (count, expr) = - with_registered_diagnostics(|diagnostics| { + ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| { let descriptions: Vec> = diagnostics.iter().filter_map(|(&code, info)| { info.description.map(|description| { diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 94195ccc72c49..cdf38453d7ea4 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1764,6 +1764,8 @@ mod tests { use std::collections::HashSet; use std::io; use std::path::PathBuf; + use diagnostics::plugin::ErrorMap; + use rustc_data_structures::sync::Lock; fn mk_sess(cm: Lrc) -> ParseSess { let emitter = errors::emitter::EmitterWriter::new(Box::new(io::sink()), Some(cm.clone()), @@ -1776,6 +1778,7 @@ mod tests { included_mod_stack: RefCell::new(Vec::new()), code_map: cm, missing_fragment_specifiers: RefCell::new(HashSet::new()), + registered_diagnostics: Lock::new(ErrorMap::new()), non_modrs_mods: RefCell::new(vec![]), } } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 1d9af682fec8a..3fb0c209f70f4 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -10,7 +10,7 @@ //! The main parser interface -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{Lrc, Lock}; use ast::{self, CrateConfig}; use codemap::{CodeMap, FilePathMapping}; use syntax_pos::{self, Span, FileMap, NO_EXPANSION, FileName}; @@ -21,6 +21,7 @@ use ptr::P; use str::char_at; use symbol::Symbol; use tokenstream::{TokenStream, TokenTree}; +use diagnostics::plugin::ErrorMap; use std::cell::RefCell; use std::collections::HashSet; @@ -47,6 +48,8 @@ pub struct ParseSess { pub unstable_features: UnstableFeatures, pub config: CrateConfig, pub missing_fragment_specifiers: RefCell>, + /// The registered diagnostics codes + pub registered_diagnostics: Lock, // Spans where a `mod foo;` statement was included in a non-mod.rs file. // These are used to issue errors if the non_modrs_mods feature is not enabled. pub non_modrs_mods: RefCell>, @@ -71,6 +74,7 @@ impl ParseSess { unstable_features: UnstableFeatures::from_environment(), config: HashSet::new(), missing_fragment_specifiers: RefCell::new(HashSet::new()), + registered_diagnostics: Lock::new(ErrorMap::new()), included_mod_stack: RefCell::new(vec![]), code_map, non_modrs_mods: RefCell::new(vec![]),