From 37771d42d72d80a3025cf1bbf2aa58df79669a4e Mon Sep 17 00:00:00 2001 From: oberien Date: Thu, 18 Jan 2018 20:49:32 +0100 Subject: [PATCH 01/24] Specialize StepBy::nth --- src/libcore/iter/mod.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 06c29b47bf921..443b1567e1b4e 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -694,6 +694,18 @@ impl Iterator for StepBy where I: Iterator { (f(inner_hint.0), inner_hint.1.map(f)) } } + + #[inline] + fn nth(&mut self, mut n: usize) -> Option { + if self.first_take { + if n == 0 { + self.first_take = false; + return self.iter.next() + } + n -= 1; + } + self.iter.nth(n * self.step) + } } // StepBy can only make the iterator shorter, so the len will still fit. From 5850f0b742430a1b1b5ae7d2491dce6ca10e20d3 Mon Sep 17 00:00:00 2001 From: oberien Date: Fri, 19 Jan 2018 14:55:20 +0100 Subject: [PATCH 02/24] Fix off-by-ones --- src/libcore/iter/mod.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 443b1567e1b4e..33c00989fd286 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -698,13 +698,16 @@ impl Iterator for StepBy where I: Iterator { #[inline] fn nth(&mut self, mut n: usize) -> Option { if self.first_take { + self.first_take = false; + let first = self.iter.next(); if n == 0 { - self.first_take = false; - return self.iter.next() + return first; } n -= 1; } - self.iter.nth(n * self.step) + // n and self.step are indices, thus we need to add 1 before multiplying. + // After that we need to subtract 1 from the result to convert it back to an index. + self.iter.nth((n + 1) * (self.step + 1) - 1) } } From d33cc12eed3df459db3c9ae2dd89df9cc6e45dd6 Mon Sep 17 00:00:00 2001 From: oberien Date: Fri, 19 Jan 2018 14:55:34 +0100 Subject: [PATCH 03/24] Unit Tests --- src/libcore/tests/iter.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 8997cf9c6bff9..e887499165966 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -161,6 +161,24 @@ fn test_iterator_step_by() { assert_eq!(it.next(), None); } +#[test] +fn test_iterator_step_by_nth() { + let mut it = (0..16).step_by(5); + assert_eq!(it.nth(0), Some(0)); + assert_eq!(it.nth(0), Some(5)); + assert_eq!(it.nth(0), Some(10)); + assert_eq!(it.nth(0), Some(15)); + assert_eq!(it.nth(0), None); + + let it = (0..18).step_by(5); + assert_eq!(it.clone().nth(0), Some(0)); + assert_eq!(it.clone().nth(1), Some(5)); + assert_eq!(it.clone().nth(2), Some(10)); + assert_eq!(it.clone().nth(3), Some(15)); + assert_eq!(it.clone().nth(4), None); + assert_eq!(it.clone().nth(42), None); +} + #[test] #[should_panic] fn test_iterator_step_by_zero() { From f08dec114f6008cb7a906ffd55c221fd30d70987 Mon Sep 17 00:00:00 2001 From: oberien Date: Fri, 19 Jan 2018 21:07:01 +0100 Subject: [PATCH 04/24] Handle Overflow --- src/libcore/iter/mod.rs | 31 ++++++++++++++++++++++++--- src/libcore/tests/iter.rs | 44 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 33c00989fd286..57e7e03a6cebc 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -705,9 +705,34 @@ impl Iterator for StepBy where I: Iterator { } n -= 1; } - // n and self.step are indices, thus we need to add 1 before multiplying. - // After that we need to subtract 1 from the result to convert it back to an index. - self.iter.nth((n + 1) * (self.step + 1) - 1) + // n and self.step are indices, we need to add 1 to get the amount of elements + // When calling `.nth`, we need to subtract 1 again to convert back to an index + // step + 1 can't overflow because `.step_by` sets `self.step` to `step - 1` + let mut step = self.step + 1; + // n + 1 could overflow + // thus, if n is usize::MAX, instead of adding one, we call .nth(step) + if n == usize::MAX { + self.iter.nth(step - 1); + } else { + n += 1; + } + + // overflow handling + while n.checked_mul(step).is_none() { + let div_n = usize::MAX / n; + let div_step = usize::MAX / step; + let nth_n = div_n * n; + let nth_step = div_step * step; + let nth = if nth_n > nth_step { + step -= div_n; + nth_n + } else { + n -= div_step; + nth_step + }; + self.iter.nth(nth - 1); + } + self.iter.nth(n * step - 1) } } diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index e887499165966..e52e119ff59b9 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -179,6 +179,50 @@ fn test_iterator_step_by_nth() { assert_eq!(it.clone().nth(42), None); } +#[test] +fn test_iterator_step_by_nth_overflow() { + #[cfg(target_pointer_width = "8")] + type Bigger = u16; + #[cfg(target_pointer_width = "16")] + type Bigger = u32; + #[cfg(target_pointer_width = "32")] + type Bigger = u64; + #[cfg(target_pointer_width = "64")] + type Bigger = u128; + + #[derive(Clone)] + struct Test(Bigger); + impl<'a> Iterator for &'a mut Test { + type Item = i32; + fn next(&mut self) -> Option { Some(21) } + fn nth(&mut self, n: usize) -> Option { + self.0 += n as Bigger + 1; + Some(42) + } + } + + let mut it = Test(0); + let root = usize::MAX >> (::std::mem::size_of::() * 8 / 2); + let n = root + 20; + (&mut it).step_by(n).nth(n); + assert_eq!(it.0, n as Bigger * n as Bigger); + + // large step + let mut it = Test(0); + (&mut it).step_by(usize::MAX).nth(5); + assert_eq!(it.0, (usize::MAX as Bigger) * 5); + + // n + 1 overflows + let mut it = Test(0); + (&mut it).step_by(2).nth(usize::MAX); + assert_eq!(it.0, (usize::MAX as Bigger) * 2); + + // n + 1 overflows + let mut it = Test(0); + (&mut it).step_by(1).nth(usize::MAX); + assert_eq!(it.0, (usize::MAX as Bigger) * 1); +} + #[test] #[should_panic] fn test_iterator_step_by_zero() { From f72b7f7c86b16fe8b76c4eb02052943dd6ef1ab2 Mon Sep 17 00:00:00 2001 From: oberien Date: Fri, 19 Jan 2018 22:34:22 +0100 Subject: [PATCH 05/24] Optimize StepBy::nth overflow handling --- src/libcore/iter/mod.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 57e7e03a6cebc..5923e6dc3ee28 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -307,6 +307,7 @@ use fmt; use iter_private::TrustedRandomAccess; use ops::Try; use usize; +use intrinsics; #[stable(feature = "rust1", since = "1.0.0")] pub use self::iterator::Iterator; @@ -718,7 +719,11 @@ impl Iterator for StepBy where I: Iterator { } // overflow handling - while n.checked_mul(step).is_none() { + loop { + let mul = n.checked_mul(step); + if unsafe { intrinsics::likely(mul.is_some())} { + return self.iter.nth(mul.unwrap() - 1); + } let div_n = usize::MAX / n; let div_step = usize::MAX / step; let nth_n = div_n * n; @@ -732,7 +737,6 @@ impl Iterator for StepBy where I: Iterator { }; self.iter.nth(nth - 1); } - self.iter.nth(n * step - 1) } } From 4a0da4cf2c7a2b5903fd1b8bc124f8963ce1b535 Mon Sep 17 00:00:00 2001 From: oberien Date: Sat, 20 Jan 2018 00:41:21 +0100 Subject: [PATCH 06/24] Spacing --- src/libcore/iter/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 5923e6dc3ee28..7314fac282b66 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -721,7 +721,7 @@ impl Iterator for StepBy where I: Iterator { // overflow handling loop { let mul = n.checked_mul(step); - if unsafe { intrinsics::likely(mul.is_some())} { + if unsafe { intrinsics::likely(mul.is_some()) } { return self.iter.nth(mul.unwrap() - 1); } let div_n = usize::MAX / n; From c6377f8e17cd7f3cf906397f3f48b522b0521471 Mon Sep 17 00:00:00 2001 From: Ryan Cumming Date: Tue, 23 Jan 2018 19:08:16 +1100 Subject: [PATCH 07/24] Avoid underflow in render_source_line While testing rust-lang/rust#47655 I was able to make the compiler panic when it's compiled with debug assertions: ```shell > rustc /dev/null --crate-type proc-macro error: internal compiler error: unexpected panic note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports note: rustc 1.25.0-dev running on x86_64-apple-darwin note: run with `RUST_BACKTRACE=1` for a backtrace thread 'rustc' panicked at 'attempt to subtract with overflow', librustc_errors/emitter.rs:287:49 ``` Without debug assertions the following warning is emitted: ```shell > rustc /dev/null --crate-type proc-macro warning: unused variable: `registrar` --> /dev/null:0:1 | | = note: #[warn(unused_variables)] on by default = note: to avoid this warning, consider using `_registrar` instead ``` The panic is due to the unused variable warning being spanned to `/dev/null:0:1`. When `render_source_line` subtracts 1 from the line number to look up the source line it panics due to underflow. Without debug assertions this would wrap and cause us to return a blank string instead. Fix by explicitly testing for 0 and exiting early. I'm unsure how to automatically test this now that rust-lang/rust#46655 has been approved. --- src/librustc_errors/emitter.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 58f851aea3817..62ae8d855897e 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -284,6 +284,10 @@ impl EmitterWriter { line: &Line, width_offset: usize, code_offset: usize) -> Vec<(usize, Style)> { + if line.line_index == 0 { + return Vec::new(); + } + let source_string = match file.get_line(line.line_index - 1) { Some(s) => s, None => return Vec::new(), From 0984ee3051f446e02e85237349c17954314676fa Mon Sep 17 00:00:00 2001 From: Araam Borhanian Date: Fri, 26 Jan 2018 21:10:35 -0500 Subject: [PATCH 08/24] Adding ICH to the glossary. --- src/librustc/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc/README.md b/src/librustc/README.md index ddf71a06d607c..722456a76ce59 100644 --- a/src/librustc/README.md +++ b/src/librustc/README.md @@ -176,6 +176,7 @@ pointers for understanding them better. - `'gcx` -- the lifetime of the global arena (see `librustc/ty`). - generics -- the set of generic type parameters defined on a type or item - ICE -- internal compiler error. When the compiler crashes. +- ICH -- incremental compilation hash. - infcx -- the inference context (see `librustc/infer`) - MIR -- the **Mid-level IR** that is created after type-checking for use by borrowck and trans. Defined in the `src/librustc/mir/` module, but much of the code that manipulates it is From 043d4615f2a9ff44d7b3726de51fa9e3bfb60d7e Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Sun, 28 Jan 2018 20:48:54 -0500 Subject: [PATCH 09/24] use correct casing for rename suggestions If the original name is uppercase, use camel case. Otherwise, use snake case. --- src/librustc_resolve/lib.rs | 12 +++++++++--- src/test/ui/blind-item-item-shadow.stderr | 4 ++-- src/test/ui/double-import.stderr | 4 ++-- src/test/ui/imports/duplicate.stderr | 4 ++-- src/test/ui/issue-26886.stderr | 4 ++-- src/test/ui/resolve-conflict-item-vs-import.stderr | 4 ++-- ...-extern-crate-rename-suggestion-formatting.stderr | 2 +- src/test/ui/use-mod.stderr | 2 +- 8 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index ecf3c9e42d58f..2da4bfedd3a17 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3998,14 +3998,20 @@ impl<'a> Resolver<'a> { if let (Ok(snippet), false) = (cm.span_to_snippet(binding.span), binding.is_renamed_extern_crate()) { + let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() { + format!("Other{}", name) + } else { + format!("other_{}", name) + }; + err.span_suggestion(binding.span, rename_msg, if snippet.ends_with(';') { - format!("{} as Other{};", + format!("{} as {};", &snippet[..snippet.len()-1], - name) + suggested_name) } else { - format!("{} as Other{}", snippet, name) + format!("{} as {}", snippet, suggested_name) }); } else { err.span_label(binding.span, rename_msg); diff --git a/src/test/ui/blind-item-item-shadow.stderr b/src/test/ui/blind-item-item-shadow.stderr index 855b3799eb5db..d3588be266975 100644 --- a/src/test/ui/blind-item-item-shadow.stderr +++ b/src/test/ui/blind-item-item-shadow.stderr @@ -10,8 +10,8 @@ error[E0255]: the name `foo` is defined multiple times = note: `foo` must be defined only once in the type namespace of this module help: You can use `as` to change the binding name of the import | -13 | use foo::foo as Otherfoo; - | ^^^^^^^^^^^^^^^^^^^^ +13 | use foo::foo as other_foo; + | ^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/double-import.stderr b/src/test/ui/double-import.stderr index fcd3f2696f200..2a0f9ee34f2be 100644 --- a/src/test/ui/double-import.stderr +++ b/src/test/ui/double-import.stderr @@ -9,8 +9,8 @@ error[E0252]: the name `foo` is defined multiple times = note: `foo` must be defined only once in the value namespace of this module help: You can use `as` to change the binding name of the import | -23 | use sub2::foo as Otherfoo; //~ ERROR the name `foo` is defined multiple times - | ^^^^^^^^^^^^^^^^^^^^^ +23 | use sub2::foo as other_foo; //~ ERROR the name `foo` is defined multiple times + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/imports/duplicate.stderr b/src/test/ui/imports/duplicate.stderr index a74401314a18c..6e5b91a11c900 100644 --- a/src/test/ui/imports/duplicate.stderr +++ b/src/test/ui/imports/duplicate.stderr @@ -9,8 +9,8 @@ error[E0252]: the name `foo` is defined multiple times = note: `foo` must be defined only once in the value namespace of this module help: You can use `as` to change the binding name of the import | -25 | use a::foo as Otherfoo; //~ ERROR the name `foo` is defined multiple times - | ^^^^^^^^^^^^^^^^^^ +25 | use a::foo as other_foo; //~ ERROR the name `foo` is defined multiple times + | ^^^^^^^^^^^^^^^^^^^ error[E0659]: `foo` is ambiguous --> $DIR/duplicate.rs:56:9 diff --git a/src/test/ui/issue-26886.stderr b/src/test/ui/issue-26886.stderr index cb2eca87068f8..e6424e535ee32 100644 --- a/src/test/ui/issue-26886.stderr +++ b/src/test/ui/issue-26886.stderr @@ -24,8 +24,8 @@ error[E0252]: the name `sync` is defined multiple times = note: `sync` must be defined only once in the type namespace of this module help: You can use `as` to change the binding name of the import | -14 | use std::sync as Othersync; //~ ERROR the name `sync` is defined multiple times - | ^^^^^^^^^^^^^^^^^^^^^^ +14 | use std::sync as other_sync; //~ ERROR the name `sync` is defined multiple times + | ^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/resolve-conflict-item-vs-import.stderr b/src/test/ui/resolve-conflict-item-vs-import.stderr index 03ef66681e440..e2245b8a8b10a 100644 --- a/src/test/ui/resolve-conflict-item-vs-import.stderr +++ b/src/test/ui/resolve-conflict-item-vs-import.stderr @@ -10,8 +10,8 @@ error[E0255]: the name `transmute` is defined multiple times = note: `transmute` must be defined only once in the value namespace of this module help: You can use `as` to change the binding name of the import | -11 | use std::mem::transmute as Othertransmute; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +11 | use std::mem::transmute as other_transmute; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr b/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr index d2ac15f7ffcb3..01dba62a8511d 100644 --- a/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr +++ b/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr @@ -7,7 +7,7 @@ error[E0259]: the name `std` is defined multiple times = note: `std` must be defined only once in the type namespace of this module help: You can use `as` to change the binding name of the import | -11 | extern crate std as Otherstd; +11 | extern crate std as other_std; | error: aborting due to previous error diff --git a/src/test/ui/use-mod.stderr b/src/test/ui/use-mod.stderr index bb64909e64a0c..1c9f306f493db 100644 --- a/src/test/ui/use-mod.stderr +++ b/src/test/ui/use-mod.stderr @@ -25,7 +25,7 @@ error[E0252]: the name `bar` is defined multiple times = note: `bar` must be defined only once in the type namespace of this module help: You can use `as` to change the binding name of the import | -15 | self as Otherbar +15 | self as other_bar | error: aborting due to 3 previous errors From 81e49597bf3fe4fb2dfe9f60325079ff6bb916a0 Mon Sep 17 00:00:00 2001 From: penpalperson <16357077+penpalperson@users.noreply.github.com> Date: Sun, 28 Jan 2018 21:55:05 -0700 Subject: [PATCH 10/24] Added inline to fmt for debug implementations of primitives. --- src/libcore/array.rs | 1 + src/libcore/fmt/float.rs | 1 + src/libcore/fmt/mod.rs | 10 ++++++++++ src/libcore/fmt/num.rs | 1 + src/libcore/ptr.rs | 1 + 5 files changed, 14 insertions(+) diff --git a/src/libcore/array.rs b/src/libcore/array.rs index 3d24f8902bd83..28f1da27bdb57 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -185,6 +185,7 @@ macro_rules! array_impls { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for [T; $N] { + #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&&self[..], f) } diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index 03e7a9a49d8a7..24ffe8c688885 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -125,6 +125,7 @@ macro_rules! floating { ($ty:ident) => ( #[stable(feature = "rust1", since = "1.0.0")] impl Debug for $ty { + #[inline] fn fmt(&self, fmt: &mut Formatter) -> Result { float_to_decimal_common(fmt, self, true, 1) } diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 65aacb23bd768..b4d23d153d800 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1558,10 +1558,12 @@ macro_rules! fmt_refs { $( #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T: ?Sized + $tr> $tr for &'a T { + #[inline] fn fmt(&self, f: &mut Formatter) -> Result { $tr::fmt(&**self, f) } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T: ?Sized + $tr> $tr for &'a mut T { + #[inline] fn fmt(&self, f: &mut Formatter) -> Result { $tr::fmt(&**self, f) } } )* @@ -1586,6 +1588,7 @@ impl Display for ! { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for bool { + #[inline] fn fmt(&self, f: &mut Formatter) -> Result { Display::fmt(self, f) } @@ -1600,6 +1603,7 @@ impl Display for bool { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for str { + #[inline] fn fmt(&self, f: &mut Formatter) -> Result { f.write_char('"')?; let mut from = 0; @@ -1628,6 +1632,7 @@ impl Display for str { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for char { + #[inline] fn fmt(&self, f: &mut Formatter) -> Result { f.write_char('\'')?; for c in self.escape_debug() { @@ -1701,10 +1706,12 @@ impl<'a, T: ?Sized> Pointer for &'a mut T { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for *const T { + #[inline] fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) } } #[stable(feature = "rust1", since = "1.0.0")] impl Debug for *mut T { + #[inline] fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) } } @@ -1718,6 +1725,7 @@ macro_rules! tuple { #[stable(feature = "rust1", since = "1.0.0")] impl<$($name:Debug),*> Debug for ($($name,)*) where last_type!($($name,)+): ?Sized { #[allow(non_snake_case, unused_assignments, deprecated)] + #[inline] fn fmt(&self, f: &mut Formatter) -> Result { let mut builder = f.debug_tuple(""); let ($(ref $name,)*) = *self; @@ -1741,6 +1749,7 @@ tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, } #[stable(feature = "rust1", since = "1.0.0")] impl Debug for [T] { + #[inline] fn fmt(&self, f: &mut Formatter) -> Result { f.debug_list().entries(self.iter()).finish() } @@ -1748,6 +1757,7 @@ impl Debug for [T] { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for () { + #[inline] fn fmt(&self, f: &mut Formatter) -> Result { f.pad("()") } diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index ee989854a3772..2992e7cf8db34 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -157,6 +157,7 @@ macro_rules! debug { ($T:ident) => { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for $T { + #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(self, f) } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index fab5832d905df..3e162afd64909 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2202,6 +2202,7 @@ macro_rules! fnptr_impls_safety_abi { #[stable(feature = "fnptr_impls", since = "1.4.0")] impl fmt::Debug for $FnTy { + #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Pointer::fmt(&(*self as *const ()), f) } From c06c707fbfdfa074026b6b09a5da9168e247d156 Mon Sep 17 00:00:00 2001 From: Christopher Durham Date: Mon, 29 Jan 2018 02:43:44 -0500 Subject: [PATCH 11/24] Fix regression: account for trait methods in arg count mismatch error --- src/librustc/traits/error_reporting.rs | 5 +++++ src/test/ui/issue-47706-trait.rs | 16 ++++++++++++++++ src/test/ui/issue-47706-trait.stderr | 12 ++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 src/test/ui/issue-47706-trait.rs create mode 100644 src/test/ui/issue-47706-trait.stderr diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 42200a3a44728..d65becb912a3c 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -831,6 +831,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { span, node: hir::ImplItemKind::Method(hir::MethodSig { ref decl, .. }, _), .. + }) | + hir::map::NodeTraitItem(&hir::TraitItem { + span, + node: hir::TraitItemKind::Method(hir::MethodSig { ref decl, .. }, _), + .. }) => { (self.tcx.sess.codemap().def_span(span), decl.inputs.iter() .map(|arg| match arg.clone().into_inner().node { diff --git a/src/test/ui/issue-47706-trait.rs b/src/test/ui/issue-47706-trait.rs new file mode 100644 index 0000000000000..86a9da49a054a --- /dev/null +++ b/src/test/ui/issue-47706-trait.rs @@ -0,0 +1,16 @@ +// 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. + +trait T { + fn f(&self, _: ()) { + None::<()>.map(Self::f); + } + //~^^ ERROR function is expected to take a single 0-tuple as argument +} diff --git a/src/test/ui/issue-47706-trait.stderr b/src/test/ui/issue-47706-trait.stderr new file mode 100644 index 0000000000000..320e98dee4acf --- /dev/null +++ b/src/test/ui/issue-47706-trait.stderr @@ -0,0 +1,12 @@ +error[E0601]: main function not found + +error[E0593]: function is expected to take a single 0-tuple as argument, but it takes 2 distinct arguments + --> $DIR/issue-47706-trait.rs:13:20 + | +12 | fn f(&self, _: ()) { + | ------------------ takes 2 distinct arguments +13 | None::<()>.map(Self::f); + | ^^^ expected function that takes a single 0-tuple as argument + +error: aborting due to 2 previous errors + From e9d70417cae7fcb08323351d9388b65b39560156 Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Tue, 23 Jan 2018 14:47:30 +0000 Subject: [PATCH 12/24] std: use more portable error number in from_raw_os_error docs On MIPS, error number 98 is not EADDRINUSE (it is EPROTOTYPE). To fix the resulting test failure this causes, use a more portable error number in the example documentation. EINVAL shold be more reliable because it was defined in the original Unix as 22 so hopefully most derivatives have defined it the same way. --- src/libstd/io/error.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs index f0b41f30251e0..bdd675e6e2b85 100644 --- a/src/libstd/io/error.rs +++ b/src/libstd/io/error.rs @@ -292,8 +292,8 @@ impl Error { /// # if cfg!(target_os = "linux") { /// use std::io; /// - /// let error = io::Error::from_raw_os_error(98); - /// assert_eq!(error.kind(), io::ErrorKind::AddrInUse); + /// let error = io::Error::from_raw_os_error(22); + /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput); /// # } /// ``` /// @@ -303,8 +303,8 @@ impl Error { /// # if cfg!(windows) { /// use std::io; /// - /// let error = io::Error::from_raw_os_error(10048); - /// assert_eq!(error.kind(), io::ErrorKind::AddrInUse); + /// let error = io::Error::from_raw_os_error(10022); + /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput); /// # } /// ``` #[stable(feature = "rust1", since = "1.0.0")] From d8e4142bd442c53b6ddc79ea0dd2d90cf550462e Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Wed, 24 Jan 2018 11:50:10 +0000 Subject: [PATCH 13/24] rustc_trans: clobber $1 (aka $at) on mips This copies what clang does. There is a long explanation as to why this is needed in the clang source (tools/clang/lib/Basic/Targets/Mips.h). --- src/librustc_trans/asm.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustc_trans/asm.rs b/src/librustc_trans/asm.rs index c7be0c4e67d71..751f8148a2a90 100644 --- a/src/librustc_trans/asm.rs +++ b/src/librustc_trans/asm.rs @@ -59,8 +59,9 @@ pub fn trans_inline_asm<'a, 'tcx>( // Default per-arch clobbers // Basically what clang does let arch_clobbers = match &bx.sess().target.target.arch[..] { - "x86" | "x86_64" => vec!["~{dirflag}", "~{fpsr}", "~{flags}"], - _ => Vec::new() + "x86" | "x86_64" => vec!["~{dirflag}", "~{fpsr}", "~{flags}"], + "mips" | "mips64" => vec!["~{$1}"], + _ => Vec::new() }; let all_constraints = From deba3890c59a3122acb6373fc09a68d84240d471 Mon Sep 17 00:00:00 2001 From: penpalperson <16357077+penpalperson@users.noreply.github.com> Date: Tue, 30 Jan 2018 05:31:38 -0700 Subject: [PATCH 14/24] Changed back inline markings. --- src/libcore/array.rs | 1 - src/libcore/fmt/float.rs | 1 - src/libcore/fmt/mod.rs | 8 -------- src/libcore/ptr.rs | 1 - 4 files changed, 11 deletions(-) diff --git a/src/libcore/array.rs b/src/libcore/array.rs index 28f1da27bdb57..3d24f8902bd83 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -185,7 +185,6 @@ macro_rules! array_impls { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for [T; $N] { - #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&&self[..], f) } diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index 24ffe8c688885..03e7a9a49d8a7 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -125,7 +125,6 @@ macro_rules! floating { ($ty:ident) => ( #[stable(feature = "rust1", since = "1.0.0")] impl Debug for $ty { - #[inline] fn fmt(&self, fmt: &mut Formatter) -> Result { float_to_decimal_common(fmt, self, true, 1) } diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index b4d23d153d800..6c8a1c3062b00 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1558,12 +1558,10 @@ macro_rules! fmt_refs { $( #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T: ?Sized + $tr> $tr for &'a T { - #[inline] fn fmt(&self, f: &mut Formatter) -> Result { $tr::fmt(&**self, f) } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T: ?Sized + $tr> $tr for &'a mut T { - #[inline] fn fmt(&self, f: &mut Formatter) -> Result { $tr::fmt(&**self, f) } } )* @@ -1603,7 +1601,6 @@ impl Display for bool { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for str { - #[inline] fn fmt(&self, f: &mut Formatter) -> Result { f.write_char('"')?; let mut from = 0; @@ -1632,7 +1629,6 @@ impl Display for str { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for char { - #[inline] fn fmt(&self, f: &mut Formatter) -> Result { f.write_char('\'')?; for c in self.escape_debug() { @@ -1706,12 +1702,10 @@ impl<'a, T: ?Sized> Pointer for &'a mut T { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for *const T { - #[inline] fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) } } #[stable(feature = "rust1", since = "1.0.0")] impl Debug for *mut T { - #[inline] fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) } } @@ -1725,7 +1719,6 @@ macro_rules! tuple { #[stable(feature = "rust1", since = "1.0.0")] impl<$($name:Debug),*> Debug for ($($name,)*) where last_type!($($name,)+): ?Sized { #[allow(non_snake_case, unused_assignments, deprecated)] - #[inline] fn fmt(&self, f: &mut Formatter) -> Result { let mut builder = f.debug_tuple(""); let ($(ref $name,)*) = *self; @@ -1749,7 +1742,6 @@ tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, } #[stable(feature = "rust1", since = "1.0.0")] impl Debug for [T] { - #[inline] fn fmt(&self, f: &mut Formatter) -> Result { f.debug_list().entries(self.iter()).finish() } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 3e162afd64909..fab5832d905df 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2202,7 +2202,6 @@ macro_rules! fnptr_impls_safety_abi { #[stable(feature = "fnptr_impls", since = "1.4.0")] impl fmt::Debug for $FnTy { - #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Pointer::fmt(&(*self as *const ()), f) } From f6a6d84031ef265756d249aa55bf1db25ae1993f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 30 Jan 2018 14:20:20 +0100 Subject: [PATCH 15/24] Update associated constants error message --- src/librustc_const_eval/check_match.rs | 11 +++++++++-- src/librustc_const_eval/pattern.rs | 11 ++++++++++- .../associated-const-type-parameter-arms.rs | 7 +++++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index fd171b8992470..ae53ed0e1140d 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -127,13 +127,16 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> { } } + impl<'a, 'tcx> PatternContext<'a, 'tcx> { fn report_inlining_errors(&self, pat_span: Span) { for error in &self.errors { match *error { PatternError::StaticInPattern(span) => { - span_err!(self.tcx.sess, span, E0158, - "statics cannot be referenced in patterns"); + self.span_e0158(span, "statics cannot be referenced in patterns") + } + PatternError::AssociatedConstInPattern(span) => { + self.span_e0158(span, "associated consts cannot be referenced in patterns") } PatternError::ConstEval(ref err) => { err.report(self.tcx, pat_span, "pattern"); @@ -141,6 +144,10 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { } } } + + fn span_e0158(&self, span: Span, text: &str) { + span_err!(self.tcx.sess, span, E0158, "{}", text) + } } impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index cfbb9623f7dc9..06fbf669f6e7b 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -27,6 +27,7 @@ use syntax_pos::Span; #[derive(Clone, Debug)] pub enum PatternError<'tcx> { + AssociatedConstInPattern(Span), StaticInPattern(Span), ConstEval(ConstEvalErr<'tcx>), } @@ -632,6 +633,10 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { -> Pattern<'tcx> { let ty = self.tables.node_id_to_type(id); let def = self.tables.qpath_def(qpath, id); + let is_associated_const = match def { + Def::AssociatedConst(_) => true, + _ => false, + }; let kind = match def { Def::Const(def_id) | Def::AssociatedConst(def_id) => { let substs = self.tables.node_substs(id); @@ -653,7 +658,11 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { return pat; } None => { - self.errors.push(PatternError::StaticInPattern(span)); + self.errors.push(if is_associated_const { + PatternError::AssociatedConstInPattern(span) + } else { + PatternError::StaticInPattern(span) + }); PatternKind::Wild } } diff --git a/src/test/compile-fail/associated-const-type-parameter-arms.rs b/src/test/compile-fail/associated-const-type-parameter-arms.rs index 52bb4a1b463b4..630a234fa6641 100644 --- a/src/test/compile-fail/associated-const-type-parameter-arms.rs +++ b/src/test/compile-fail/associated-const-type-parameter-arms.rs @@ -16,6 +16,7 @@ pub trait Foo { } struct Abc; + impl Foo for Abc { const X: EFoo = EFoo::B; } @@ -27,8 +28,10 @@ impl Foo for Def { pub fn test(arg: EFoo) { match arg { - A::X => println!("A::X"), //~ error: statics cannot be referenced in patterns [E0158] - B::X => println!("B::X"), //~ error: statics cannot be referenced in patterns [E0158] + A::X => println!("A::X"), + //~^ error: associated consts cannot be referenced in patterns [E0158] + B::X => println!("B::X"), + //~^ error: associated consts cannot be referenced in patterns [E0158] _ => (), } } From eaebfd4420b190a492e23613dcb97c849cb8449e Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 30 Jan 2018 10:18:54 -0800 Subject: [PATCH 16/24] Ignore run-pass/sse2 when using system LLVM This is a test of `target_feature`, which needs a rust-specific patch to LLVM to add `MCSubtargetInfo::getFeatureTable()`. --- src/test/run-pass/sse2.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-pass/sse2.rs b/src/test/run-pass/sse2.rs index c2414e5ff5d96..22469b2fde058 100644 --- a/src/test/run-pass/sse2.rs +++ b/src/test/run-pass/sse2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// min-llvm-version 4.0 +// no-system-llvm -- needs MCSubtargetInfo::getFeatureTable() // ignore-cloudabi no std::env #![feature(cfg_target_feature)] From d492fe0a00b4afb99c7ba6292961d6d98698373c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 30 Jan 2018 11:53:18 -0800 Subject: [PATCH 17/24] rustc: Add some defines for LLVM 7 compat I was testing out the tip support to see what's going on with wasm, and this was I believe the only issue encountered with LLVM 7 support so far. --- src/rustllvm/PassWrapper.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index b2f1229891d26..06d1301d70003 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -836,6 +836,10 @@ struct LLVMRustThinLTOData { StringMap ImportLists; StringMap ExportLists; StringMap ModuleToDefinedGVSummaries; + +#if LLVM_VERSION_GE(7, 0) + LLVMRustThinLTOData() : Index(/* isPerformingAnalysis = */ false) {} +#endif }; // Just an argument to the `LLVMRustCreateThinLTOData` function below. @@ -918,7 +922,14 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, // // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp` #if LLVM_VERSION_GE(5, 0) +#if LLVM_VERSION_GE(7, 0) + auto deadIsPrevailing = [&](GlobalValue::GUID G) { + return PrevailingType::Unknown; + }; + computeDeadSymbols(Ret->Index, Ret->GUIDPreservedSymbols, deadIsPrevailing); +#else computeDeadSymbols(Ret->Index, Ret->GUIDPreservedSymbols); +#endif ComputeCrossModuleImport( Ret->Index, Ret->ModuleToDefinedGVSummaries, From a2cc5d68a7d4a739b3da62540cb09f313de2f452 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 30 Jan 2018 11:54:07 -0800 Subject: [PATCH 18/24] rustc: Add an option to default hidden visibility This commit adds a new option to target specifictions to specify that symbols should be "hidden" visibility by default in LLVM. While there are no existing targets that take advantage of this the `wasm32-unknown-unknown` target will soon start to use this visibility. The LLD linker currently interprets `hidden` as "don't export this from the wasm module" which is what we want for 90% of our functions. While the LLD linker does have a "export this symbol" argument which is what we use for other linkers, it was also somewhat easier to do this change instead which'll involve less arguments flying around. Additionally there's no need for non-`hidden` visibility for most of our symbols! This change should not immediately impact the wasm targets as-is, but rather this is laying the foundations for soon integrating LLD as a linker for wasm code. --- src/libpanic_abort/lib.rs | 3 +++ src/librustc/dep_graph/dep_node.rs | 3 +++ src/librustc/ty/maps/mod.rs | 1 + src/librustc/ty/maps/plumbing.rs | 2 ++ src/librustc_back/target/mod.rs | 7 +++++++ .../target/wasm32_unknown_unknown.rs | 3 +++ src/librustc_mir/monomorphize/partitioning.rs | 18 +++++++++++++++--- src/librustc_trans/allocator.rs | 4 ++++ src/librustc_trans/back/symbol_export.rs | 3 +++ 9 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs index c3bd6a2bc187d..5f768ef4399e8 100644 --- a/src/libpanic_abort/lib.rs +++ b/src/libpanic_abort/lib.rs @@ -27,10 +27,12 @@ #![feature(libc)] #![feature(panic_runtime)] #![feature(staged_api)] +#![feature(rustc_attrs)] // Rust's "try" function, but if we're aborting on panics we just call the // function as there's nothing else we need to do here. #[no_mangle] +#[rustc_std_internal_symbol] pub unsafe extern fn __rust_maybe_catch_panic(f: fn(*mut u8), data: *mut u8, _data_ptr: *mut usize, @@ -50,6 +52,7 @@ pub unsafe extern fn __rust_maybe_catch_panic(f: fn(*mut u8), // will kill us with an illegal instruction, which will do a good enough job for // now hopefully. #[no_mangle] +#[rustc_std_internal_symbol] pub unsafe extern fn __rust_start_panic(_data: usize, _vtable: usize) -> u32 { abort(); diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 1de9091b5df7d..4034055d04155 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -639,6 +639,9 @@ define_dep_nodes!( <'tcx> [] TargetFeaturesEnabled(DefId), [] InstanceDefSizeEstimate { instance_def: InstanceDef<'tcx> }, + + [] GetSymbolExportLevel(DefId), + ); trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug { diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 6c79f6a62fa0b..85fca68187fe6 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -343,6 +343,7 @@ define_maps! { <'tcx> -> (Arc, Arc>>>), [] fn export_name: ExportName(DefId) -> Option, [] fn contains_extern_indicator: ContainsExternIndicator(DefId) -> bool, + [] fn symbol_export_level: GetSymbolExportLevel(DefId) -> SymbolExportLevel, [] fn is_translated_function: IsTranslatedFunction(DefId) -> bool, [] fn codegen_unit: CodegenUnit(InternedString) -> Arc>, [] fn compile_codegen_unit: CompileCodegenUnit(InternedString) -> Stats, diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index c9eebc3d2a0a7..0ab6ee1a54a9b 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -921,6 +921,8 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::TargetFeaturesWhitelist => { force!(target_features_whitelist, LOCAL_CRATE); } DepKind::TargetFeaturesEnabled => { force!(target_features_enabled, def_id!()); } + + DepKind::GetSymbolExportLevel => { force!(symbol_export_level, def_id!()); } } true diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 3c8a676dcc200..2872c59157d6b 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -468,6 +468,10 @@ pub struct TargetOptions { /// The codegen backend to use for this target, typically "llvm" pub codegen_backend: String, + + /// The default visibility for symbols in this target should be "hidden" + /// rather than "default" + pub default_hidden_visibility: bool, } impl Default for TargetOptions { @@ -538,6 +542,7 @@ impl Default for TargetOptions { no_builtins: false, i128_lowering: false, codegen_backend: "llvm".to_string(), + default_hidden_visibility: false, } } } @@ -785,6 +790,7 @@ impl Target { key!(singlethread, bool); key!(no_builtins, bool); key!(codegen_backend); + key!(default_hidden_visibility, bool); if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) { for name in array.iter().filter_map(|abi| abi.as_string()) { @@ -982,6 +988,7 @@ impl ToJson for Target { target_option_val!(singlethread); target_option_val!(no_builtins); target_option_val!(codegen_backend); + target_option_val!(default_hidden_visibility); if default.abi_blacklist != self.options.abi_blacklist { d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter() diff --git a/src/librustc_back/target/wasm32_unknown_unknown.rs b/src/librustc_back/target/wasm32_unknown_unknown.rs index 7e1011ab8af96..242860e5c6e92 100644 --- a/src/librustc_back/target/wasm32_unknown_unknown.rs +++ b/src/librustc_back/target/wasm32_unknown_unknown.rs @@ -83,6 +83,9 @@ pub fn target() -> Result { // performing LTO with compiler-builtins. no_builtins: true, + // no dynamic linking, no need for default visibility! + default_hidden_visibility: true, + .. Default::default() }; Ok(Target { diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 806d787c84522..e9471cdb4f949 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -107,6 +107,7 @@ use rustc::dep_graph::WorkProductId; use rustc::hir::def_id::DefId; use rustc::hir::map::DefPathData; use rustc::mir::mono::{Linkage, Visibility}; +use rustc::middle::exported_symbols::SymbolExportLevel; use rustc::ty::{self, TyCtxt, InstanceDef}; use rustc::ty::item_path::characteristic_def_id_of_type; use rustc::util::nodemap::{FxHashMap, FxHashSet}; @@ -322,7 +323,16 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, .or_insert_with(make_codegen_unit); let mut can_be_internalized = true; - let (linkage, visibility) = match trans_item.explicit_linkage(tcx) { + let default_visibility = |id: DefId| { + if tcx.sess.target.target.options.default_hidden_visibility && + tcx.symbol_export_level(id) != SymbolExportLevel::C + { + Visibility::Hidden + } else { + Visibility::Default + } + }; + let (linkage, mut visibility) = match trans_item.explicit_linkage(tcx) { Some(explicit_linkage) => (explicit_linkage, Visibility::Default), None => { match trans_item { @@ -352,7 +362,8 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Visibility::Hidden } else if def_id.is_local() { if tcx.is_exported_symbol(def_id) { - Visibility::Default + can_be_internalized = false; + default_visibility(def_id) } else { Visibility::Hidden } @@ -375,7 +386,8 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, MonoItem::GlobalAsm(node_id) => { let def_id = tcx.hir.local_def_id(node_id); let visibility = if tcx.is_exported_symbol(def_id) { - Visibility::Default + can_be_internalized = false; + default_visibility(def_id) } else { Visibility::Hidden }; diff --git a/src/librustc_trans/allocator.rs b/src/librustc_trans/allocator.rs index fd5aa1364d381..e1c145b122d76 100644 --- a/src/librustc_trans/allocator.rs +++ b/src/librustc_trans/allocator.rs @@ -86,6 +86,10 @@ pub(crate) unsafe fn trans(tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind) name.as_ptr(), ty); + if tcx.sess.target.target.options.default_hidden_visibility { + llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden); + } + let callee = CString::new(kind.fn_name(method.name)).unwrap(); let callee = llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr(), diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs index 15ff59c7df998..989ef8a953746 100644 --- a/src/librustc_trans/back/symbol_export.rs +++ b/src/librustc_trans/back/symbol_export.rs @@ -133,6 +133,8 @@ pub fn provide(providers: &mut Providers) { Arc::new(local_crate) }; + + providers.symbol_export_level = export_level; } pub fn provide_extern(providers: &mut Providers) { @@ -203,6 +205,7 @@ pub fn provide_extern(providers: &mut Providers) { Arc::new(crate_exports) }; + providers.symbol_export_level = export_level; } fn export_level(tcx: TyCtxt, sym_def_id: DefId) -> SymbolExportLevel { From 1e380cbfdd96365ef0eb6dfec341e85b68fa64b5 Mon Sep 17 00:00:00 2001 From: Vadzim Dambrouski Date: Wed, 31 Jan 2018 00:57:30 +0300 Subject: [PATCH 19/24] [MSP430] Don't enable trap_unreachable option by default on msp. Since MSP430 doesn't meaningfully support faulting on illegal instructions, LLVM generates a call to abort() function instead of a trap instruction. Such calls are 4 bytes long, and that is too much overhead for such small target. --- src/librustc_back/target/msp430_none_elf.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librustc_back/target/msp430_none_elf.rs b/src/librustc_back/target/msp430_none_elf.rs index 509a7cf5e0323..966df897f01f1 100644 --- a/src/librustc_back/target/msp430_none_elf.rs +++ b/src/librustc_back/target/msp430_none_elf.rs @@ -53,6 +53,12 @@ pub fn target() -> TargetResult { // don't want to invoke that many gcc instances. default_codegen_units: Some(1), + // Since MSP430 doesn't meaningfully support faulting on illegal + // instructions, LLVM generates a call to abort() function instead + // of a trap instruction. Such calls are 4 bytes long, and that is + // too much overhead for such small target. + trap_unreachable: false, + .. Default::default( ) } }) From 973756d715f9caaeee44e9387f5c60458ae5c4fc Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 31 Jan 2018 00:23:25 +0200 Subject: [PATCH 20/24] rustc_trans: keep LLVM types for trait objects anonymous. --- src/librustc_trans/type_of.rs | 4 +++- src/test/codegen/function-arguments.rs | 4 ++-- src/test/run-pass/issue-47638.rs | 18 ++++++++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 src/test/run-pass/issue-47638.rs diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs index b1533cfad19f5..af957500f7002 100644 --- a/src/librustc_trans/type_of.rs +++ b/src/librustc_trans/type_of.rs @@ -57,7 +57,9 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ty::TyClosure(..) | ty::TyGenerator(..) | ty::TyAdt(..) | - ty::TyDynamic(..) | + // FIXME(eddyb) producing readable type names for trait objects can result + // in problematically distinct types due to HRTB and subtyping (see #47638). + // ty::TyDynamic(..) | ty::TyForeign(..) | ty::TyStr => { let mut name = String::with_capacity(32); diff --git a/src/test/codegen/function-arguments.rs b/src/test/codegen/function-arguments.rs index f8945a6ee8d93..0e98d3f9050a8 100644 --- a/src/test/codegen/function-arguments.rs +++ b/src/test/codegen/function-arguments.rs @@ -122,13 +122,13 @@ pub fn unsafe_slice(_: &[UnsafeInner]) { pub fn str(_: &[u8]) { } -// CHECK: @trait_borrow(%"core::ops::drop::Drop"* nonnull %arg0.0, {}* noalias nonnull readonly %arg0.1) +// CHECK: @trait_borrow({}* nonnull %arg0.0, {}* noalias nonnull readonly %arg0.1) // FIXME #25759 This should also have `nocapture` #[no_mangle] pub fn trait_borrow(_: &Drop) { } -// CHECK: @trait_box(%"core::ops::drop::Drop"* noalias nonnull, {}* noalias nonnull readonly) +// CHECK: @trait_box({}* noalias nonnull, {}* noalias nonnull readonly) #[no_mangle] pub fn trait_box(_: Box) { } diff --git a/src/test/run-pass/issue-47638.rs b/src/test/run-pass/issue-47638.rs new file mode 100644 index 0000000000000..6f627b2a3c137 --- /dev/null +++ b/src/test/run-pass/issue-47638.rs @@ -0,0 +1,18 @@ +// 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. + +fn id<'c, 'b>(f: &'c &'b Fn(&i32)) -> &'c &'b Fn(&'static i32) { + f +} + +fn main() { + let f: &Fn(&i32) = &|x| {}; + id(&f); +} From c73925452c870f028ab393acf8edc5ceea382fcb Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 31 Jan 2018 00:59:20 +0000 Subject: [PATCH 21/24] Fix ICE when reading non-UTF-8 input from stdin Fixes #22387. --- src/librustc_driver/lib.rs | 29 +++++++++++++++++------ src/test/run-make/stdin-non-utf8/Makefile | 5 ++++ 2 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 src/test/run-make/stdin-non-utf8/Makefile diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 6118ee94c84cf..2f083c2193a21 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -456,10 +456,13 @@ pub fn run_compiler<'a>(args: &[String], None); let (odir, ofile) = make_output(&matches); - let (input, input_file_path) = match make_input(&matches.free) { - Some((input, input_file_path)) => callbacks.some_input(input, input_file_path), + let (input, input_file_path, input_err) = match make_input(&matches.free) { + Some((input, input_file_path, input_err)) => { + let (input, input_file_path) = callbacks.some_input(input, input_file_path); + (input, input_file_path, input_err) + }, None => match callbacks.no_input(&matches, &sopts, &cfg, &odir, &ofile, &descriptions) { - Some((input, input_file_path)) => (input, input_file_path), + Some((input, input_file_path)) => (input, input_file_path, None), None => return (Ok(()), None), }, }; @@ -470,6 +473,13 @@ pub fn run_compiler<'a>(args: &[String], sopts, input_file_path.clone(), descriptions, codemap, emitter_dest, ); + if let Some(err) = input_err { + // Immediately stop compilation if there was an issue reading + // the input (for example if the input stream is not UTF-8). + sess.err(&format!("{}", err)); + return (Err(CompileIncomplete::Stopped), Some(sess)); + } + let trans = get_trans(&sess); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); @@ -512,17 +522,22 @@ fn make_output(matches: &getopts::Matches) -> (Option, Option) } // Extract input (string or file and optional path) from matches. -fn make_input(free_matches: &[String]) -> Option<(Input, Option)> { +fn make_input(free_matches: &[String]) -> Option<(Input, Option, Option)> { if free_matches.len() == 1 { let ifile = &free_matches[0]; if ifile == "-" { let mut src = String::new(); - io::stdin().read_to_string(&mut src).unwrap(); + let err = if io::stdin().read_to_string(&mut src).is_err() { + Some(io::Error::new(io::ErrorKind::InvalidData, + "couldn't read from stdin, as it did not contain valid UTF-8")) + } else { + None + }; Some((Input::Str { name: FileName::Anon, input: src }, - None)) + None, err)) } else { Some((Input::File(PathBuf::from(ifile)), - Some(PathBuf::from(ifile)))) + Some(PathBuf::from(ifile)), None)) } } else { None diff --git a/src/test/run-make/stdin-non-utf8/Makefile b/src/test/run-make/stdin-non-utf8/Makefile new file mode 100644 index 0000000000000..307f3d85c0067 --- /dev/null +++ b/src/test/run-make/stdin-non-utf8/Makefile @@ -0,0 +1,5 @@ +-include ../tools.mk + +all: + echo '\xD2' | $(RUSTC) - 2>&1 \ + | $(CGREP) "error: couldn't read from stdin, as it did not contain valid UTF-8" From 00a33d685be2d325381a5b2842774f4ad1039dff Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 31 Jan 2018 10:23:15 +0000 Subject: [PATCH 22/24] Add echo escape flag --- src/test/run-make/stdin-non-utf8/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-make/stdin-non-utf8/Makefile b/src/test/run-make/stdin-non-utf8/Makefile index 307f3d85c0067..f883e546e9c9b 100644 --- a/src/test/run-make/stdin-non-utf8/Makefile +++ b/src/test/run-make/stdin-non-utf8/Makefile @@ -1,5 +1,5 @@ -include ../tools.mk all: - echo '\xD2' | $(RUSTC) - 2>&1 \ + echo -e '\xD2' | $(RUSTC) - 2>&1 \ | $(CGREP) "error: couldn't read from stdin, as it did not contain valid UTF-8" From a43d7eb3dd9cb97a81374001a23456bbee008d65 Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 31 Jan 2018 11:56:15 +0000 Subject: [PATCH 23/24] Use file containing non-UTF-8 character instead of echo -e --- src/test/run-make/stdin-non-utf8/Makefile | 3 ++- src/test/run-make/stdin-non-utf8/non-utf8 | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 src/test/run-make/stdin-non-utf8/non-utf8 diff --git a/src/test/run-make/stdin-non-utf8/Makefile b/src/test/run-make/stdin-non-utf8/Makefile index f883e546e9c9b..7948c442616e3 100644 --- a/src/test/run-make/stdin-non-utf8/Makefile +++ b/src/test/run-make/stdin-non-utf8/Makefile @@ -1,5 +1,6 @@ -include ../tools.mk all: - echo -e '\xD2' | $(RUSTC) - 2>&1 \ + cp non-utf8 $(TMPDIR)/non-utf.rs + cat $(TMPDIR)/non-utf.rs | $(RUSTC) - 2>&1 \ | $(CGREP) "error: couldn't read from stdin, as it did not contain valid UTF-8" diff --git a/src/test/run-make/stdin-non-utf8/non-utf8 b/src/test/run-make/stdin-non-utf8/non-utf8 new file mode 100644 index 0000000000000..bc87051a85299 --- /dev/null +++ b/src/test/run-make/stdin-non-utf8/non-utf8 @@ -0,0 +1 @@ +Ò From 8ebe5424809a517a9e74984a32e79e0ff9d612f9 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 30 Jan 2018 15:40:44 -0800 Subject: [PATCH 24/24] rustc: Move location of `codegen-backends` dir Right now this directory is located under: $sysroot/lib/rustlib/$target/lib/codegen-backends but after seeing what we do in a few other places it seems that a more appropriate location would be: $sysroot/lib/rustlib/$target/codegen-backends so this commit moves it! --- src/bootstrap/builder.rs | 5 +++++ src/bootstrap/compile.rs | 3 +-- src/bootstrap/dist.rs | 8 +++----- src/librustc_driver/lib.rs | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 1272643edd259..780513dd94394 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -377,6 +377,11 @@ impl<'a> Builder<'a> { self.ensure(Libdir { compiler, target }) } + pub fn sysroot_codegen_backends(&self, compiler: Compiler) -> PathBuf { + self.sysroot_libdir(compiler, compiler.host) + .with_file_name("codegen-backends") + } + /// Returns the compiler's libdir where it stores the dynamic libraries that /// it itself links against. /// diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index fa289bbd76a8b..1d5e11c5d6d41 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -724,8 +724,7 @@ fn copy_codegen_backends_to_sysroot(builder: &Builder, // // Here we're looking for the output dylib of the `CodegenBackend` step and // we're copying that into the `codegen-backends` folder. - let libdir = builder.sysroot_libdir(target_compiler, target); - let dst = libdir.join("codegen-backends"); + let dst = builder.sysroot_codegen_backends(target_compiler); t!(fs::create_dir_all(&dst)); for backend in builder.config.rust_codegen_backends.iter() { diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 4127239dc49b8..dbb7d19e43285 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -435,11 +435,9 @@ impl Step for Rustc { } // Copy over the codegen backends - let backends_src = builder.sysroot_libdir(compiler, host) - .join("codegen-backends"); - let backends_dst = image.join("lib/rustlib") - .join(&*host) - .join("lib/codegen-backends"); + let backends_src = builder.sysroot_codegen_backends(compiler); + let backends_rel = backends_src.strip_prefix(&src).unwrap(); + let backends_dst = image.join(&backends_rel); t!(fs::create_dir_all(&backends_dst)); cp_r(&backends_src, &backends_dst); diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 6118ee94c84cf..2bf91f79b2bbe 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -289,7 +289,7 @@ fn get_trans_sysroot(backend_name: &str) -> fn() -> Box { let sysroot = sysroot_candidates.iter() .map(|sysroot| { let libdir = filesearch::relative_target_lib_path(&sysroot, &target); - sysroot.join(&libdir).join("codegen-backends") + sysroot.join(libdir).with_file_name("codegen-backends") }) .filter(|f| { info!("codegen backend candidate: {}", f.display());