From b31ff95ae6fe3fe9501065b11afb8435ce8f783a Mon Sep 17 00:00:00 2001 From: Jewoo Lee Date: Sun, 18 Feb 2018 20:14:21 +0900 Subject: [PATCH 01/19] Add non-panicking variants of pow to all integer types Currently, calling pow may panic in case of overflow, and the function does not have non-panicking counterparts. Thus, it would be beneficial to add those in. --- src/libcore/num/mod.rs | 308 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 308 insertions(+) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 560dcf295b278..2b656fad1719e 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -634,6 +634,46 @@ $EndFeature, " } } + doc_comment! { + concat!("Checked exponentiation. Computes `self.pow(exp)`, returning `None` if +overflow occurred. + +# Examples + +Basic usage: + +``` +#![feature(no_panic_pow)] +", $Feature, "assert_eq!(8", stringify!($SelfT), ".checked_pow(2), Some(64)); +assert_eq!(", stringify!($SelfT), "::max_value().checked_pow(2), None);", +$EndFeature, " +```"), + + #[unstable(feature = "no_panic_pow", issue = "48320")] + #[inline] + pub fn checked_pow(self, mut exp: u32) -> Option { + let mut base = self; + let mut acc: Self = 1; + + while exp > 1 { + if (exp & 1) == 1 { + acc = acc.checked_mul(base)?; + } + exp /= 2; + base = base.checked_mul(base)?; + } + + // Deal with the final bit of the exponent separately, since + // squaring the base afterwards is not necessary and may cause a + // needless overflow. + if exp == 1 { + acc = acc.checked_mul(base)?; + } + + Some(acc) + } + } + doc_comment! { concat!("Saturating integer addition. Computes `self + rhs`, saturating at the numeric bounds instead of overflowing. @@ -713,6 +753,34 @@ $EndFeature, " } } + doc_comment! { + concat!("Saturating integer exponentiation. Computes `self.pow(exp)`, +saturating at the numeric bounds instead of overflowing. + +# Examples + +Basic usage: + +``` +#![feature(no_panic_pow)] +", $Feature, "use std::", stringify!($SelfT), "; + +assert_eq!((-4", stringify!($SelfT), ").saturating_pow(3), -64); +assert_eq!(", stringify!($SelfT), "::MIN.saturating_pow(2), ", stringify!($SelfT), "::MAX); +assert_eq!(", stringify!($SelfT), "::MIN.saturating_pow(3), ", stringify!($SelfT), "::MIN);", +$EndFeature, " +```"), + #[unstable(feature = "no_panic_pow", issue = "48320")] + #[inline] + pub fn saturating_pow(self, exp: u32) -> Self { + match self.checked_pow(exp) { + Some(x) => x, + None if self < 0 && exp % 2 == 1 => Self::min_value(), + None => Self::max_value(), + } + } + } + doc_comment! { concat!("Wrapping (modular) addition. Computes `self + rhs`, wrapping around at the boundary of the type. @@ -947,6 +1015,46 @@ $EndFeature, " } } + doc_comment! { + concat!("Wrapping (modular) exponentiation. Computes `self.pow(exp)`, +wrapping around at the boundary of the type. + +# Examples + +Basic usage: + +``` +#![feature(no_panic_pow)] +", $Feature, "assert_eq!(3", stringify!($SelfT), ".wrapping_pow(4), 81); +assert_eq!(3i8.wrapping_pow(5), -13); +assert_eq!(3i8.wrapping_pow(6), -39);", +$EndFeature, " +```"), + #[unstable(feature = "no_panic_pow", issue = "48320")] + #[inline] + pub fn wrapping_pow(self, mut exp: u32) -> Self { + let mut base = self; + let mut acc: Self = 1; + + while exp > 1 { + if (exp & 1) == 1 { + acc = acc.wrapping_mul(base); + } + exp /= 2; + base = base.wrapping_mul(base); + } + + // Deal with the final bit of the exponent separately, since + // squaring the base afterwards is not necessary and may cause a + // needless overflow. + if exp == 1 { + acc = acc.wrapping_mul(base); + } + + acc + } + } + doc_comment! { concat!("Calculates `self` + `rhs` @@ -1202,6 +1310,56 @@ $EndFeature, " doc_comment! { concat!("Raises self to the power of `exp`, using exponentiation by squaring. +Returns a tuple of the exponentiation along with a bool indicating +whether an overflow happened. + +# Examples + +Basic usage: + +``` +#![feature(no_panic_pow)] +", $Feature, "assert_eq!(3", stringify!($SelfT), ".overflowing_pow(4), (81, false)); +assert_eq!(3i8.overflowing_pow(5), (-13, true));", +$EndFeature, " +```"), + #[unstable(feature = "no_panic_pow", issue = "48320")] + #[inline] + pub fn overflowing_pow(self, mut exp: u32) -> (Self, bool) { + let mut base = self; + let mut acc: Self = 1; + let mut overflown = false; + // Scratch space for storing results of overflowing_mul. + let mut r; + + while exp > 1 { + if (exp & 1) == 1 { + r = acc.overflowing_mul(base); + acc = r.0; + overflown |= r.1; + } + exp /= 2; + r = base.overflowing_mul(base); + base = r.0; + overflown |= r.1; + } + + // Deal with the final bit of the exponent separately, since + // squaring the base afterwards is not necessary and may cause a + // needless overflow. + if exp == 1 { + r = acc.overflowing_mul(base); + acc = r.0; + overflown |= r.1; + } + + (acc, overflown) + } + } + + doc_comment! { + concat!("Raises self to the power of `exp`, using exponentiation by squaring. + # Examples Basic usage: @@ -1887,6 +2045,44 @@ assert_eq!(0x10", stringify!($SelfT), ".checked_shr(129), None);", $EndFeature, } } + doc_comment! { + concat!("Checked exponentiation. Computes `self.pow(exp)`, returning `None` if +overflow occurred. + +# Examples + +Basic usage: + +``` +#![feature(no_panic_pow)] +", $Feature, "assert_eq!(2", stringify!($SelfT), ".checked_pow(5), Some(32)); +assert_eq!(", stringify!($SelfT), "::max_value().checked_pow(2), None);", $EndFeature, " +```"), + #[unstable(feature = "no_panic_pow", issue = "48320")] + #[inline] + pub fn checked_pow(self, mut exp: u32) -> Option { + let mut base = self; + let mut acc: Self = 1; + + while exp > 1 { + if (exp & 1) == 1 { + acc = acc.checked_mul(base)?; + } + exp /= 2; + base = base.checked_mul(base)?; + } + + // Deal with the final bit of the exponent separately, since + // squaring the base afterwards is not necessary and may cause a + // needless overflow. + if exp == 1 { + acc = acc.checked_mul(base)?; + } + + Some(acc) + } + } + doc_comment! { concat!("Saturating integer addition. Computes `self + rhs`, saturating at the numeric bounds instead of overflowing. @@ -1953,6 +2149,32 @@ assert_eq!((", stringify!($SelfT), "::MAX).saturating_mul(10), ", stringify!($Se } } + doc_comment! { + concat!("Saturating integer exponentiation. Computes `self.pow(exp)`, +saturating at the numeric bounds instead of overflowing. + +# Examples + +Basic usage: + +``` +#![feature(no_panic_pow)] +", $Feature, "use std::", stringify!($SelfT), "; + +assert_eq!(4", stringify!($SelfT), ".saturating_pow(3), 64); +assert_eq!(", stringify!($SelfT), "::MAX.saturating_pow(2), ", stringify!($SelfT), "::MAX);", +$EndFeature, " +```"), + #[unstable(feature = "no_panic_pow", issue = "48320")] + #[inline] + pub fn saturating_pow(self, exp: u32) -> Self { + match self.checked_pow(exp) { + Some(x) => x, + None => Self::max_value(), + } + } + } + doc_comment! { concat!("Wrapping (modular) addition. Computes `self + rhs`, wrapping around at the boundary of the type. @@ -2147,6 +2369,44 @@ assert_eq!(128", stringify!($SelfT), ".wrapping_shr(128), 128);", $EndFeature, " } } + doc_comment! { + concat!("Wrapping (modular) exponentiation. Computes `self.pow(exp)`, +wrapping around at the boundary of the type. + +# Examples + +Basic usage: + +``` +#![feature(no_panic_pow)] +", $Feature, "assert_eq!(3", stringify!($SelfT), ".wrapping_pow(5), 243); +assert_eq!(3u8.wrapping_pow(6), 217);", $EndFeature, " +```"), + #[unstable(feature = "no_panic_pow", issue = "48320")] + #[inline] + pub fn wrapping_pow(self, mut exp: u32) -> Self { + let mut base = self; + let mut acc: Self = 1; + + while exp > 1 { + if (exp & 1) == 1 { + acc = acc.wrapping_mul(base); + } + exp /= 2; + base = base.wrapping_mul(base); + } + + // Deal with the final bit of the exponent separately, since + // squaring the base afterwards is not necessary and may cause a + // needless overflow. + if exp == 1 { + acc = acc.wrapping_mul(base); + } + + acc + } + } + doc_comment! { concat!("Calculates `self` + `rhs` @@ -2353,7 +2613,55 @@ assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(132), (0x1, true));", $E pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) { (self.wrapping_shr(rhs), (rhs > ($BITS - 1))) } + } + doc_comment! { + concat!("Raises self to the power of `exp`, using exponentiation by squaring. + +Returns a tuple of the exponentiation along with a bool indicating +whether an overflow happened. + +# Examples + +Basic usage: + +``` +#![feature(no_panic_pow)] +", $Feature, "assert_eq!(3", stringify!($SelfT), ".overflowing_pow(5), (243, false)); +assert_eq!(3u8.overflowing_pow(6), (217, true));", $EndFeature, " +```"), + #[unstable(feature = "no_panic_pow", issue = "48320")] + #[inline] + pub fn overflowing_pow(self, mut exp: u32) -> (Self, bool) { + let mut base = self; + let mut acc: Self = 1; + let mut overflown = false; + // Scratch space for storing results of overflowing_mul. + let mut r; + + while exp > 1 { + if (exp & 1) == 1 { + r = acc.overflowing_mul(base); + acc = r.0; + overflown |= r.1; + } + exp /= 2; + r = base.overflowing_mul(base); + base = r.0; + overflown |= r.1; + } + + // Deal with the final bit of the exponent separately, since + // squaring the base afterwards is not necessary and may cause a + // needless overflow. + if exp == 1 { + r = acc.overflowing_mul(base); + acc = r.0; + overflown |= r.1; + } + + (acc, overflown) + } } doc_comment! { From 2d3f31df8bdcefdd17b5b6a77eac4c94c08aa38d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 20 Feb 2018 19:29:13 +0100 Subject: [PATCH 02/19] Change local storage name for rustdoc because of conflicts with mdbook --- src/librustdoc/html/static/storage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js index 0aa1065b3786a..d60e53ef72cca 100644 --- a/src/librustdoc/html/static/storage.js +++ b/src/librustdoc/html/static/storage.js @@ -30,7 +30,7 @@ function getCurrentValue(name) { function switchTheme(styleElem, mainStyleElem, newTheme) { styleElem.href = mainStyleElem.href.replace("rustdoc.css", newTheme + ".css"); - updateLocalStorage('theme', newTheme); + updateLocalStorage('rustdoc-theme', newTheme); } switchTheme(currentTheme, mainTheme, getCurrentValue('theme') || 'main'); From 5b61b615f5701bea9482f27e1a9f5ae36df721a7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 20 Feb 2018 20:11:58 +0100 Subject: [PATCH 03/19] Allow to not switch to a theme if it doesn't exist --- src/librustdoc/html/static/main.js | 8 ------- src/librustdoc/html/static/storage.js | 34 ++++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index f688be89beebc..ba2e58eb47576 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -96,14 +96,6 @@ } } - function onEach(arr, func) { - if (arr && arr.length > 0 && func) { - for (var i = 0; i < arr.length; i++) { - func(arr[i]); - } - } - } - function isHidden(elem) { return (elem.offsetParent === null) } diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js index d60e53ef72cca..f21dfc8af9298 100644 --- a/src/librustdoc/html/static/storage.js +++ b/src/librustdoc/html/static/storage.js @@ -13,6 +13,18 @@ var currentTheme = document.getElementById("themeStyle"); var mainTheme = document.getElementById("mainThemeStyle"); +var savedHref = []; + +function onEach(arr, func) { + if (arr && arr.length > 0 && func) { + for (var i = 0; i < arr.length; i++) { + if (func(arr[i]) === true) { + break; + } + } + } +} + function updateLocalStorage(name, value) { if (typeof(Storage) !== "undefined") { localStorage[name] = value; @@ -29,8 +41,24 @@ function getCurrentValue(name) { } function switchTheme(styleElem, mainStyleElem, newTheme) { - styleElem.href = mainStyleElem.href.replace("rustdoc.css", newTheme + ".css"); - updateLocalStorage('rustdoc-theme', newTheme); + var newHref = mainStyleElem.href.replace("rustdoc.css", newTheme + ".css"); + var found = false; + + if (savedHref.length === 0) { + onEach(document.getElementsByTagName("link"), function(el) { + savedHref.push(el.href); + }); + } + onEach(savedHref, function(el) { + if (el === newHref) { + found = true; + return true; + } + }); + if (found === true) { + styleElem.href = newHref; + updateLocalStorage('rustdoc-theme', newTheme); + } } -switchTheme(currentTheme, mainTheme, getCurrentValue('theme') || 'main'); +switchTheme(currentTheme, mainTheme, getCurrentValue('rustdoc-theme') || 'main'); From 8d51c331c759210ba320c5662ab3ce3af5e0500b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 20 Feb 2018 20:13:17 +0100 Subject: [PATCH 04/19] Remove theme button outline --- src/librustdoc/html/static/rustdoc.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index cd4f2cfa678e6..a6630902c9794 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1189,6 +1189,10 @@ kbd { top: 19px; } +.theme-picker button { + outline: none; +} + #theme-picker { padding: 4px; width: 27px; From b1a6c8bdd3a76207eff76b004945bc2a13755eca Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Thu, 22 Feb 2018 19:53:44 -0500 Subject: [PATCH 05/19] Stabilize [T]::rotate_{left,right} https://github.com/rust-lang/rust/issues/41891 --- src/liballoc/benches/lib.rs | 1 - src/liballoc/lib.rs | 1 - src/liballoc/slice.rs | 20 +++----------------- src/liballoc/tests/lib.rs | 1 - src/libcore/slice/mod.rs | 4 ++-- src/libcore/tests/lib.rs | 1 - 6 files changed, 5 insertions(+), 23 deletions(-) diff --git a/src/liballoc/benches/lib.rs b/src/liballoc/benches/lib.rs index 174628ccd0788..2de0ffb4b2611 100644 --- a/src/liballoc/benches/lib.rs +++ b/src/liballoc/benches/lib.rs @@ -13,7 +13,6 @@ #![feature(i128_type)] #![feature(rand)] #![feature(repr_simd)] -#![feature(slice_rotate)] #![feature(test)] extern crate rand; diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 5139e54b5604a..d250cfe1880fc 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -79,7 +79,6 @@ #![cfg_attr(test, feature(placement_in))] #![cfg_attr(not(test), feature(core_float))] #![cfg_attr(not(test), feature(exact_size_is_empty))] -#![cfg_attr(not(test), feature(slice_rotate))] #![cfg_attr(not(test), feature(generator_trait))] #![cfg_attr(test, feature(rand, test))] #![feature(allow_internal_unstable)] diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 028983de556f2..dc40062ef13df 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1460,8 +1460,6 @@ impl [T] { /// # Examples /// /// ``` - /// #![feature(slice_rotate)] - /// /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f']; /// a.rotate_left(2); /// assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']); @@ -1470,23 +1468,15 @@ impl [T] { /// Rotating a subslice: /// /// ``` - /// #![feature(slice_rotate)] - /// /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f']; /// a[1..5].rotate_left(1); /// assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']); - /// ``` - #[unstable(feature = "slice_rotate", issue = "41891")] + /// ``` + #[stable(feature = "slice_rotate", since = "1.26.0")] pub fn rotate_left(&mut self, mid: usize) { core_slice::SliceExt::rotate_left(self, mid); } - #[unstable(feature = "slice_rotate", issue = "41891")] - #[rustc_deprecated(since = "", reason = "renamed to `rotate_left`")] - pub fn rotate(&mut self, mid: usize) { - core_slice::SliceExt::rotate_left(self, mid); - } - /// Rotates the slice in-place such that the first `self.len() - k` /// elements of the slice move to the end while the last `k` elements move /// to the front. After calling `rotate_right`, the element previously at @@ -1505,8 +1495,6 @@ impl [T] { /// # Examples /// /// ``` - /// #![feature(slice_rotate)] - /// /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f']; /// a.rotate_right(2); /// assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']); @@ -1515,13 +1503,11 @@ impl [T] { /// Rotate a subslice: /// /// ``` - /// #![feature(slice_rotate)] - /// /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f']; /// a[1..5].rotate_right(1); /// assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']); /// ``` - #[unstable(feature = "slice_rotate", issue = "41891")] + #[stable(feature = "slice_rotate", since = "1.26.0")] pub fn rotate_right(&mut self, k: usize) { core_slice::SliceExt::rotate_right(self, k); } diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 427a7adcbded1..168dbb2ce9b1f 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -23,7 +23,6 @@ #![feature(pattern)] #![feature(placement_in_syntax)] #![feature(rand)] -#![feature(slice_rotate)] #![feature(splice)] #![feature(str_escape)] #![feature(string_retain)] diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index ac390313a6797..a43ed65907f83 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -211,10 +211,10 @@ pub trait SliceExt { #[stable(feature = "core", since = "1.6.0")] fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq; - #[unstable(feature = "slice_rotate", issue = "41891")] + #[stable(feature = "slice_rotate", since = "1.26.0")] fn rotate_left(&mut self, mid: usize); - #[unstable(feature = "slice_rotate", issue = "41891")] + #[stable(feature = "slice_rotate", since = "1.26.0")] fn rotate_right(&mut self, k: usize); #[stable(feature = "clone_from_slice", since = "1.7.0")] diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 3e901a9d442ce..cb8bac10d2b9a 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -35,7 +35,6 @@ #![feature(refcell_replace_swap)] #![feature(sip_hash_13)] #![feature(slice_patterns)] -#![feature(slice_rotate)] #![feature(sort_internals)] #![feature(specialization)] #![feature(step_trait)] From 2985a1abfb48adeb848386377a8c6a3560c17910 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 16 Feb 2018 12:10:06 +0100 Subject: [PATCH 06/19] Report non-standard compile flags on ICE --- src/librustc_driver/lib.rs | 85 +++++++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 5 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 05dcaf731352a..8171d135cae38 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -139,6 +139,19 @@ pub mod target_features { const BUG_REPORT_URL: &'static str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\ md#bug-reports"; +const ICE_REPORT_COMPILER_FLAGS: &'static [&'static str] = &[ + "Z", + "C", + "crate-type", +]; +const ICE_REPORT_COMPILER_FLAGS_EXCLUDE: &'static [&'static str] = &[ + "metadata", + "extra-filename", +]; +const ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE: &'static [&'static str] = &[ + "incremental", +]; + pub fn abort_on_err(result: Result, sess: &Session) -> T { match result { Err(CompileIncomplete::Errored(ErrorReported)) => { @@ -1431,6 +1444,57 @@ pub fn in_rustc_thread(f: F) -> Result> thread.unwrap().join() } +/// Get a list of extra command-line flags provided by the user, as strings. +/// +/// This function is used during ICEs to show more information useful for +/// debugging, since some ICEs only happens with non-default compiler flags +/// (and the users don't always report them). +fn extra_compiler_flags() -> Option<(Vec, bool)> { + let mut args = Vec::new(); + for arg in env::args_os() { + args.push(arg.to_string_lossy().to_string()); + } + + let matches = if let Some(matches) = handle_options(&args) { + matches + } else { + return None; + }; + + let mut result = Vec::new(); + let mut excluded_cargo_defaults = false; + for flag in ICE_REPORT_COMPILER_FLAGS { + let prefix = if flag.len() == 1 { "-" } else { "--" }; + + for content in &matches.opt_strs(flag) { + // Split always returns the first element + let name = if let Some(first) = content.split('=').next() { + first + } else { + &content + }; + + let content = if ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.contains(&name) { + name + } else { + content + }; + + if !ICE_REPORT_COMPILER_FLAGS_EXCLUDE.contains(&name) { + result.push(format!("{}{} {}", prefix, flag, content)); + } else { + excluded_cargo_defaults = true; + } + } + } + + if result.len() > 0 { + Some((result, excluded_cargo_defaults)) + } else { + None + } +} + /// Run a procedure which will detect panics in the compiler and print nicer /// error messages rather than just failing the test. /// @@ -1462,11 +1526,22 @@ pub fn monitor(f: F) { errors::Level::Bug); } - let xs = ["the compiler unexpectedly panicked. this is a bug.".to_string(), - format!("we would appreciate a bug report: {}", BUG_REPORT_URL), - format!("rustc {} running on {}", - option_env!("CFG_VERSION").unwrap_or("unknown_version"), - config::host_triple())]; + let mut xs = vec![ + "the compiler unexpectedly panicked. this is a bug.".to_string(), + format!("we would appreciate a bug report: {}", BUG_REPORT_URL), + format!("rustc {} running on {}", + option_env!("CFG_VERSION").unwrap_or("unknown_version"), + config::host_triple()), + ]; + + if let Some((flags, excluded_cargo_defaults)) = extra_compiler_flags() { + xs.push(format!("compiler flags: {}", flags.join(" "))); + + if excluded_cargo_defaults { + xs.push("some of the compiler flags provided by cargo are hidden".to_string()); + } + } + for note in &xs { handler.emit(&MultiSpan::new(), ¬e, From 70db41cdf74589c957cb930cdd58ebf6bafee5af Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 23 Feb 2018 23:54:24 +0000 Subject: [PATCH 07/19] Handle gdb command failure gracefully in compiletest Previously, if the gdb command was available, but threw an error, compiletest would panic. This is obviously not good. Now, gdb is treated as missing if calling `gdb --version` does not output anything on stdout. --- src/tools/compiletest/src/main.rs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index e3d453a991d80..304143eaa0bff 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -736,17 +736,12 @@ fn analyze_gdb(gdb: Option) -> (Option, Option, bool) { Some(ref s) => s, }; - let version_line = Command::new(gdb) - .arg("--version") - .output() - .map(|output| { - String::from_utf8_lossy(&output.stdout) - .lines() - .next() - .unwrap() - .to_string() - }) - .ok(); + let mut version_line = None; + if let Ok(output) = Command::new(gdb).arg("--version").output() { + if let Some(first_line) = String::from_utf8_lossy(&output.stdout).lines().next() { + version_line = Some(first_line.to_string()); + } + } let version = match version_line { Some(line) => extract_gdb_version(&line), From 23dc694c42954499105072cb2c9a3a0006e56d7e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 23 Feb 2018 18:06:05 +0100 Subject: [PATCH 08/19] Fix auto trait impl rustdoc ice --- src/librustdoc/clean/auto_trait.rs | 2 +- src/librustdoc/clean/mod.rs | 6 +++++- src/test/rustdoc/auto-impl-for-trait.rs | 26 +++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 src/test/rustdoc/auto-impl-for-trait.rs diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index f1bba0e836189..3654de6fb2ed2 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -25,7 +25,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { AdtKind::Struct => Def::Struct, AdtKind::Enum => Def::Enum, AdtKind::Union => Def::Union, - }, + } _ => panic!("Unexpected type {:?}", def_id), }; diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 4543b246b83ad..870b5383852b0 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -3428,7 +3428,11 @@ fn build_deref_target_impls(cx: &DocContext, let primitive = match *target { ResolvedPath { did, .. } if did.is_local() => continue, ResolvedPath { did, .. } => { - ret.extend(inline::build_impls(cx, did, true)); + // We set the last parameter to false to avoid looking for auto-impls for traits + // and therefore avoid an ICE. + // The reason behind this is that auto-traits don't propagate through Deref so + // we're not supposed to synthesise impls for them. + ret.extend(inline::build_impls(cx, did, false)); continue } _ => match target.primitive_type() { diff --git a/src/test/rustdoc/auto-impl-for-trait.rs b/src/test/rustdoc/auto-impl-for-trait.rs new file mode 100644 index 0000000000000..3cd6e7aa4b3d2 --- /dev/null +++ b/src/test/rustdoc/auto-impl-for-trait.rs @@ -0,0 +1,26 @@ +// Copyright 2018 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. + +// Test for https://github.com/rust-lang/rust/issues/48463 issue. + +use std::any::Any; +use std::ops::Deref; + +pub struct AnyValue { + val: Box, +} + +impl Deref for AnyValue { + type Target = Any; + + fn deref(&self) -> &Any { + &*self.val + } +} From e20f7b2ea73fbe0077a565c692a3a6f2e20ff4e3 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 24 Feb 2018 00:31:33 -0800 Subject: [PATCH 09/19] Restrict the Termination impls to simplify stabilization Make a minimal commitment for stabilization. More impls are likely in future, but are not necessary at this time. --- src/libstd/process.rs | 24 ++++++++++++++----- ...2.rs => termination-trait-for-exitcode.rs} | 7 ++++-- 2 files changed, 23 insertions(+), 8 deletions(-) rename src/test/run-pass/rfc-1937-termination-trait/{termination-trait-for-i32.rs => termination-trait-for-exitcode.rs} (81%) diff --git a/src/libstd/process.rs b/src/libstd/process.rs index e25599b8bd871..e5fc33e241c89 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1080,6 +1080,15 @@ impl fmt::Display for ExitStatus { } } +/// This is ridiculously unstable, as it's a completely-punted-upon part +/// of the `?`-in-`main` RFC. It's here only to allow experimenting with +/// returning a code directly from main. It will definitely change +/// drastically before being stabilized, if it doesn't just get deleted. +#[doc(hidden)] +#[derive(Clone, Copy, Debug)] +#[unstable(feature = "process_exitcode_placeholder", issue = "43301")] +pub struct ExitCode(pub i32); + impl Child { /// Forces the child to exit. This is equivalent to sending a /// SIGKILL on unix platforms. @@ -1428,7 +1437,7 @@ impl Termination for () { } #[unstable(feature = "termination_trait_lib", issue = "43301")] -impl Termination for Result { +impl Termination for Result<(), E> { fn report(self) -> i32 { match self { Ok(val) => val.report(), @@ -1442,20 +1451,23 @@ impl Termination for Result { #[unstable(feature = "termination_trait_lib", issue = "43301")] impl Termination for ! { - fn report(self) -> i32 { unreachable!(); } + fn report(self) -> i32 { self } } #[unstable(feature = "termination_trait_lib", issue = "43301")] -impl Termination for bool { +impl Termination for Result { fn report(self) -> i32 { - if self { exit::SUCCESS } else { exit::FAILURE } + let Err(err) = self; + eprintln!("Error: {:?}", err); + exit::FAILURE } } #[unstable(feature = "termination_trait_lib", issue = "43301")] -impl Termination for i32 { +impl Termination for ExitCode { fn report(self) -> i32 { - self + let ExitCode(code) = self; + code } } diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-i32.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs similarity index 81% rename from src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-i32.rs rename to src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs index fa7cb023b447c..30ecc4e89372b 100644 --- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-i32.rs +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs @@ -9,7 +9,10 @@ // except according to those terms. #![feature(termination_trait)] +#![feature(process_exitcode_placeholder)] -fn main() -> i32 { - 0 +use std::process::ExitCode; + +fn main() -> ExitCode { + ExitCode(0) } From 24666443898c142944b4156c22d04130b9db645b Mon Sep 17 00:00:00 2001 From: varkor Date: Sun, 25 Feb 2018 23:05:06 +0000 Subject: [PATCH 10/19] Ensure main() always has external linkage This ensures that the entry function is never elided due to inlining, even with `inline(always)`. Fixes #47783. There were a couple of possible ways of addressing this issue; I simply picked the one that seemed most direct. A warning could be appropriate, but considering using inlining hints in other places it doesn't apply also throws no warnings, and it seems like an edge case anyway, I haven't added one for now. --- src/librustc_mir/monomorphize/item.rs | 5 ++++- src/test/run-pass/inlined-main.rs | 12 ++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/inlined-main.rs diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 549919a2c8919..7c86f5a4b1a84 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -118,10 +118,13 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { match *self.as_mono_item() { MonoItem::Fn(ref instance) => { + let entry_def_id = + tcx.sess.entry_fn.borrow().map(|(id, _)| tcx.hir.local_def_id(id)); // If this function isn't inlined or otherwise has explicit // linkage, then we'll be creating a globally shared version. if self.explicit_linkage(tcx).is_some() || - !instance.def.requires_local(tcx) + !instance.def.requires_local(tcx) || + Some(instance.def_id()) == entry_def_id { return InstantiationMode::GloballyShared { may_conflict: false } } diff --git a/src/test/run-pass/inlined-main.rs b/src/test/run-pass/inlined-main.rs new file mode 100644 index 0000000000000..1288c37d615cd --- /dev/null +++ b/src/test/run-pass/inlined-main.rs @@ -0,0 +1,12 @@ +// Copyright 2018 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. + +#[inline(always)] +fn main() {} From 88de279dca86ed5bfd8a0ab6089ff6af2bfc7c2b Mon Sep 17 00:00:00 2001 From: John Paul Adrian Glaubitz Date: Fri, 23 Feb 2018 22:15:40 +0100 Subject: [PATCH 11/19] bootstrap: Add openssl configuration for powerpc-unknown-linux-gnuspe --- src/bootstrap/native.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 15dd7fabfa58b..653606e5d24b5 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -480,6 +480,7 @@ impl Step for Openssl { "mips64el-unknown-linux-gnuabi64" => "linux64-mips64", "mipsel-unknown-linux-gnu" => "linux-mips32", "powerpc-unknown-linux-gnu" => "linux-ppc", + "powerpc-unknown-linux-gnuspe" => "linux-ppc", "powerpc-unknown-netbsd" => "BSD-generic32", "powerpc64-unknown-linux-gnu" => "linux-ppc64", "powerpc64le-unknown-linux-gnu" => "linux-ppc64le", From a22fbf8a9c89e9e7fd19a50b711e6f9cac21c6b5 Mon Sep 17 00:00:00 2001 From: John Paul Adrian Glaubitz Date: Fri, 23 Feb 2018 22:18:40 +0100 Subject: [PATCH 12/19] librustc_back: Add support for powerpc-linux-gnuspe --- src/librustc_back/target/mod.rs | 1 + .../target/powerpc_unknown_linux_gnuspe.rs | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/librustc_back/target/powerpc_unknown_linux_gnuspe.rs diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index d356105e39314..40b1b10c73b76 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -143,6 +143,7 @@ supported_targets! { ("mips64el-unknown-linux-gnuabi64", mips64el_unknown_linux_gnuabi64), ("mipsel-unknown-linux-gnu", mipsel_unknown_linux_gnu), ("powerpc-unknown-linux-gnu", powerpc_unknown_linux_gnu), + ("powerpc-unknown-linux-gnuspe", powerpc_unknown_linux_gnuspe), ("powerpc64-unknown-linux-gnu", powerpc64_unknown_linux_gnu), ("powerpc64le-unknown-linux-gnu", powerpc64le_unknown_linux_gnu), ("s390x-unknown-linux-gnu", s390x_unknown_linux_gnu), diff --git a/src/librustc_back/target/powerpc_unknown_linux_gnuspe.rs b/src/librustc_back/target/powerpc_unknown_linux_gnuspe.rs new file mode 100644 index 0000000000000..ffcc321749b5a --- /dev/null +++ b/src/librustc_back/target/powerpc_unknown_linux_gnuspe.rs @@ -0,0 +1,35 @@ +// Copyright 2018 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. + +use LinkerFlavor; +use target::{Target, TargetResult}; + +pub fn target() -> TargetResult { + let mut base = super::linux_base::opts(); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mspe".to_string()); + base.max_atomic_width = Some(32); + + // see #36994 + base.exe_allocation_crate = None; + + Ok(Target { + llvm_target: "powerpc-unknown-linux-gnuspe".to_string(), + target_endian: "big".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(), + arch: "powerpc".to_string(), + target_os: "linux".to_string(), + target_env: "gnu".to_string(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: base, + }) +} From b7683a33ce22d4ca13991abd3ad8c4ba1ec19d39 Mon Sep 17 00:00:00 2001 From: John Paul Adrian Glaubitz Date: Fri, 23 Feb 2018 22:22:15 +0100 Subject: [PATCH 13/19] build-manifest: Add powerpc-unknown-linux-gnuspe target --- src/tools/build-manifest/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 0845179532224..49b054f8b9e50 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -83,6 +83,7 @@ static TARGETS: &'static [&'static str] = &[ "mipsel-unknown-linux-gnu", "mipsel-unknown-linux-musl", "powerpc-unknown-linux-gnu", + "powerpc-unknown-linux-gnuspe", "powerpc64-unknown-linux-gnu", "powerpc64le-unknown-linux-gnu", "s390x-unknown-linux-gnu", From 7c84ba43ce28ee681d307f6db5ce72c06c354c5a Mon Sep 17 00:00:00 2001 From: John Paul Adrian Glaubitz Date: Fri, 23 Feb 2018 22:46:48 +0100 Subject: [PATCH 14/19] test: Run atomic-lock-free on powerpc-linux-gnuspe --- src/test/run-make/atomic-lock-free/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/run-make/atomic-lock-free/Makefile b/src/test/run-make/atomic-lock-free/Makefile index 63b8608afc763..a7df821f92d71 100644 --- a/src/test/run-make/atomic-lock-free/Makefile +++ b/src/test/run-make/atomic-lock-free/Makefile @@ -32,6 +32,8 @@ endif ifeq ($(filter powerpc,$(LLVM_COMPONENTS)),powerpc) $(RUSTC) --target=powerpc-unknown-linux-gnu atomic_lock_free.rs nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add + $(RUSTC) --target=powerpc-unknown-linux-gnuspe atomic_lock_free.rs + nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add $(RUSTC) --target=powerpc64-unknown-linux-gnu atomic_lock_free.rs nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add $(RUSTC) --target=powerpc64le-unknown-linux-gnu atomic_lock_free.rs From 5db73fc6dbf9e4ee1a498655cb609efdf5fa93ed Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Thu, 22 Feb 2018 16:37:44 -0700 Subject: [PATCH 15/19] Encode linker arguments as UTF-16 on MSVC platforms --- src/librustc_trans/back/link.rs | 14 ++++++++++- .../long-linker-command-lines-cmd-exe/foo.rs | 25 +++++++++++++++---- .../run-make/long-linker-command-lines/foo.rs | 21 +++++++++++++--- 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index d7c75dea8d04e..8f308e726865c 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -849,7 +849,19 @@ fn exec_linker(sess: &Session, cmd: &mut Command, tmpdir: &Path) args.push_str("\n"); } let file = tmpdir.join("linker-arguments"); - fs::write(&file, args.as_bytes())?; + let bytes = if sess.target.target.options.is_like_msvc { + let mut out = vec![]; + // start the stream with a UTF-16 BOM + for c in vec![0xFEFF].into_iter().chain(args.encode_utf16()) { + // encode in little endian + out.push(c as u8); + out.push((c >> 8) as u8); + } + out + } else { + args.into_bytes() + }; + fs::write(&file, &bytes)?; cmd2.arg(format!("@{}", file.display())); return cmd2.output(); diff --git a/src/test/run-make/long-linker-command-lines-cmd-exe/foo.rs b/src/test/run-make/long-linker-command-lines-cmd-exe/foo.rs index f9168a82e2259..67d8ad0b67255 100644 --- a/src/test/run-make/long-linker-command-lines-cmd-exe/foo.rs +++ b/src/test/run-make/long-linker-command-lines-cmd-exe/foo.rs @@ -36,8 +36,11 @@ fn main() { let ok = tmpdir.join("ok"); let not_ok = tmpdir.join("not_ok"); if env::var("YOU_ARE_A_LINKER").is_ok() { - match env::args().find(|a| a.contains("@")) { - Some(file) => { fs::copy(&file[1..], &ok).unwrap(); } + match env::args_os().find(|a| a.to_string_lossy().contains("@")) { + Some(file) => { + let file = file.to_str().unwrap(); + fs::copy(&file[1..], &ok).unwrap(); + } None => { File::create(¬_ok).unwrap(); } } return @@ -84,11 +87,23 @@ fn main() { continue } - let mut contents = String::new(); - File::open(&ok).unwrap().read_to_string(&mut contents).unwrap(); + let mut contents = Vec::new(); + File::open(&ok).unwrap().read_to_end(&mut contents).unwrap(); for j in 0..i { - assert!(contents.contains(&format!("{}{}", lib_name, j))); + let exp = format!("{}{}", lib_name, j); + let exp = if cfg!(target_env = "msvc") { + let mut out = Vec::with_capacity(exp.len() * 2); + for c in exp.encode_utf16() { + // encode in little endian + out.push(c as u8); + out.push((c >> 8) as u8); + } + out + } else { + exp.into_bytes() + }; + assert!(contents.windows(exp.len()).any(|w| w == &exp[..])); } break diff --git a/src/test/run-make/long-linker-command-lines/foo.rs b/src/test/run-make/long-linker-command-lines/foo.rs index e6fd6b653667f..2ac240982afc4 100644 --- a/src/test/run-make/long-linker-command-lines/foo.rs +++ b/src/test/run-make/long-linker-command-lines/foo.rs @@ -27,7 +27,8 @@ fn main() { let tmpdir = PathBuf::from(env::var_os("TMPDIR").unwrap()); let ok = tmpdir.join("ok"); if env::var("YOU_ARE_A_LINKER").is_ok() { - if let Some(file) = env::args().find(|a| a.contains("@")) { + if let Some(file) = env::args_os().find(|a| a.to_string_lossy().contains("@")) { + let file = file.to_str().expect("non-utf8 file argument"); fs::copy(&file[1..], &ok).unwrap(); } return @@ -76,11 +77,23 @@ fn main() { continue } - let mut contents = String::new(); - File::open(&ok).unwrap().read_to_string(&mut contents).unwrap(); + let mut contents = Vec::new(); + File::open(&ok).unwrap().read_to_end(&mut contents).unwrap(); for j in 0..i { - assert!(contents.contains(&format!("{}{}", lib_name, j))); + let exp = format!("{}{}", lib_name, j); + let exp = if cfg!(target_env = "msvc") { + let mut out = Vec::with_capacity(exp.len() * 2); + for c in exp.encode_utf16() { + // encode in little endian + out.push(c as u8); + out.push((c >> 8) as u8); + } + out + } else { + exp.into_bytes() + }; + assert!(contents.windows(exp.len()).any(|w| w == &exp[..])); } break From 2026453bcf7e2479cd2a1a3602985a2fdd9bc241 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 26 Feb 2018 10:20:14 -0800 Subject: [PATCH 16/19] Add specific target option for returning struct as an integer. --- src/librustc_back/target/apple_base.rs | 1 + src/librustc_back/target/mod.rs | 11 +++++------ src/librustc_back/target/openbsd_base.rs | 2 +- src/librustc_back/target/windows_base.rs | 1 + src/librustc_back/target/windows_msvc_base.rs | 1 + src/librustc_trans/cabi_x86.rs | 3 +-- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/librustc_back/target/apple_base.rs b/src/librustc_back/target/apple_base.rs index 159f93a74c683..72173b62594e9 100644 --- a/src/librustc_back/target/apple_base.rs +++ b/src/librustc_back/target/apple_base.rs @@ -46,6 +46,7 @@ pub fn opts() -> TargetOptions { pre_link_args: LinkArgs::new(), exe_allocation_crate: super::maybe_jemalloc(), has_elf_tls: version >= (10, 7), + abi_return_struct_as_int: true, .. Default::default() } } diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 2872c59157d6b..e734817098043 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -343,9 +343,8 @@ pub struct TargetOptions { pub staticlib_suffix: String, /// OS family to use for conditional compilation. Valid options: "unix", "windows". pub target_family: Option, - /// Whether the target toolchain is like OpenBSD's. - /// Only useful for compiling against OpenBSD, for configuring abi when returning a struct. - pub is_like_openbsd: bool, + /// Whether the target toolchain's ABI supports returning small structs as an integer. + pub abi_return_struct_as_int: bool, /// Whether the target toolchain is like macOS's. Only useful for compiling against iOS/macOS, /// in particular running dsymutil and some other stuff like `-dead_strip`. Defaults to false. pub is_like_osx: bool, @@ -501,7 +500,7 @@ impl Default for TargetOptions { staticlib_prefix: "lib".to_string(), staticlib_suffix: ".a".to_string(), target_family: None, - is_like_openbsd: false, + abi_return_struct_as_int: false, is_like_osx: false, is_like_solaris: false, is_like_windows: false, @@ -756,7 +755,7 @@ impl Target { key!(staticlib_prefix); key!(staticlib_suffix); key!(target_family, optional); - key!(is_like_openbsd, bool); + key!(abi_return_struct_as_int, bool); key!(is_like_osx, bool); key!(is_like_solaris, bool); key!(is_like_windows, bool); @@ -954,7 +953,7 @@ impl ToJson for Target { target_option_val!(staticlib_prefix); target_option_val!(staticlib_suffix); target_option_val!(target_family); - target_option_val!(is_like_openbsd); + target_option_val!(abi_return_struct_as_int); target_option_val!(is_like_osx); target_option_val!(is_like_solaris); target_option_val!(is_like_windows); diff --git a/src/librustc_back/target/openbsd_base.rs b/src/librustc_back/target/openbsd_base.rs index ab421dec7807f..311e260ee3f34 100644 --- a/src/librustc_back/target/openbsd_base.rs +++ b/src/librustc_back/target/openbsd_base.rs @@ -31,7 +31,7 @@ pub fn opts() -> TargetOptions { target_family: Some("unix".to_string()), linker_is_gnu: true, has_rpath: true, - is_like_openbsd: true, + abi_return_struct_as_int: true, pre_link_args: args, position_independent_executables: true, eliminate_frame_pointer: false, // FIXME 43575 diff --git a/src/librustc_back/target/windows_base.rs b/src/librustc_back/target/windows_base.rs index cc40b8b052983..30038400f6c81 100644 --- a/src/librustc_back/target/windows_base.rs +++ b/src/librustc_back/target/windows_base.rs @@ -101,6 +101,7 @@ pub fn opts() -> TargetOptions { "rsend.o".to_string() ], custom_unwind_resume: true, + abi_return_struct_as_int: true, .. Default::default() } diff --git a/src/librustc_back/target/windows_msvc_base.rs b/src/librustc_back/target/windows_msvc_base.rs index 64df6624dd1c2..e0bf36ee4077e 100644 --- a/src/librustc_back/target/windows_msvc_base.rs +++ b/src/librustc_back/target/windows_msvc_base.rs @@ -34,6 +34,7 @@ pub fn opts() -> TargetOptions { pre_link_args: args, crt_static_allows_dylibs: true, crt_static_respected: true, + abi_return_struct_as_int: true, .. Default::default() } diff --git a/src/librustc_trans/cabi_x86.rs b/src/librustc_trans/cabi_x86.rs index 60347ba0945f9..b14558448067c 100644 --- a/src/librustc_trans/cabi_x86.rs +++ b/src/librustc_trans/cabi_x86.rs @@ -52,8 +52,7 @@ pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, // http://www.angelcode.com/dev/callconv/callconv.html // Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp let t = &cx.sess().target.target; - if t.options.is_like_osx || t.options.is_like_windows - || t.options.is_like_openbsd { + if t.options.abi_return_struct_as_int { // According to Clang, everyone but MSVC returns single-element // float aggregates directly in a floating-point register. if !t.options.is_like_msvc && is_single_fp_element(cx, fty.ret.layout) { From 279e5b0a48cd9883a6e43571a9de25de06bdde22 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 26 Feb 2018 10:21:35 -0800 Subject: [PATCH 17/19] FreeBSD uses Clang which can return small structs as an integer. --- src/librustc_back/target/freebsd_base.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_back/target/freebsd_base.rs b/src/librustc_back/target/freebsd_base.rs index a0f84a6ab0495..291b22768998c 100644 --- a/src/librustc_back/target/freebsd_base.rs +++ b/src/librustc_back/target/freebsd_base.rs @@ -36,6 +36,7 @@ pub fn opts() -> TargetOptions { eliminate_frame_pointer: false, // FIXME 43575 relro_level: RelroLevel::Full, exe_allocation_crate: super::maybe_jemalloc(), + abi_return_struct_as_int: true, .. Default::default() } } From 9c80019e6c14ba7ecd00f896cfb4bdcce0066101 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Mon, 26 Feb 2018 15:07:24 -0700 Subject: [PATCH 18/19] Fix error-format argument to x.py --- src/bootstrap/compile.rs | 4 ++++ src/bootstrap/flags.rs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index c85b04ddc0245..2c9f0ddb6c33d 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -1007,6 +1007,10 @@ pub fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path, is_check: boo continue }; if json["reason"].as_str() != Some("compiler-artifact") { + if build.config.rustc_error_format.as_ref().map_or(false, |e| e == "json") { + // most likely not a cargo message, so let's send it out as well + println!("{}", line); + } continue } for filename in json["filenames"].as_array().unwrap() { diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 8ca5910a11c0d..af50ad1e96b9f 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -119,7 +119,7 @@ To learn more about a subcommand, run `./x.py -h`"); opts.optopt("", "src", "path to the root of the rust checkout", "DIR"); opts.optopt("j", "jobs", "number of jobs to run in parallel", "JOBS"); opts.optflag("h", "help", "print this help message"); - opts.optflag("", "error-format", "rustc error format"); + opts.optopt("", "error-format", "rustc error format", "FORMAT"); // fn usage() let usage = |exit_code: i32, opts: &Options, subcommand_help: &str, extra_help: &str| -> ! { From c133a082a87ac2cb520688e33ed17aa794cab368 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 26 Feb 2018 15:58:16 -0800 Subject: [PATCH 19/19] rustc: Rename `bmi` feature to `bmi1` This is what [Intel calls it][bmi1] and will [remove a special case][stdsimd] when verifying intrinsics in stdsimd. [bmi1]: https://software.intel.com/sites/landingpage/IntrinsicsGuide/#othertechs=BMI1 [stdsimd]: https://github.com/rust-lang-nursery/stdsimd/blob/bed25b2a9f3b28e6ea80de6d87842f739a2e2d58/crates/stdsimd-verify/tests/x86-intel.rs#L252-L258 --- src/librustc_trans/llvm_util.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs index 6271dcdfb2433..00ac9d802457c 100644 --- a/src/librustc_trans/llvm_util.rs +++ b/src/librustc_trans/llvm_util.rs @@ -87,7 +87,7 @@ const X86_WHITELIST: &'static [&'static str] = &["aes", "avx", "avx2", "avx512bw "avx512cd", "avx512dq", "avx512er", "avx512f", "avx512ifma", "avx512pf", "avx512vbmi", "avx512vl", "avx512vpopcntdq", - "bmi", "bmi2", "fma", "fxsr", + "bmi1", "bmi2", "fma", "fxsr", "lzcnt", "mmx", "pclmulqdq", "popcnt", "rdrand", "rdseed", "sse", "sse2", "sse3", "sse4.1", @@ -108,6 +108,7 @@ pub fn to_llvm_feature(s: &str) -> &str { match s { "pclmulqdq" => "pclmul", "rdrand" => "rdrnd", + "bmi1" => "bmi", s => s, } }