From 0384722357d4a6dcc2a1e79b41cf9f0df50cb577 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 17 Aug 2016 11:49:28 -0500 Subject: [PATCH 01/17] Add `must_use` to the Reference --- src/doc/reference.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/doc/reference.md b/src/doc/reference.md index f0ab1488d4015..d14322a0655ca 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -2070,6 +2070,9 @@ macro scope. trait of the same name. `{Self}` will be replaced with the type that is supposed to implement the trait but doesn't. To use this, the `on_unimplemented` feature gate must be enabled. +- `must_use` - on structs and enums, will warn if a value of this type isn't used or + assigned to a variable. You may also include an optional message by using + `#[must_use = "message"]` which will be given alongside the warning. ### Conditional compilation From 33560ee51c71548a553c46039cb83dbd581b0ed5 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Sun, 21 Aug 2016 17:01:26 -0400 Subject: [PATCH 02/17] add links to interesting items in `std::ptr` documentation r? @steveklabnik add links for Box, Rc, and Vec --- src/libcore/intrinsics.rs | 15 ++++++++++----- src/libcore/ptr.rs | 32 ++++++++++++++++++++++---------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index c645608dda790..0a40a5d0b1462 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -224,15 +224,20 @@ extern "rust-intrinsic" { /// trait objects, because they can't be read out onto the stack and /// dropped normally. /// - /// * It is friendlier to the optimizer to do this over `ptr::read` when - /// dropping manually allocated memory (e.g. when writing Box/Rc/Vec), - /// as the compiler doesn't need to prove that it's sound to elide the - /// copy. + /// * It is friendlier to the optimizer to do this over [`ptr::read`] when + /// dropping manually allocated memory (e.g. when writing + /// [`Box`]/[`Rc`]/[`Vec`]), as the compiler doesn't need to prove that + /// it's sound to elide the copy. /// /// # Undefined Behavior /// - /// This has all the same safety problems as `ptr::read` with respect to + /// This has all the same safety problems as [`ptr::read`] with respect to /// invalid pointers, types, and double drops. + /// + /// [`ptr::read`]: fn.read.html + /// [`Box`]: ../boxed/struct.Box.html + /// [`Rc`]: ../rc/struct.Rc.html + /// [`Vec`]: ../vec/struct.Vec.html #[stable(feature = "drop_in_place", since = "1.8.0")] pub fn drop_in_place(to_drop: *mut T); diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 925cdfec900db..f111070b6a6b7 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -114,11 +114,17 @@ pub unsafe fn replace(dest: *mut T, mut src: T) -> T { /// # Safety /// /// Beyond accepting a raw pointer, this is unsafe because it semantically -/// moves the value out of `src` without preventing further usage of `src`. -/// If `T` is not `Copy`, then care must be taken to ensure that the value at -/// `src` is not used before the data is overwritten again (e.g. with `write`, -/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use -/// because it will attempt to drop the value previously at `*src`. +/// moves the value out of `src` without preventing further usage of `src`. If +/// `T` is not [`Copy`], then care must be taken to ensure that the value at +/// `src` is not used before the data is overwritten again (e.g. with +/// [`write`], [`zero_memory`], or [`copy_memory`]). Note that `*src = foo` +/// counts as a use because it will attempt to drop the value previously at +/// `*src`. +/// +/// [`Copy`]: ../marker/trait.Copy.html +/// [`write`]: fn.write.html +/// [`zero_memory`]: fn.zero_memory.html +/// [`copy_memory`]: fn.copy_memory.html /// /// # Examples /// @@ -206,11 +212,17 @@ pub unsafe fn write(dst: *mut T, src: T) { /// # Safety /// /// Beyond accepting a raw pointer, this is unsafe because it semantically -/// moves the value out of `src` without preventing further usage of `src`. -/// If `T` is not `Copy`, then care must be taken to ensure that the value at -/// `src` is not used before the data is overwritten again (e.g. with `write`, -/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use -/// because it will attempt to drop the value previously at `*src`. +/// moves the value out of `src` without preventing further usage of `src`. If +/// `T` is not [`Copy`], then care must be taken to ensure that the value at +/// `src` is not used before the data is overwritten again (e.g. with +/// [`write`], [`zero_memory`], or [`copy_memory`]). Note that `*src = foo` +/// counts as a use because it will attempt to drop the value previously at +/// `*src`. +/// +/// [`Copy`]: ../marker/trait.Copy.html +/// [`write`]: fn.write.html +/// [`zero_memory`]: fn.zero_memory.html +/// [`copy_memory`]: fn.copy_memory.html /// /// # Examples /// From 89f7e9269826abf44ee39fdde06197aff15f30ff Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Thu, 18 Aug 2016 15:10:57 -0400 Subject: [PATCH 03/17] demonstrate `RHS != Self` use cases for `Add` and `Sub` remove extra `../`s --- src/libcore/ops.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 5d431230e9744..78c8fc0ac4549 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -212,6 +212,12 @@ macro_rules! forward_ref_binop { /// Point { x: 3, y: 3 }); /// } /// ``` +/// +/// Note that `RHS = Self` by default, but this is not mandatory. For example, +/// [std::time::SystemTime] implements `Add`, which permits +/// operations of the form `SystemTime = SystemTime + Duration`. +/// +/// [std::time::SystemTime]: ../time/struct.SystemTime.html #[lang = "add"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Add { @@ -279,6 +285,12 @@ add_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } /// Point { x: 1, y: 0 }); /// } /// ``` +/// +/// Note that `RHS = Self` by default, but this is not mandatory. For example, +/// [std::time::SystemTime] implements `Sub`, which permits +/// operations of the form `SystemTime = SystemTime - Duration`. +/// +/// [std::time::SystemTime]: ../time/struct.SystemTime.html #[lang = "sub"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Sub { From 7782838a2cb0f544c7dcd315852630c59ec942d2 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Wed, 17 Aug 2016 14:51:50 -0400 Subject: [PATCH 04/17] refactor range examples This pull request adds a module-level example of how all the range operators work. It also slims down struct-level examples in lieu of a link to module examples. add feature for inclusive_range_syntax fix incorrectly closed code fences --- src/libcore/ops.rs | 67 +++++++++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 21 deletions(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 14aa2ba3bd429..681071e5e305c 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -140,6 +140,22 @@ //! //! // `consume_and_return_x` can no longer be invoked at this point //! ``` +//! +//! This example shows the behavior of the various `Range*` structs. +//! +//! ```rust +//! #![feature(inclusive_range_syntax)] +//! +//! let arr = [0, 1, 2, 3, 4]; +//! +//! assert_eq!(arr[ .. ], [0,1,2,3,4]); // RangeFull +//! assert_eq!(arr[ ..3], [0,1,2 ]); // RangeTo +//! assert_eq!(arr[1.. ], [ 1,2,3,4]); // RangeFrom +//! assert_eq!(arr[1..3], [ 1,2 ]); // Range +//! +//! assert_eq!(arr[ ...3], [0,1,2,3 ]); // RangeToIncusive +//! assert_eq!(arr[1...3], [ 1,2,3 ]); // RangeInclusive +//! ``` #![stable(feature = "rust1", since = "1.0.0")] @@ -1881,11 +1897,12 @@ pub trait IndexMut: Index { /// /// ``` /// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ .. ], [0,1,2,3]); // RangeFull -/// assert_eq!(arr[ ..3], [0,1,2 ]); -/// assert_eq!(arr[1.. ], [ 1,2,3]); -/// assert_eq!(arr[1..3], [ 1,2 ]); +/// assert_eq!(arr[ .. ], [0, 1, 2, 3]); /// ``` +/// +/// See the [module examples] for the behavior of other range structs. +/// +/// [module examples]: ../#Examples #[derive(Copy, Clone, PartialEq, Eq, Hash)] #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeFull; @@ -1910,12 +1927,13 @@ impl fmt::Debug for RangeFull { /// assert_eq!(3+4+5, (3..6).sum()); /// /// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ .. ], [0,1,2,3]); -/// assert_eq!(arr[ ..3], [0,1,2 ]); -/// assert_eq!(arr[1.. ], [ 1,2,3]); -/// assert_eq!(arr[1..3], [ 1,2 ]); // Range +/// assert_eq!(arr[1..3], [1, 2]); /// } /// ``` +/// +/// See the [module examples] for the behavior of other range structs. +/// +/// [module examples]: ../#Examples #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct Range { @@ -1973,12 +1991,13 @@ impl> Range { /// assert_eq!(2+3+4, (2..).take(3).sum()); /// /// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ .. ], [0,1,2,3]); -/// assert_eq!(arr[ ..3], [0,1,2 ]); -/// assert_eq!(arr[1.. ], [ 1,2,3]); // RangeFrom -/// assert_eq!(arr[1..3], [ 1,2 ]); +/// assert_eq!(arr[1.. ], [1, 2, 3]); /// } /// ``` +/// +/// See the [module examples] for the behavior of other range structs. +/// +/// [module examples]: ../#Examples #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeFrom { @@ -2040,11 +2059,12 @@ impl> RangeFrom { /// /// ``` /// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ .. ], [0,1,2,3]); -/// assert_eq!(arr[ ..3], [0,1,2 ]); // RangeTo -/// assert_eq!(arr[1.. ], [ 1,2,3]); -/// assert_eq!(arr[1..3], [ 1,2 ]); +/// assert_eq!(arr[ ..3], [0, 1, 2]); /// ``` +/// +/// See the [module examples] for the behavior of other range structs. +/// +/// [module examples]: ../#Examples #[derive(Copy, Clone, PartialEq, Eq, Hash)] #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeTo { @@ -2091,10 +2111,13 @@ impl> RangeTo { /// assert_eq!(3+4+5, (3...5).sum()); /// /// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ ...2], [0,1,2 ]); -/// assert_eq!(arr[1...2], [ 1,2 ]); // RangeInclusive +/// assert_eq!(arr[1...2], [1, 2]); /// } /// ``` +/// +/// See the [module examples] for the behavior of other range structs. +/// +/// [module examples]: ../#Examples #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] pub enum RangeInclusive { @@ -2192,11 +2215,13 @@ impl> RangeInclusive { /// array elements up to and including the index indicated by `end`. /// /// ``` -/// #![feature(inclusive_range_syntax)] /// let arr = [0, 1, 2, 3]; -/// assert_eq!(arr[ ...2], [0,1,2 ]); // RangeToInclusive -/// assert_eq!(arr[1...2], [ 1,2 ]); +/// assert_eq!(arr[ ...2], [0, 1, 2]); /// ``` +/// +/// See the [module examples] for the behavior of other range structs. +/// +/// [module examples]: ../#Examples #[derive(Copy, Clone, PartialEq, Eq, Hash)] #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] pub struct RangeToInclusive { From c330046cbd4edfcb22ad63717ecc6ca0da10cc43 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Tue, 23 Aug 2016 12:26:07 -0400 Subject: [PATCH 05/17] add `fn main` wrappers to enable Rust Playground "Run" button --- src/libcore/ops.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 681071e5e305c..52e4da799545d 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -145,16 +145,17 @@ //! //! ```rust //! #![feature(inclusive_range_syntax)] +//! fn main() { +//! let arr = [0, 1, 2, 3, 4]; //! -//! let arr = [0, 1, 2, 3, 4]; -//! -//! assert_eq!(arr[ .. ], [0,1,2,3,4]); // RangeFull -//! assert_eq!(arr[ ..3], [0,1,2 ]); // RangeTo -//! assert_eq!(arr[1.. ], [ 1,2,3,4]); // RangeFrom -//! assert_eq!(arr[1..3], [ 1,2 ]); // Range +//! assert_eq!(arr[ .. ], [0,1,2,3,4]); // RangeFull +//! assert_eq!(arr[ ..3], [0,1,2 ]); // RangeTo +//! assert_eq!(arr[1.. ], [ 1,2,3,4]); // RangeFrom +//! assert_eq!(arr[1..3], [ 1,2 ]); // Range //! -//! assert_eq!(arr[ ...3], [0,1,2,3 ]); // RangeToIncusive -//! assert_eq!(arr[1...3], [ 1,2,3 ]); // RangeInclusive +//! assert_eq!(arr[ ...3], [0,1,2,3 ]); // RangeToIncusive +//! assert_eq!(arr[1...3], [ 1,2,3 ]); // RangeInclusive +//! } //! ``` #![stable(feature = "rust1", since = "1.0.0")] From 34be21d9b537449bce6d9730d7cfdfad3fd88117 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Tue, 23 Aug 2016 17:35:35 -0400 Subject: [PATCH 06/17] add a note that whitespace alignment is nonidiomatic --- src/libcore/ops.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 52e4da799545d..153ac1ec20948 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -157,6 +157,9 @@ //! assert_eq!(arr[1...3], [ 1,2,3 ]); // RangeInclusive //! } //! ``` +//! +//! Note: whitespace alignment is not idiomatic Rust. An exception is made in +//! this case to facilitate comparison. #![stable(feature = "rust1", since = "1.0.0")] From b5ce02cbe4bfed5a0abf9a21a0d17c0ab34f9915 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Tue, 30 Aug 2016 16:56:54 -0400 Subject: [PATCH 07/17] remove references to `zero_memory` and `copy_memory` I can no longer find these methods in nightly docs. --- src/libcore/ptr.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index f111070b6a6b7..61d53e6050b91 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -117,14 +117,12 @@ pub unsafe fn replace(dest: *mut T, mut src: T) -> T { /// moves the value out of `src` without preventing further usage of `src`. If /// `T` is not [`Copy`], then care must be taken to ensure that the value at /// `src` is not used before the data is overwritten again (e.g. with -/// [`write`], [`zero_memory`], or [`copy_memory`]). Note that `*src = foo` +/// [`write`]). Note that `*src = foo` /// counts as a use because it will attempt to drop the value previously at /// `*src`. /// /// [`Copy`]: ../marker/trait.Copy.html /// [`write`]: fn.write.html -/// [`zero_memory`]: fn.zero_memory.html -/// [`copy_memory`]: fn.copy_memory.html /// /// # Examples /// @@ -215,14 +213,12 @@ pub unsafe fn write(dst: *mut T, src: T) { /// moves the value out of `src` without preventing further usage of `src`. If /// `T` is not [`Copy`], then care must be taken to ensure that the value at /// `src` is not used before the data is overwritten again (e.g. with -/// [`write`], [`zero_memory`], or [`copy_memory`]). Note that `*src = foo` +/// [`write`]). Note that `*src = foo` /// counts as a use because it will attempt to drop the value previously at /// `*src`. /// /// [`Copy`]: ../marker/trait.Copy.html /// [`write`]: fn.write.html -/// [`zero_memory`]: fn.zero_memory.html -/// [`copy_memory`]: fn.copy_memory.html /// /// # Examples /// From e0279d71926d0fd7925f55f600bc9947dd070e68 Mon Sep 17 00:00:00 2001 From: James Miller Date: Wed, 31 Aug 2016 16:40:43 +1200 Subject: [PATCH 08/17] Normalize the function signature of closures Previously we didn't normalize the function signatures used for closures. This didn't cause a problem in most cases, but caused an ICE in during MIR type checking. Fixes #36139 --- src/librustc_typeck/astconv.rs | 7 ++++- src/librustc_typeck/check/closure.rs | 2 ++ .../issue-36139-normalize-closure-sig.rs | 28 +++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/issue-36139-normalize-closure-sig.rs diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index f24a7cf2121eb..844b39c6d16f7 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1877,11 +1877,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { hir::DefaultReturn(..) => self.tcx().mk_nil(), }; + let input_tys = self_ty.into_iter().chain(arg_tys).collect(); + + debug!("ty_of_method_or_bare_fn: input_tys={:?}", input_tys); + debug!("ty_of_method_or_bare_fn: output_ty={:?}", output_ty); + (self.tcx().mk_bare_fn(ty::BareFnTy { unsafety: unsafety, abi: abi, sig: ty::Binder(ty::FnSig { - inputs: self_ty.into_iter().chain(arg_tys).collect(), + inputs: input_tys, output: output_ty, variadic: decl.variadic }), diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 46e8c27f6d33b..aa61974e03908 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -74,6 +74,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let fn_sig = self.tcx.liberate_late_bound_regions( self.tcx.region_maps.call_site_extent(expr.id, body.id), &fn_ty.sig); + let fn_sig = + (**self).normalize_associated_types_in(body.span, body.id, &fn_sig); check_fn(self, hir::Unsafety::Normal, expr.id, &fn_sig, decl, expr.id, &body); diff --git a/src/test/run-pass/issue-36139-normalize-closure-sig.rs b/src/test/run-pass/issue-36139-normalize-closure-sig.rs new file mode 100644 index 0000000000000..adde0ed306674 --- /dev/null +++ b/src/test/run-pass/issue-36139-normalize-closure-sig.rs @@ -0,0 +1,28 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Previously the closure's argument would be inferred to +// >::Item, causing an error in MIR type +// checking + +trait ITrait<'a> {type Item;} + +struct S {} + +impl<'a> ITrait<'a> for S { type Item = &'a mut usize; } + +fn m(_: F) + where I: for<'a> ITrait<'a>, + F: for<'a> FnMut(>::Item) { } + + +fn main() { + m::(|x| { *x += 1; }); +} From 9a400f0a313c765ed8a39d0863321ff9e88d8961 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Wed, 31 Aug 2016 18:17:44 -0400 Subject: [PATCH 09/17] replace `../` with `../../std/` to support `core` docs --- src/libcore/ops.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 78c8fc0ac4549..e36539bf17d57 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -217,7 +217,7 @@ macro_rules! forward_ref_binop { /// [std::time::SystemTime] implements `Add`, which permits /// operations of the form `SystemTime = SystemTime + Duration`. /// -/// [std::time::SystemTime]: ../time/struct.SystemTime.html +/// [std::time::SystemTime]: ../../std/time/struct.SystemTime.html #[lang = "add"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Add { @@ -290,7 +290,7 @@ add_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } /// [std::time::SystemTime] implements `Sub`, which permits /// operations of the form `SystemTime = SystemTime - Duration`. /// -/// [std::time::SystemTime]: ../time/struct.SystemTime.html +/// [std::time::SystemTime]: ../../std/time/struct.SystemTime.html #[lang = "sub"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Sub { From 1b0476297e6d8bee01197e507f50350a748388a2 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Wed, 31 Aug 2016 15:19:43 -0700 Subject: [PATCH 10/17] Special case a few colors for Windows --- src/librustc_errors/emitter.rs | 15 +++++++++++++-- src/librustc_errors/lib.rs | 8 +++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index ed133d21b8a0f..dcdbe2a85259b 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -883,7 +883,11 @@ impl Destination { Style::FileNameStyle | Style::LineAndColumn => {} Style::LineNumber => { try!(self.start_attr(term::Attr::Bold)); - try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_BLUE))); + if cfg!(windows) { + try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_CYAN))); + } else { + try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_BLUE))); + } } Style::ErrorCode => { try!(self.start_attr(term::Attr::Bold)); @@ -896,6 +900,9 @@ impl Destination { } Style::OldSchoolNoteText | Style::HeaderMsg => { try!(self.start_attr(term::Attr::Bold)); + if cfg!(windows) { + try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_WHITE))); + } } Style::UnderlinePrimary | Style::LabelPrimary => { try!(self.start_attr(term::Attr::Bold)); @@ -904,7 +911,11 @@ impl Destination { Style::UnderlineSecondary | Style::LabelSecondary => { try!(self.start_attr(term::Attr::Bold)); - try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_BLUE))); + if cfg!(windows) { + try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_CYAN))); + } else { + try!(self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_BLUE))); + } } Style::NoStyle => {} Style::Level(l) => { diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index c99bc47044853..d82d7dbe70f92 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -732,7 +732,13 @@ impl Level { pub fn color(self) -> term::color::Color { match self { Bug | Fatal | PhaseFatal | Error => term::color::BRIGHT_RED, - Warning => term::color::YELLOW, + Warning => { + if cfg!(windows) { + term::color::BRIGHT_YELLOW + } else { + term::color::YELLOW + } + }, Note => term::color::BRIGHT_GREEN, Help => term::color::BRIGHT_CYAN, Cancelled => unreachable!(), From 439afcd9747808fb187b0676d63af5375a677e3d Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Wed, 31 Aug 2016 17:48:26 -0700 Subject: [PATCH 11/17] Update error message for lifetime of borrowed values --- src/librustc_borrowck/borrowck/mod.rs | 22 ++++++++++------- .../borrowck-let-suggestion-suffixes.rs | 24 +++++++++---------- .../regions-escape-loop-via-vec.rs | 4 ++-- .../lifetimes}/borrowck-let-suggestion.rs | 5 ---- .../lifetimes/borrowck-let-suggestion.stderr | 14 +++++++++++ src/test/ui/span/issue-11925.stderr | 4 ++-- 6 files changed, 44 insertions(+), 29 deletions(-) rename src/test/{compile-fail/borrowck => ui/lifetimes}/borrowck-let-suggestion.rs (66%) create mode 100644 src/test/ui/lifetimes/borrowck-let-suggestion.stderr diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index e8b44d85bf916..ac8cfa7f43709 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -1029,6 +1029,12 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } err_out_of_scope(super_scope, sub_scope, cause) => { + let (value_kind, value_msg) = match err.cmt.cat { + mc::Categorization::Rvalue(_) => + ("temporary value", "temporary value created here"), + _ => + ("borrowed value", "does not live long enough") + }; match cause { euv::ClosureCapture(s) => { // The primary span starts out as the closure creation point. @@ -1039,13 +1045,13 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { Some(primary) => { db.span = MultiSpan::from_span(s); db.span_label(primary, &format!("capture occurs here")); - db.span_label(s, &format!("does not live long enough")); + db.span_label(s, &value_msg); } None => () } } _ => { - db.span_label(error_span, &format!("does not live long enough")); + db.span_label(error_span, &value_msg); } } @@ -1054,14 +1060,15 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { match (sub_span, super_span) { (Some(s1), Some(s2)) if s1 == s2 => { - db.span_label(s1, &"borrowed value dropped before borrower"); + db.span_label(s1, &format!("{} dropped before borrower", value_kind)); db.note("values in a scope are dropped in the opposite order \ they are created"); } _ => { match sub_span { Some(s) => { - db.span_label(s, &"borrowed value must be valid until here"); + db.span_label(s, &format!("{} needs to live until here", + value_kind)); } None => { self.tcx.note_and_explain_region( @@ -1073,7 +1080,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } match super_span { Some(s) => { - db.span_label(s, &"borrowed value only valid until here"); + db.span_label(s, &format!("{} only lives until here", value_kind)); } None => { self.tcx.note_and_explain_region( @@ -1086,9 +1093,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } } - if let Some(span) = statement_scope_span(self.tcx, super_scope) { - db.span_help(span, - "consider using a `let` binding to increase its lifetime"); + if let Some(_) = statement_scope_span(self.tcx, super_scope) { + db.note("consider using a `let` binding to increase its lifetime"); } } diff --git a/src/test/compile-fail/borrowck/borrowck-let-suggestion-suffixes.rs b/src/test/compile-fail/borrowck/borrowck-let-suggestion-suffixes.rs index 6c9f67b2b33d4..95c74348e788b 100644 --- a/src/test/compile-fail/borrowck/borrowck-let-suggestion-suffixes.rs +++ b/src/test/compile-fail/borrowck/borrowck-let-suggestion-suffixes.rs @@ -25,9 +25,9 @@ fn f() { v3.push(&'x'); // statement 6 //~^ ERROR borrowed value does not live long enough - //~| NOTE does not live long enough - //~| NOTE borrowed value only valid until here - //~| HELP consider using a `let` binding to increase its lifetime + //~| NOTE temporary value created here + //~| NOTE temporary value only lives until here + //~| NOTE consider using a `let` binding to increase its lifetime { @@ -35,26 +35,26 @@ fn f() { v4.push(&'y'); //~^ ERROR borrowed value does not live long enough - //~| NOTE does not live long enough - //~| NOTE borrowed value only valid until here - //~| HELP consider using a `let` binding to increase its lifetime + //~| NOTE temporary value created here + //~| NOTE temporary value only lives until here + //~| NOTE consider using a `let` binding to increase its lifetime } // (statement 7) - //~^ NOTE borrowed value must be valid until here + //~^ NOTE temporary value needs to live until here let mut v5 = Vec::new(); // statement 8 v5.push(&'z'); //~^ ERROR borrowed value does not live long enough - //~| NOTE does not live long enough - //~| NOTE borrowed value only valid until here - //~| HELP consider using a `let` binding to increase its lifetime + //~| NOTE temporary value created here + //~| NOTE temporary value only lives until here + //~| NOTE consider using a `let` binding to increase its lifetime v1.push(&old[0]); } //~^ NOTE borrowed value dropped before borrower -//~| NOTE borrowed value must be valid until here -//~| NOTE borrowed value must be valid until here +//~| NOTE temporary value needs to live until here +//~| NOTE temporary value needs to live until here fn main() { f(); diff --git a/src/test/compile-fail/regions-escape-loop-via-vec.rs b/src/test/compile-fail/regions-escape-loop-via-vec.rs index 8c026df7d9754..f5ea7a2108e79 100644 --- a/src/test/compile-fail/regions-escape-loop-via-vec.rs +++ b/src/test/compile-fail/regions-escape-loop-via-vec.rs @@ -24,8 +24,8 @@ fn broken() { x += 1; //~ ERROR cannot assign //~^ NOTE assignment to borrowed `x` occurs here } - //~^ NOTE borrowed value only valid until here + //~^ NOTE borrowed value only lives until here } -//~^ NOTE borrowed value must be valid until here +//~^ NOTE borrowed value needs to live until here fn main() { } diff --git a/src/test/compile-fail/borrowck/borrowck-let-suggestion.rs b/src/test/ui/lifetimes/borrowck-let-suggestion.rs similarity index 66% rename from src/test/compile-fail/borrowck/borrowck-let-suggestion.rs rename to src/test/ui/lifetimes/borrowck-let-suggestion.rs index ef8f44c1df789..eeafaab44c620 100644 --- a/src/test/compile-fail/borrowck/borrowck-let-suggestion.rs +++ b/src/test/ui/lifetimes/borrowck-let-suggestion.rs @@ -10,12 +10,7 @@ fn f() { let x = [1].iter(); - //~^ ERROR borrowed value does not live long enough - //~| NOTE does not live long enough - //~| NOTE borrowed value only valid until here - //~| HELP consider using a `let` binding to increase its lifetime } -//~^ borrowed value must be valid until here fn main() { f(); diff --git a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr new file mode 100644 index 0000000000000..91600340019c3 --- /dev/null +++ b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr @@ -0,0 +1,14 @@ +error: borrowed value does not live long enough + --> $DIR/borrowck-let-suggestion.rs:12:13 + | +12 | let x = [1].iter(); + | ^^^ - temporary value only lives until here + | | + | temporary value created here +13 | } + | - temporary value needs to live until here + | + = note: consider using a `let` binding to increase its lifetime + +error: aborting due to previous error + diff --git a/src/test/ui/span/issue-11925.stderr b/src/test/ui/span/issue-11925.stderr index d379cfc3d68a7..3fedb2884bc58 100644 --- a/src/test/ui/span/issue-11925.stderr +++ b/src/test/ui/span/issue-11925.stderr @@ -5,10 +5,10 @@ error: `x` does not live long enough | ^ | | | does not live long enough - | borrowed value only valid until here + | borrowed value only lives until here ... 23 | } - | - borrowed value must be valid until here + | - borrowed value needs to live until here error: aborting due to previous error From 7d5fa9edc9b9784cbde3550826cc0f37aa6c1501 Mon Sep 17 00:00:00 2001 From: Mohit Agarwal Date: Thu, 1 Sep 2016 18:49:35 +0530 Subject: [PATCH 12/17] configure: check if any of the arguments contain --help Currently it checks only the first argument. Fixes #31216 --- configure | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/configure b/configure index 44fb3d368d2c7..bcc1faea3b5d8 100755 --- a/configure +++ b/configure @@ -360,6 +360,13 @@ abs_path() { (unset CDPATH && cd "$_path" > /dev/null && pwd) } +HELP=0 +for arg; do + case "$arg" in + --help) HELP=1;; + esac +done + msg "looking for configure programs" need_cmd cmp need_cmd mkdir @@ -566,11 +573,8 @@ esac OPTIONS="" -HELP=0 -if [ "$1" = "--help" ] +if [ "$HELP" -eq 1 ] then - HELP=1 - shift echo echo "Usage: $CFG_SELF [options]" echo From 0f8eb81011dcc2f235e74a4f0b7c2d80c1b0b4ab Mon Sep 17 00:00:00 2001 From: Florian Gilcher Date: Mon, 29 Aug 2016 20:05:47 +0200 Subject: [PATCH 13/17] Document try!'s error conversion behaviour --- src/libcore/macros.rs | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index c916ad930ff10..f29a49dd5fe1a 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -189,10 +189,19 @@ macro_rules! debug_assert_eq { ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_eq!($($arg)*); }) } -/// Helper macro for unwrapping `Result` values while returning early with an -/// error if the value of the expression is `Err`. Can only be used in -/// functions that return `Result` because of the early return of `Err` that -/// it provides. +/// Helper macro for reducing boilerplate code for matching `Result` together +/// with converting downstream errors. +/// +/// `try!` matches the given `Result`. In case of the `Ok` variant, the +/// expression has the value of the wrapped value. +/// +/// In case of the `Err` variant, it retrieves the inner error. `try!` then +/// performs conversion using `From`. This provides automatic conversion +/// between specialized errors and more general ones. The resulting +/// error is then immediately returned. +/// +/// Because of the early return, `try!` can only be used in functions that +/// return `Result`. /// /// # Examples /// @@ -201,18 +210,28 @@ macro_rules! debug_assert_eq { /// use std::fs::File; /// use std::io::prelude::*; /// -/// fn write_to_file_using_try() -> Result<(), io::Error> { +/// enum MyError { +/// FileWriteError +/// } +/// +/// impl From for MyError { +/// fn from(e: io::Error) -> MyError { +/// MyError::FileWriteError +/// } +/// } +/// +/// fn write_to_file_using_try() -> Result<(), MyError> { /// let mut file = try!(File::create("my_best_friends.txt")); /// try!(file.write_all(b"This is a list of my best friends.")); /// println!("I wrote to the file"); /// Ok(()) /// } /// // This is equivalent to: -/// fn write_to_file_using_match() -> Result<(), io::Error> { +/// fn write_to_file_using_match() -> Result<(), MyError> { /// let mut file = try!(File::create("my_best_friends.txt")); /// match file.write_all(b"This is a list of my best friends.") { /// Ok(v) => v, -/// Err(e) => return Err(e), +/// Err(e) => return Err(From::from(e)), /// } /// println!("I wrote to the file"); /// Ok(()) From 7cd4e7ff0b2e0872ed5dac00f3b680e7dbc3d24b Mon Sep 17 00:00:00 2001 From: Eugene R Gonzalez Date: Thu, 1 Sep 2016 18:46:30 -0400 Subject: [PATCH 14/17] Fixed E0528 label and unit test --- src/librustc_typeck/check/_match.rs | 9 ++++++--- src/test/compile-fail/E0528.rs | 4 +++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 225468cb9f40c..e1ce89f0ab5dc 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -248,9 +248,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } else if let Some(rest) = size.checked_sub(min_len) { (inner_ty, tcx.mk_array(inner_ty, rest)) } else { - span_err!(tcx.sess, pat.span, E0528, - "pattern requires at least {} elements but array has {}", - min_len, size); + struct_span_err!(tcx.sess, pat.span, E0528, + "pattern requires at least {} elements but array has {}", + min_len, size) + .span_label(pat.span, + &format!("pattern cannot match array of {} elements", size)) + .emit(); (inner_ty, tcx.types.err) } } diff --git a/src/test/compile-fail/E0528.rs b/src/test/compile-fail/E0528.rs index 27187bb5aba08..e912650f11292 100644 --- a/src/test/compile-fail/E0528.rs +++ b/src/test/compile-fail/E0528.rs @@ -13,7 +13,9 @@ fn main() { let r = &[1, 2]; match r { - &[a, b, c, rest..] => { //~ ERROR E0528 + &[a, b, c, rest..] => { + //~^ ERROR E0528 + //~| NOTE pattern cannot match array of 2 elements } } } From 96283fc08367ae8c3d344f2342c4ebe11d799092 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 1 Sep 2016 10:52:44 -0700 Subject: [PATCH 15/17] test: Add a min-llvm-version directive We've got tests which require a particular version of LLVM to run as they're testing bug fixes. Our build system, however, supports multiple LLVM versions, so we can't run these tests on all LLVM versions. This adds a new `min-llvm-version` directive for tests so they can opt out of being run on older versions of LLVM. This then namely applies that logic to the `issue-36023.rs` test case and... Closes #36138 --- mk/main.mk | 1 + mk/tests.mk | 1 + src/bootstrap/check.rs | 4 +++- src/test/run-pass/issue-36023.rs | 2 ++ src/tools/compiletest/src/common.rs | 3 +++ src/tools/compiletest/src/header.rs | 22 +++++++++++++++++++++- src/tools/compiletest/src/main.rs | 2 ++ 7 files changed, 33 insertions(+), 2 deletions(-) diff --git a/mk/main.mk b/mk/main.mk index 5a849af9856f1..6130b58138751 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -348,6 +348,7 @@ LLVM_AS_$(1)=$$(CFG_LLVM_INST_DIR_$(1))/bin/llvm-as$$(X_$(1)) LLC_$(1)=$$(CFG_LLVM_INST_DIR_$(1))/bin/llc$$(X_$(1)) LLVM_ALL_COMPONENTS_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --components) +LLVM_VERSION_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --version) endef diff --git a/mk/tests.mk b/mk/tests.mk index 201e4cae51d6d..c135aa9b8fb95 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -649,6 +649,7 @@ CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) = \ --lldb-python $$(CFG_LLDB_PYTHON) \ --gdb-version="$(CFG_GDB_VERSION)" \ --lldb-version="$(CFG_LLDB_VERSION)" \ + --llvm-version="$$(LLVM_VERSION_$(3))" \ --android-cross-path=$(CFG_ARM_LINUX_ANDROIDEABI_NDK) \ --adb-path=$(CFG_ADB) \ --adb-test-dir=$(CFG_ADB_TEST_DIR) \ diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 3d8b1438125e6..2b9d717cbd48d 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -148,6 +148,9 @@ pub fn compiletest(build: &Build, if let Some(ref dir) = build.lldb_python_dir { cmd.arg("--lldb-python-dir").arg(dir); } + let llvm_config = build.llvm_config(target); + let llvm_version = output(Command::new(&llvm_config).arg("--version")); + cmd.arg("--llvm-version").arg(llvm_version); cmd.args(&build.flags.args); @@ -158,7 +161,6 @@ pub fn compiletest(build: &Build, // Only pass correct values for these flags for the `run-make` suite as it // requires that a C++ compiler was configured which isn't always the case. if suite == "run-make" { - let llvm_config = build.llvm_config(target); let llvm_components = output(Command::new(&llvm_config).arg("--components")); let llvm_cxxflags = output(Command::new(&llvm_config).arg("--cxxflags")); cmd.arg("--cc").arg(build.cc(target)) diff --git a/src/test/run-pass/issue-36023.rs b/src/test/run-pass/issue-36023.rs index f6c03b384f23d..53a8a403b6410 100644 --- a/src/test/run-pass/issue-36023.rs +++ b/src/test/run-pass/issue-36023.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// min-llvm-version 3.9 + use std::ops::Deref; fn main() { diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 6090cb4f52725..5d522736089ea 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -152,6 +152,9 @@ pub struct Config { // Version of LLDB pub lldb_version: Option, + // Version of LLVM + pub llvm_version: Option, + // Path to the android tools pub android_cross_path: PathBuf, diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index af33d76be1b0d..899a366a4bb74 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -44,7 +44,9 @@ impl EarlyProps { (config.mode == common::Pretty && parse_name_directive(ln, "ignore-pretty")) || (config.target != config.host && parse_name_directive(ln, "ignore-cross-compile")) || - ignore_gdb(config, ln) || ignore_lldb(config, ln); + ignore_gdb(config, ln) || + ignore_lldb(config, ln) || + ignore_llvm(config, ln); props.should_fail = props.should_fail || parse_name_directive(ln, "should-fail"); }); @@ -115,6 +117,24 @@ impl EarlyProps { false } } + + fn ignore_llvm(config: &Config, line: &str) -> bool { + if let Some(ref actual_version) = config.llvm_version { + if line.contains("min-llvm-version") { + let min_version = line.trim() + .split(' ') + .last() + .expect("Malformed llvm version directive"); + // Ignore if actual version is smaller the minimum required + // version + &actual_version[..] < min_version + } else { + false + } + } else { + false + } + } } } diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 90641b5c476d7..4afeb3613319b 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -99,6 +99,7 @@ pub fn parse_config(args: Vec ) -> Config { optopt("", "host", "the host to build for", "HOST"), optopt("", "gdb-version", "the version of GDB used", "VERSION STRING"), optopt("", "lldb-version", "the version of LLDB used", "VERSION STRING"), + optopt("", "llvm-version", "the version of LLVM used", "VERSION STRING"), optopt("", "android-cross-path", "Android NDK standalone path", "PATH"), optopt("", "adb-path", "path to the android debugger", "PATH"), optopt("", "adb-test-dir", "path to tests for the android debugger", "PATH"), @@ -170,6 +171,7 @@ pub fn parse_config(args: Vec ) -> Config { host: opt_str2(matches.opt_str("host")), gdb_version: extract_gdb_version(matches.opt_str("gdb-version")), lldb_version: extract_lldb_version(matches.opt_str("lldb-version")), + llvm_version: matches.opt_str("llvm-version"), android_cross_path: opt_path(matches, "android-cross-path"), adb_path: opt_str2(matches.opt_str("adb-path")), adb_test_dir: format!("{}/{}", From 7f95bb0dbd70e838d7cc12520135b08853c8b192 Mon Sep 17 00:00:00 2001 From: Eugene R Gonzalez Date: Thu, 1 Sep 2016 22:35:25 -0400 Subject: [PATCH 16/17] Fixed E0529's label and unit test --- src/librustc_typeck/check/_match.rs | 5 ++++- src/test/compile-fail/E0529.rs | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 225468cb9f40c..1027a3207f0af 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -270,7 +270,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { _ => {} } } - err.emit(); + + err.span_label( pat.span, + &format!("pattern cannot match with input type `{}`", expected_ty) + ).emit(); } (tcx.types.err, tcx.types.err) } diff --git a/src/test/compile-fail/E0529.rs b/src/test/compile-fail/E0529.rs index 488fe7c7763ae..18d3e68816aad 100644 --- a/src/test/compile-fail/E0529.rs +++ b/src/test/compile-fail/E0529.rs @@ -13,7 +13,9 @@ fn main() { let r: f32 = 1.0; match r { - [a, b] => { //~ ERROR E0529 + [a, b] => { + //~^ ERROR E0529 + //~| NOTE pattern cannot match with input type `f32` } } } From 3a96fe32753f0308002e18d165f52d54e5ac64cb Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Wed, 31 Aug 2016 19:10:24 -0400 Subject: [PATCH 17/17] Transition Travis CI to use rustbuild. --- .travis.yml | 4 ++-- src/bootstrap/compile.rs | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0abd858d8228b..c5d8a94f39b05 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,9 +15,9 @@ before_install: script: - docker run -v `pwd`:/build rust sh -c " - ./configure --llvm-root=/usr/lib/llvm-3.7 && + ./configure --enable-rustbuild --llvm-root=/usr/lib/llvm-3.7 && make tidy && - make check-notidy -j4 + make check -j4 " # Real testing happens on http://buildbot.rust-lang.org/ diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 155848901cdb4..302ac68460c69 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -203,6 +203,10 @@ pub fn rustc<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) { cargo.env("LLVM_RUSTLLVM", "1"); } cargo.env("LLVM_CONFIG", build.llvm_config(target)); + let target_config = build.config.target_config.get(target); + if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) { + cargo.env("CFG_LLVM_ROOT", s); + } if build.config.llvm_static_stdcpp { cargo.env("LLVM_STATIC_STDCPP", compiler_file(build.cxx(target), "libstdc++.a"));