From e333725664c45874262ecb11e511c17cfd4672f0 Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Wed, 9 May 2018 01:41:44 +0200 Subject: [PATCH 01/18] use fmt::Result where applicable --- src/librustc/ich/fingerprint.rs | 2 +- .../control_flow_graph/dominators/mod.rs | 4 ++-- src/librustc_data_structures/owning_ref/mod.rs | 6 +++--- src/librustc_errors/lib.rs | 4 ++-- src/librustc_mir/borrow_check/nll/region_infer/mod.rs | 2 +- src/librustc_mir/transform/elaborate_drops.rs | 2 +- src/librustdoc/html/render.rs | 4 ++-- src/libstd/path.rs | 2 +- src/libstd/sys/redox/syscall/error.rs | 4 ++-- src/libstd/sys_common/wtf8.rs | 4 ++-- src/libsyntax_ext/format_foreign.rs | 2 +- src/test/run-pass/atomic-print.rs | 2 +- src/test/run-pass/union/union-trait-impl.rs | 2 +- 13 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/librustc/ich/fingerprint.rs b/src/librustc/ich/fingerprint.rs index a7adf28c481b9..f56f4e12e7a02 100644 --- a/src/librustc/ich/fingerprint.rs +++ b/src/librustc/ich/fingerprint.rs @@ -67,7 +67,7 @@ impl Fingerprint { } impl ::std::fmt::Display for Fingerprint { - fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { + fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(formatter, "{:x}-{:x}", self.0, self.1) } } diff --git a/src/librustc_data_structures/control_flow_graph/dominators/mod.rs b/src/librustc_data_structures/control_flow_graph/dominators/mod.rs index dc487f1162ca9..54407658e6ccc 100644 --- a/src/librustc_data_structures/control_flow_graph/dominators/mod.rs +++ b/src/librustc_data_structures/control_flow_graph/dominators/mod.rs @@ -175,7 +175,7 @@ impl DominatorTree { } impl fmt::Debug for DominatorTree { - fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&DominatorTreeNode { tree: self, node: self.root, @@ -190,7 +190,7 @@ struct DominatorTreeNode<'tree, Node: Idx> { } impl<'tree, Node: Idx> fmt::Debug for DominatorTreeNode<'tree, Node> { - fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let subtrees: Vec<_> = self.tree .children(self.node) .iter() diff --git a/src/librustc_data_structures/owning_ref/mod.rs b/src/librustc_data_structures/owning_ref/mod.rs index c466b8f8ad1b5..aa113fac9fb7d 100644 --- a/src/librustc_data_structures/owning_ref/mod.rs +++ b/src/librustc_data_structures/owning_ref/mod.rs @@ -1002,7 +1002,7 @@ impl Debug for OwningRef where O: Debug, T: Debug, { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "OwningRef {{ owner: {:?}, reference: {:?} }}", self.owner(), @@ -1014,7 +1014,7 @@ impl Debug for OwningRefMut where O: Debug, T: Debug, { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "OwningRefMut {{ owner: {:?}, reference: {:?} }}", self.owner(), @@ -1047,7 +1047,7 @@ unsafe impl Sync for OwningRefMut where O: Sync, for<'a> (&'a mut T): Sync {} impl Debug for Erased { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "",) } } diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index c2b442e949758..fd90e1cbe0866 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -232,7 +232,7 @@ impl FatalError { } impl fmt::Display for FatalError { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "parser fatal error") } } @@ -249,7 +249,7 @@ impl error::Error for FatalError { pub struct ExplicitBug; impl fmt::Display for ExplicitBug { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "parser internal bug") } } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index 4d1f3e2b4300a..57b8824191f7b 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -1185,7 +1185,7 @@ impl<'tcx> RegionDefinition<'tcx> { } impl fmt::Debug for Constraint { - fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!( formatter, "({:?}: {:?} @ {:?}) due to {:?}", diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index 5397d18cdd720..79252e7654bfa 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -174,7 +174,7 @@ struct Elaborator<'a, 'b: 'a, 'tcx: 'b> { } impl<'a, 'b, 'tcx> fmt::Debug for Elaborator<'a, 'b, 'tcx> { - fn fmt(&self, _f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { Ok(()) } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 21de2db1dfe74..fe9fc3ddd680e 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2579,7 +2579,7 @@ fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, } fn render_implementor(cx: &Context, implementor: &Impl, w: &mut fmt::Formatter, - implementor_dups: &FxHashMap<&str, (DefId, bool)>) -> Result<(), fmt::Error> { + implementor_dups: &FxHashMap<&str, (DefId, bool)>) -> fmt::Result { write!(w, "
  • ")?; // If there's already another implementor that has the same abbridged name, use the // full path, for example in `std::iter::ExactSizeIterator` @@ -2612,7 +2612,7 @@ fn render_implementor(cx: &Context, implementor: &Impl, w: &mut fmt::Formatter, fn render_impls(cx: &Context, w: &mut fmt::Formatter, traits: &[&&Impl], - containing_item: &clean::Item) -> Result<(), fmt::Error> { + containing_item: &clean::Item) -> fmt::Result { for i in traits { let did = i.trait_did().unwrap(); let assoc_link = AssocItemLink::GotoSource(did, &i.inner_impl().provided_trait_methods); diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 696711a70d4f6..5d35a7861736a 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1460,7 +1460,7 @@ impl> iter::Extend

    for PathBuf { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for PathBuf { - fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&**self, formatter) } } diff --git a/src/libstd/sys/redox/syscall/error.rs b/src/libstd/sys/redox/syscall/error.rs index d8d78d550162a..1ef79547431f8 100644 --- a/src/libstd/sys/redox/syscall/error.rs +++ b/src/libstd/sys/redox/syscall/error.rs @@ -48,13 +48,13 @@ impl Error { } impl fmt::Debug for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(self.text()) } } impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(self.text()) } } diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs index fe7e058091ed5..14a2555adf9ba 100644 --- a/src/libstd/sys_common/wtf8.rs +++ b/src/libstd/sys_common/wtf8.rs @@ -56,7 +56,7 @@ pub struct CodePoint { /// Example: `U+1F4A9` impl fmt::Debug for CodePoint { #[inline] - fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "U+{:04X}", self.value) } } @@ -144,7 +144,7 @@ impl ops::DerefMut for Wtf8Buf { /// Example: `"a\u{D800}"` for a string with code points [U+0061, U+D800] impl fmt::Debug for Wtf8Buf { #[inline] - fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&**self, formatter) } } diff --git a/src/libsyntax_ext/format_foreign.rs b/src/libsyntax_ext/format_foreign.rs index e95c6f2e1243f..2b8603c75a57b 100644 --- a/src/libsyntax_ext/format_foreign.rs +++ b/src/libsyntax_ext/format_foreign.rs @@ -989,7 +989,7 @@ mod strcursor { } impl<'a> std::fmt::Debug for StrCursor<'a> { - fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { write!(fmt, "StrCursor({:?} | {:?})", self.slice_before(), self.slice_after()) } } diff --git a/src/test/run-pass/atomic-print.rs b/src/test/run-pass/atomic-print.rs index 914b89dfb4dc0..2d478e954e7cb 100644 --- a/src/test/run-pass/atomic-print.rs +++ b/src/test/run-pass/atomic-print.rs @@ -15,7 +15,7 @@ use std::{env, fmt, process, sync, thread}; struct SlowFmt(u32); impl fmt::Debug for SlowFmt { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { thread::sleep_ms(3); self.0.fmt(f) } diff --git a/src/test/run-pass/union/union-trait-impl.rs b/src/test/run-pass/union/union-trait-impl.rs index 1cdaff2cab7c8..c1e408cc02ac6 100644 --- a/src/test/run-pass/union/union-trait-impl.rs +++ b/src/test/run-pass/union/union-trait-impl.rs @@ -15,7 +15,7 @@ union U { } impl fmt::Display for U { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { unsafe { write!(f, "Oh hai {}", self.a) } } } From 9d7eda96ee57ed951bd93a420814c6f8c65c1cf2 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Thu, 10 May 2018 18:05:29 +1000 Subject: [PATCH 02/18] Mention that fs::canonicalize makes paths absolute. --- src/libstd/fs.rs | 4 ++-- src/libstd/path.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 7bd1adc411ae4..f877c77ad7ff0 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -1699,8 +1699,8 @@ pub fn read_link>(path: P) -> io::Result { fs_imp::readlink(path.as_ref()) } -/// Returns the canonical form of a path with all intermediate components -/// normalized and symbolic links resolved. +/// Returns the canonical, absolute form of a path with all intermediate +/// components normalized and symbolic links resolved. /// /// # Platform-specific behavior /// diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 696711a70d4f6..b670ae597b280 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -2284,8 +2284,8 @@ impl Path { fs::symlink_metadata(self) } - /// Returns the canonical form of the path with all intermediate components - /// normalized and symbolic links resolved. + /// Returns the canonical, absolute form of the path with all intermediate + /// components normalized and symbolic links resolved. /// /// This is an alias to [`fs::canonicalize`]. /// From 8720314c025cd222fd04d07119e2cf180f53770a Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Thu, 10 May 2018 18:06:47 +1000 Subject: [PATCH 03/18] fs::canonicalize has some important portability concerns. --- src/libstd/fs.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index f877c77ad7ff0..732da79a4d4da 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -1708,7 +1708,14 @@ pub fn read_link>(path: P) -> io::Result { /// and the `CreateFile` and `GetFinalPathNameByHandle` functions on Windows. /// Note that, this [may change in the future][changes]. /// +/// On Windows, this converts the path to use [extended length path][path] +/// syntax, which allows your program to use longer path names, but means you +/// can only join backslash-delimited paths to it, and it may be incompatible +/// with other applications (if passed to the application on the command-line, +/// or written to a file another application may read). +/// /// [changes]: ../io/index.html#platform-specific-behavior +/// [path]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath /// /// # Errors /// From 2ae8accd24bec0c4eadba7b02a0a2422b1f1247e Mon Sep 17 00:00:00 2001 From: Aaron DeVore Date: Thu, 10 May 2018 11:47:31 -0700 Subject: [PATCH 04/18] fs::write: Add example writing a &str --- src/libstd/fs.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 7bd1adc411ae4..ab44723217eab 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -331,6 +331,7 @@ pub fn read_to_string>(path: P) -> io::Result { /// /// fn main() -> std::io::Result<()> { /// fs::write("foo.txt", b"Lorem ipsum")?; +/// fs::write("bar.txt", "dolor sit")?; /// Ok(()) /// } /// ``` From 4d8d0a6f85ee66c7b65c53de3039aa38d99f05af Mon Sep 17 00:00:00 2001 From: Roman Stoliar Date: Tue, 8 May 2018 23:47:50 +0300 Subject: [PATCH 05/18] const time added rustc_const_unstable attribute extended tests added conversion test fixed tidy test added feature attribute --- src/libcore/tests/time.rs | 42 ++++++++++++++++++- src/libcore/time.rs | 12 ++++-- src/test/ui/const-eval/duration_conversion.rs | 28 +++++++++++++ 3 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/const-eval/duration_conversion.rs diff --git a/src/libcore/tests/time.rs b/src/libcore/tests/time.rs index 042c523f25f25..0f3b95236f069 100644 --- a/src/libcore/tests/time.rs +++ b/src/libcore/tests/time.rs @@ -23,9 +23,43 @@ fn creation() { #[test] fn secs() { assert_eq!(Duration::new(0, 0).as_secs(), 0); + assert_eq!(Duration::new(0, 500_000_005).as_secs(), 0); + assert_eq!(Duration::new(0, 1_050_000_001).as_secs(), 1); assert_eq!(Duration::from_secs(1).as_secs(), 1); assert_eq!(Duration::from_millis(999).as_secs(), 0); assert_eq!(Duration::from_millis(1001).as_secs(), 1); + assert_eq!(Duration::from_micros(999_999).as_secs(), 0); + assert_eq!(Duration::from_micros(1_000_001).as_secs(), 1); + assert_eq!(Duration::from_nanos(999_999_999).as_secs(), 0); + assert_eq!(Duration::from_nanos(1_000_000_001).as_secs(), 1); +} + +#[test] +fn millis() { + assert_eq!(Duration::new(0, 0).subsec_millis(), 0); + assert_eq!(Duration::new(0, 500_000_005).subsec_millis(), 500); + assert_eq!(Duration::new(0, 1_050_000_001).subsec_millis(), 50); + assert_eq!(Duration::from_secs(1).subsec_millis(), 0); + assert_eq!(Duration::from_millis(999).subsec_millis(), 999); + assert_eq!(Duration::from_millis(1001).subsec_millis(), 1); + assert_eq!(Duration::from_micros(999_999).subsec_millis(), 999); + assert_eq!(Duration::from_micros(1_001_000).subsec_millis(), 1); + assert_eq!(Duration::from_nanos(999_999_999).subsec_millis(), 999); + assert_eq!(Duration::from_nanos(1_001_000_000).subsec_millis(), 1); +} + +#[test] +fn micros() { + assert_eq!(Duration::new(0, 0).subsec_micros(), 0); + assert_eq!(Duration::new(0, 500_000_005).subsec_micros(), 500_000); + assert_eq!(Duration::new(0, 1_050_000_001).subsec_micros(), 50_000); + assert_eq!(Duration::from_secs(1).subsec_micros(), 0); + assert_eq!(Duration::from_millis(999).subsec_micros(), 999_000); + assert_eq!(Duration::from_millis(1001).subsec_micros(), 1_000); + assert_eq!(Duration::from_micros(999_999).subsec_micros(), 999_999); + assert_eq!(Duration::from_micros(1_000_001).subsec_micros(), 1); + assert_eq!(Duration::from_nanos(999_999_999).subsec_micros(), 999_999); + assert_eq!(Duration::from_nanos(1_000_001_000).subsec_micros(), 1); } #[test] @@ -34,8 +68,12 @@ fn nanos() { assert_eq!(Duration::new(0, 5).subsec_nanos(), 5); assert_eq!(Duration::new(0, 1_000_000_001).subsec_nanos(), 1); assert_eq!(Duration::from_secs(1).subsec_nanos(), 0); - assert_eq!(Duration::from_millis(999).subsec_nanos(), 999 * 1_000_000); - assert_eq!(Duration::from_millis(1001).subsec_nanos(), 1 * 1_000_000); + assert_eq!(Duration::from_millis(999).subsec_nanos(), 999_000_000); + assert_eq!(Duration::from_millis(1001).subsec_nanos(), 1_000_000); + assert_eq!(Duration::from_micros(999_999).subsec_nanos(), 999_999_000); + assert_eq!(Duration::from_micros(1_000_001).subsec_nanos(), 1000); + assert_eq!(Duration::from_nanos(999_999_999).subsec_nanos(), 999_999_999); + assert_eq!(Duration::from_nanos(1_000_000_001).subsec_nanos(), 1); } #[test] diff --git a/src/libcore/time.rs b/src/libcore/time.rs index 8e8b1691c657a..c0b2b2a0bc682 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -203,8 +203,9 @@ impl Duration { /// /// [`subsec_nanos`]: #method.subsec_nanos #[stable(feature = "duration", since = "1.3.0")] + #[rustc_const_unstable(feature="duration_getters")] #[inline] - pub fn as_secs(&self) -> u64 { self.secs } + pub const fn as_secs(&self) -> u64 { self.secs } /// Returns the fractional part of this `Duration`, in milliseconds. /// @@ -222,8 +223,9 @@ impl Duration { /// assert_eq!(duration.subsec_millis(), 432); /// ``` #[stable(feature = "duration_extras", since = "1.27.0")] + #[rustc_const_unstable(feature="duration_getters")] #[inline] - pub fn subsec_millis(&self) -> u32 { self.nanos / NANOS_PER_MILLI } + pub const fn subsec_millis(&self) -> u32 { self.nanos / NANOS_PER_MILLI } /// Returns the fractional part of this `Duration`, in microseconds. /// @@ -241,8 +243,9 @@ impl Duration { /// assert_eq!(duration.subsec_micros(), 234_567); /// ``` #[stable(feature = "duration_extras", since = "1.27.0")] + #[rustc_const_unstable(feature="duration_getters")] #[inline] - pub fn subsec_micros(&self) -> u32 { self.nanos / NANOS_PER_MICRO } + pub const fn subsec_micros(&self) -> u32 { self.nanos / NANOS_PER_MICRO } /// Returns the fractional part of this `Duration`, in nanoseconds. /// @@ -260,8 +263,9 @@ impl Duration { /// assert_eq!(duration.subsec_nanos(), 10_000_000); /// ``` #[stable(feature = "duration", since = "1.3.0")] + #[rustc_const_unstable(feature="duration_getters")] #[inline] - pub fn subsec_nanos(&self) -> u32 { self.nanos } + pub const fn subsec_nanos(&self) -> u32 { self.nanos } /// Checked `Duration` addition. Computes `self + other`, returning [`None`] /// if overflow occurred. diff --git a/src/test/ui/const-eval/duration_conversion.rs b/src/test/ui/const-eval/duration_conversion.rs new file mode 100644 index 0000000000000..4481b75840487 --- /dev/null +++ b/src/test/ui/const-eval/duration_conversion.rs @@ -0,0 +1,28 @@ +// 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. + +// compile-pass + +#![feature(duration_getters)] + +use std::time::Duration; + +fn main() { + const _ONE_SECOND: Duration = Duration::from_nanos(1_000_000_000); + const _ONE_MILLISECOND: Duration = Duration::from_nanos(1_000_000); + const _ONE_MICROSECOND: Duration = Duration::from_nanos(1_000); + const _ONE_NANOSECOND: Duration = Duration::from_nanos(1); + const _ONE: usize = _ONE_SECOND.as_secs() as usize; + const _TWO: usize = _ONE_MILLISECOND.subsec_millis() as usize; + const _THREE: usize = _ONE_MICROSECOND.subsec_micros() as usize; + const _FOUR: usize = _ONE_NANOSECOND.subsec_nanos() as usize; + const _0: [[u8; _ONE]; _TWO] = [[1; _ONE]; _TWO]; + const _1: [[u8; _THREE]; _FOUR] = [[3; _THREE]; _FOUR]; +} From d71625b233a274f5eb0a97e94229d96c8fd37cfc Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Fri, 11 May 2018 00:59:46 +0200 Subject: [PATCH 06/18] Do not silently truncate offsets for `read_at`/`write_at` on emscripten Generate an IO error if the offset is out of bounds for the system call. --- src/libstd/sys/unix/fd.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs index 5dafc3251e755..d38c62d74d22d 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -76,7 +76,13 @@ impl FileDesc { -> io::Result { use libc::pread64; - cvt(pread64(fd, buf, count, offset as i32)) + // pread64 on emscripten actually takes a 32 bit offset + if let Ok(o) = offset.try_into() { + cvt(pread64(fd, buf, count, o)) + } else { + Err(io::Error::new(io::ErrorKind::InvalidInput, + "cannot pread >2GB")) + } } #[cfg(not(any(target_os = "android", target_os = "emscripten")))] @@ -117,7 +123,13 @@ impl FileDesc { -> io::Result { use libc::pwrite64; - cvt(pwrite64(fd, buf, count, offset as i32)) + // pwrite64 on emscripten actually takes a 32 bit offset + if let Ok(o) = offset.try_into() { + cvt(pwrite64(fd, buf, count, o)) + } else { + Err(io::Error::new(io::ErrorKind::InvalidInput, + "cannot pwrite >2GB")) + } } #[cfg(not(any(target_os = "android", target_os = "emscripten")))] From 7006018745566fae2f09f6fc201cf4f6de6a4414 Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Sat, 5 May 2018 22:14:33 -0700 Subject: [PATCH 07/18] don't make crazy suggestion for unreachable braced pub-use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Higher Intermediate Representation doesn't have spans for visibility keywords, so we were assuming that the first whitespace-delimited token in the item span was the `pub` to be weakened. This doesn't work for brace-grouped `use`s, which get lowered as if they were several individual `use` statements, but with spans that only cover the braced path-segments. Constructing a correct suggestion here presents some challenges—until someone works those out, we can at least protect the dignity of our compiler marking the suggestion for `use` items as potentially incorrect. This resolves #50455 (but again, it would be desirable in the future to make a correct suggestion instead of copping out like this). --- src/librustc_lint/builtin.rs | 45 ++++++++++--------- src/test/ui/lint/unreachable_pub-pub_crate.rs | 1 + .../ui/lint/unreachable_pub-pub_crate.stderr | 32 ++++++++----- src/test/ui/lint/unreachable_pub.rs | 1 + src/test/ui/lint/unreachable_pub.stderr | 32 ++++++++----- 5 files changed, 67 insertions(+), 44 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 5102bfe766eef..251b95a6fcb79 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1287,32 +1287,27 @@ impl LintPass for UnreachablePub { impl UnreachablePub { fn perform_lint(&self, cx: &LateContext, what: &str, id: ast::NodeId, - vis: &hir::Visibility, span: Span, exportable: bool) { + vis: &hir::Visibility, span: Span, exportable: bool, + mut applicability: Applicability) { if !cx.access_levels.is_reachable(id) && *vis == hir::Visibility::Public { + if span.ctxt().outer().expn_info().is_some() { + applicability = Applicability::MaybeIncorrect; + } let def_span = cx.tcx.sess.codemap().def_span(span); let mut err = cx.struct_span_lint(UNREACHABLE_PUB, def_span, &format!("unreachable `pub` {}", what)); - // visibility is token at start of declaration (can be macro - // variable rather than literal `pub`) + // We are presuming that visibility is token at start of + // declaration (can be macro variable rather than literal `pub`) let pub_span = cx.tcx.sess.codemap().span_until_char(def_span, ' '); let replacement = if cx.tcx.features().crate_visibility_modifier { "crate" } else { "pub(crate)" }.to_owned(); - let app = if span.ctxt().outer().expn_info().is_none() { - // even if macros aren't involved the suggestion - // may be incorrect -- the user may have mistakenly - // hidden it behind a private module and this lint is - // a helpful way to catch that. However, we're trying - // not to change the nature of the code with this lint - // so it's marked as machine applicable. - Applicability::MachineApplicable - } else { - Applicability::MaybeIncorrect - }; - err.span_suggestion_with_applicability(pub_span, "consider restricting its visibility", - replacement, app); + err.span_suggestion_with_applicability(pub_span, + "consider restricting its visibility", + replacement, + applicability); if exportable { err.help("or consider exporting it for use by other crates"); } @@ -1321,21 +1316,31 @@ impl UnreachablePub { } } + impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnreachablePub { fn check_item(&mut self, cx: &LateContext, item: &hir::Item) { - self.perform_lint(cx, "item", item.id, &item.vis, item.span, true); + let applicability = match item.node { + // suggestion span-manipulation is inadequate for `pub use + // module::{item}` (Issue #50455) + hir::ItemUse(..) => Applicability::MaybeIncorrect, + _ => Applicability::MachineApplicable, + }; + self.perform_lint(cx, "item", item.id, &item.vis, item.span, true, applicability); } fn check_foreign_item(&mut self, cx: &LateContext, foreign_item: &hir::ForeignItem) { - self.perform_lint(cx, "item", foreign_item.id, &foreign_item.vis, foreign_item.span, true); + self.perform_lint(cx, "item", foreign_item.id, &foreign_item.vis, + foreign_item.span, true, Applicability::MachineApplicable); } fn check_struct_field(&mut self, cx: &LateContext, field: &hir::StructField) { - self.perform_lint(cx, "field", field.id, &field.vis, field.span, false); + self.perform_lint(cx, "field", field.id, &field.vis, field.span, false, + Applicability::MachineApplicable); } fn check_impl_item(&mut self, cx: &LateContext, impl_item: &hir::ImplItem) { - self.perform_lint(cx, "item", impl_item.id, &impl_item.vis, impl_item.span, false); + self.perform_lint(cx, "item", impl_item.id, &impl_item.vis, impl_item.span, false, + Applicability::MachineApplicable); } } diff --git a/src/test/ui/lint/unreachable_pub-pub_crate.rs b/src/test/ui/lint/unreachable_pub-pub_crate.rs index f5e6b4d3b4862..0a1926f8ae56a 100644 --- a/src/test/ui/lint/unreachable_pub-pub_crate.rs +++ b/src/test/ui/lint/unreachable_pub-pub_crate.rs @@ -24,6 +24,7 @@ mod private_mod { // non-leaked `pub` items in private module should be linted pub use std::fmt; + pub use std::env::{Args}; // braced-use has different item spans than unbraced pub struct Hydrogen { // `pub` struct fields, too diff --git a/src/test/ui/lint/unreachable_pub-pub_crate.stderr b/src/test/ui/lint/unreachable_pub-pub_crate.stderr index d1711be456bcc..2948deb23009c 100644 --- a/src/test/ui/lint/unreachable_pub-pub_crate.stderr +++ b/src/test/ui/lint/unreachable_pub-pub_crate.stderr @@ -14,7 +14,15 @@ LL | #![warn(unreachable_pub)] = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:28:5 + --> $DIR/unreachable_pub-pub_crate.rs:27:24 + | +LL | pub use std::env::{Args}; // braced-use has different item spans than unbraced + | ^^^^ help: consider restricting its visibility: `pub(crate)` + | + = help: or consider exporting it for use by other crates + +warning: unreachable `pub` item + --> $DIR/unreachable_pub-pub_crate.rs:29:5 | LL | pub struct Hydrogen { | ---^^^^^^^^^^^^^^^^ @@ -24,7 +32,7 @@ LL | pub struct Hydrogen { = help: or consider exporting it for use by other crates warning: unreachable `pub` field - --> $DIR/unreachable_pub-pub_crate.rs:30:9 + --> $DIR/unreachable_pub-pub_crate.rs:31:9 | LL | pub neutrons: usize, | ---^^^^^^^^^^^^^^^^ @@ -32,7 +40,7 @@ LL | pub neutrons: usize, | help: consider restricting its visibility: `pub(crate)` warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:36:9 + --> $DIR/unreachable_pub-pub_crate.rs:37:9 | LL | pub fn count_neutrons(&self) -> usize { self.neutrons } | ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +48,7 @@ LL | pub fn count_neutrons(&self) -> usize { self.neutrons } | help: consider restricting its visibility: `pub(crate)` warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:40:5 + --> $DIR/unreachable_pub-pub_crate.rs:41:5 | LL | pub enum Helium {} | ---^^^^^^^^^^^^ @@ -50,7 +58,7 @@ LL | pub enum Helium {} = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:41:5 + --> $DIR/unreachable_pub-pub_crate.rs:42:5 | LL | pub union Lithium { c1: usize, c2: u8 } | ---^^^^^^^^^^^^^^ @@ -60,7 +68,7 @@ LL | pub union Lithium { c1: usize, c2: u8 } = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:42:5 + --> $DIR/unreachable_pub-pub_crate.rs:43:5 | LL | pub fn beryllium() {} | ---^^^^^^^^^^^^^^^ @@ -70,7 +78,7 @@ LL | pub fn beryllium() {} = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:43:5 + --> $DIR/unreachable_pub-pub_crate.rs:44:5 | LL | pub trait Boron {} | ---^^^^^^^^^^^^ @@ -80,7 +88,7 @@ LL | pub trait Boron {} = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:44:5 + --> $DIR/unreachable_pub-pub_crate.rs:45:5 | LL | pub const CARBON: usize = 1; | ---^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -90,7 +98,7 @@ LL | pub const CARBON: usize = 1; = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:45:5 + --> $DIR/unreachable_pub-pub_crate.rs:46:5 | LL | pub static NITROGEN: usize = 2; | ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -100,7 +108,7 @@ LL | pub static NITROGEN: usize = 2; = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:46:5 + --> $DIR/unreachable_pub-pub_crate.rs:47:5 | LL | pub type Oxygen = bool; | ---^^^^^^^^^^^^^^^^^^^^ @@ -110,7 +118,7 @@ LL | pub type Oxygen = bool; = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:49:47 + --> $DIR/unreachable_pub-pub_crate.rs:50:47 | LL | ($visibility: vis, $name: ident) => { $visibility struct $name {} } | -----------^^^^^^^^^^^^^ @@ -123,7 +131,7 @@ LL | define_empty_struct_with_visibility!(pub, Fluorine); = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:54:9 + --> $DIR/unreachable_pub-pub_crate.rs:55:9 | LL | pub fn catalyze() -> bool; | ---^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/lint/unreachable_pub.rs b/src/test/ui/lint/unreachable_pub.rs index 347579c3e7bb9..5bb67670d85c2 100644 --- a/src/test/ui/lint/unreachable_pub.rs +++ b/src/test/ui/lint/unreachable_pub.rs @@ -19,6 +19,7 @@ mod private_mod { // non-leaked `pub` items in private module should be linted pub use std::fmt; + pub use std::env::{Args}; // braced-use has different item spans than unbraced pub struct Hydrogen { // `pub` struct fields, too diff --git a/src/test/ui/lint/unreachable_pub.stderr b/src/test/ui/lint/unreachable_pub.stderr index 1d693161108db..ad88c55d54013 100644 --- a/src/test/ui/lint/unreachable_pub.stderr +++ b/src/test/ui/lint/unreachable_pub.stderr @@ -14,7 +14,15 @@ LL | #![warn(unreachable_pub)] = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:23:5 + --> $DIR/unreachable_pub.rs:22:24 + | +LL | pub use std::env::{Args}; // braced-use has different item spans than unbraced + | ^^^^ help: consider restricting its visibility: `crate` + | + = help: or consider exporting it for use by other crates + +warning: unreachable `pub` item + --> $DIR/unreachable_pub.rs:24:5 | LL | pub struct Hydrogen { | ---^^^^^^^^^^^^^^^^ @@ -24,7 +32,7 @@ LL | pub struct Hydrogen { = help: or consider exporting it for use by other crates warning: unreachable `pub` field - --> $DIR/unreachable_pub.rs:25:9 + --> $DIR/unreachable_pub.rs:26:9 | LL | pub neutrons: usize, | ---^^^^^^^^^^^^^^^^ @@ -32,7 +40,7 @@ LL | pub neutrons: usize, | help: consider restricting its visibility: `crate` warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:31:9 + --> $DIR/unreachable_pub.rs:32:9 | LL | pub fn count_neutrons(&self) -> usize { self.neutrons } | ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +48,7 @@ LL | pub fn count_neutrons(&self) -> usize { self.neutrons } | help: consider restricting its visibility: `crate` warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:35:5 + --> $DIR/unreachable_pub.rs:36:5 | LL | pub enum Helium {} | ---^^^^^^^^^^^^ @@ -50,7 +58,7 @@ LL | pub enum Helium {} = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:36:5 + --> $DIR/unreachable_pub.rs:37:5 | LL | pub union Lithium { c1: usize, c2: u8 } | ---^^^^^^^^^^^^^^ @@ -60,7 +68,7 @@ LL | pub union Lithium { c1: usize, c2: u8 } = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:37:5 + --> $DIR/unreachable_pub.rs:38:5 | LL | pub fn beryllium() {} | ---^^^^^^^^^^^^^^^ @@ -70,7 +78,7 @@ LL | pub fn beryllium() {} = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:38:5 + --> $DIR/unreachable_pub.rs:39:5 | LL | pub trait Boron {} | ---^^^^^^^^^^^^ @@ -80,7 +88,7 @@ LL | pub trait Boron {} = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:39:5 + --> $DIR/unreachable_pub.rs:40:5 | LL | pub const CARBON: usize = 1; | ---^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -90,7 +98,7 @@ LL | pub const CARBON: usize = 1; = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:40:5 + --> $DIR/unreachable_pub.rs:41:5 | LL | pub static NITROGEN: usize = 2; | ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -100,7 +108,7 @@ LL | pub static NITROGEN: usize = 2; = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:41:5 + --> $DIR/unreachable_pub.rs:42:5 | LL | pub type Oxygen = bool; | ---^^^^^^^^^^^^^^^^^^^^ @@ -110,7 +118,7 @@ LL | pub type Oxygen = bool; = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:44:47 + --> $DIR/unreachable_pub.rs:45:47 | LL | ($visibility: vis, $name: ident) => { $visibility struct $name {} } | -----------^^^^^^^^^^^^^ @@ -123,7 +131,7 @@ LL | define_empty_struct_with_visibility!(pub, Fluorine); = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:49:9 + --> $DIR/unreachable_pub.rs:50:9 | LL | pub fn catalyze() -> bool; | ---^^^^^^^^^^^^^^^^^^^^^^^ From c3b23b3b1413c92137b329fd63f95abc1cd7a8b1 Mon Sep 17 00:00:00 2001 From: kennytm Date: Fri, 11 May 2018 12:30:50 +0800 Subject: [PATCH 08/18] AppVeyor: Dump crash log on failure. --- appveyor.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index a92f4a1781181..60f5b4be8def8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -211,6 +211,11 @@ test_script: - set NO_CCACHE=1 - sh src/ci/run.sh +on_failure: + # Dump crash log + - set PATH=%PATH%;"C:\Program Files (x86)\Windows Kits\10\Debuggers\X64" + - if exist %LOCALAPPDATA%\CrashDumps for %%f in (%LOCALAPPDATA%\CrashDumps\*) do cdb -c "k;q" -G -z "%%f" + branches: only: - auto From 89a8f2c10332b059e14999dc19fde4cc03ef7167 Mon Sep 17 00:00:00 2001 From: Isaac Whitfield Date: Tue, 8 May 2018 22:20:09 -0700 Subject: [PATCH 09/18] Remove shared access to DepGraph::work_products --- src/librustc/dep_graph/graph.rs | 25 +--------------- src/librustc_incremental/persist/mod.rs | 2 +- src/librustc_incremental/persist/save.rs | 17 +++++------ .../persist/work_product.rs | 18 ++++++------ src/librustc_trans/back/write.rs | 29 +++++++++++-------- src/librustc_trans/lib.rs | 6 ++-- 6 files changed, 39 insertions(+), 58 deletions(-) diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 03aff64100558..797332e699d4b 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -13,7 +13,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::small_vec::SmallVec; -use rustc_data_structures::sync::{Lrc, RwLock, ReadGuard, Lock}; +use rustc_data_structures::sync::{Lrc, Lock}; use std::env; use std::hash::Hash; use ty::{self, TyCtxt}; @@ -80,9 +80,6 @@ struct DepGraphData { /// this map. We can later look for and extract that data. previous_work_products: FxHashMap, - /// Work-products that we generate in this run. - work_products: RwLock>, - dep_node_debug: Lock>, // Used for testing, only populated when -Zquery-dep-graph is specified. @@ -103,7 +100,6 @@ impl DepGraph { DepGraph { data: Some(Lrc::new(DepGraphData { previous_work_products: prev_work_products, - work_products: RwLock::new(FxHashMap()), dep_node_debug: Lock::new(FxHashMap()), current: Lock::new(CurrentDepGraph::new()), previous: prev_graph, @@ -462,19 +458,6 @@ impl DepGraph { self.data.as_ref().unwrap().previous.node_to_index(dep_node) } - /// Indicates that we created the given work-product in this run - /// for `v`. This record will be preserved and loaded in the next - /// run. - pub fn insert_work_product(&self, v: &WorkProductId, data: WorkProduct) { - debug!("insert_work_product({:?}, {:?})", v, data); - self.data - .as_ref() - .unwrap() - .work_products - .borrow_mut() - .insert(v.clone(), data); - } - /// Check whether a previous work product exists for `v` and, if /// so, return the path that leads to it. Used to skip doing work. pub fn previous_work_product(&self, v: &WorkProductId) -> Option { @@ -485,12 +468,6 @@ impl DepGraph { }) } - /// Access the map of work-products created during this run. Only - /// used during saving of the dep-graph. - pub fn work_products(&self) -> ReadGuard> { - self.data.as_ref().unwrap().work_products.borrow() - } - /// Access the map of work-products created during the cached run. Only /// used during saving of the dep-graph. pub fn previous_work_products(&self) -> &FxHashMap { diff --git a/src/librustc_incremental/persist/mod.rs b/src/librustc_incremental/persist/mod.rs index 755a550b5bca3..3c23b7c6417bc 100644 --- a/src/librustc_incremental/persist/mod.rs +++ b/src/librustc_incremental/persist/mod.rs @@ -30,5 +30,5 @@ pub use self::load::load_query_result_cache; pub use self::load::LoadResult; pub use self::save::save_dep_graph; pub use self::save::save_work_products; -pub use self::work_product::save_trans_partition; +pub use self::work_product::create_trans_partition; pub use self::work_product::delete_workproduct_files; diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs index e524fcecf9094..497d24fae5bfe 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/src/librustc_incremental/persist/save.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc::dep_graph::{DepGraph, DepKind}; +use rustc::dep_graph::{DepGraph, DepKind, WorkProduct, WorkProductId}; use rustc::session::Session; use rustc::ty::TyCtxt; use rustc::util::common::time; @@ -55,7 +55,9 @@ pub fn save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { }) } -pub fn save_work_products(sess: &Session, dep_graph: &DepGraph) { +pub fn save_work_products(sess: &Session, + dep_graph: &DepGraph, + new_work_products: FxHashMap) { if sess.opts.incremental.is_none() { return; } @@ -63,14 +65,12 @@ pub fn save_work_products(sess: &Session, dep_graph: &DepGraph) { debug!("save_work_products()"); dep_graph.assert_ignored(); let path = work_products_path(sess); - save_in(sess, path, |e| encode_work_products(dep_graph, e)); + save_in(sess, path, |e| encode_work_products(&new_work_products, e)); // We also need to clean out old work-products, as not all of them are // deleted during invalidation. Some object files don't change their // content, they are just not needed anymore. - let new_work_products = dep_graph.work_products(); let previous_work_products = dep_graph.previous_work_products(); - for (id, wp) in previous_work_products.iter() { if !new_work_products.contains_key(id) { work_product::delete_workproduct_files(sess, wp); @@ -234,10 +234,9 @@ fn encode_dep_graph(tcx: TyCtxt, Ok(()) } -fn encode_work_products(dep_graph: &DepGraph, +fn encode_work_products(work_products: &FxHashMap, encoder: &mut Encoder) -> io::Result<()> { - let work_products: Vec<_> = dep_graph - .work_products() + let serialized_products: Vec<_> = work_products .iter() .map(|(id, work_product)| { SerializedWorkProduct { @@ -247,7 +246,7 @@ fn encode_work_products(dep_graph: &DepGraph, }) .collect(); - work_products.encode(encoder) + serialized_products.encode(encoder) } fn encode_query_cache(tcx: TyCtxt, diff --git a/src/librustc_incremental/persist/work_product.rs b/src/librustc_incremental/persist/work_product.rs index 879132bcacfcf..23e3664cdba13 100644 --- a/src/librustc_incremental/persist/work_product.rs +++ b/src/librustc_incremental/persist/work_product.rs @@ -11,21 +11,21 @@ //! This module contains files for saving intermediate work-products. use persist::fs::*; -use rustc::dep_graph::{WorkProduct, WorkProductId, DepGraph, WorkProductFileKind}; +use rustc::dep_graph::{WorkProduct, WorkProductId, WorkProductFileKind}; use rustc::session::Session; use rustc::util::fs::link_or_copy; use std::path::PathBuf; use std::fs as std_fs; -pub fn save_trans_partition(sess: &Session, - dep_graph: &DepGraph, - cgu_name: &str, - files: &[(WorkProductFileKind, PathBuf)]) { - debug!("save_trans_partition({:?},{:?})", +pub fn create_trans_partition(sess: &Session, + cgu_name: &str, + files: &[(WorkProductFileKind, PathBuf)]) + -> Option<(WorkProductId, WorkProduct)> { + debug!("create_trans_partition({:?},{:?})", cgu_name, files); if sess.opts.incremental.is_none() { - return + return None } let work_product_id = WorkProductId::from_cgu_name(cgu_name); @@ -53,8 +53,8 @@ pub fn save_trans_partition(sess: &Session, }) .collect(); let saved_files = match saved_files { + None => return None, Some(v) => v, - None => return, }; let work_product = WorkProduct { @@ -62,7 +62,7 @@ pub fn save_trans_partition(sess: &Session, saved_files, }; - dep_graph.insert_work_product(&work_product_id, work_product); + Some((work_product_id, work_product)) } pub fn delete_workproduct_files(sess: &Session, work_product: &WorkProduct) { diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 64876e82309f0..70b2796b7755d 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -17,8 +17,8 @@ use back::linker::LinkerInfo; use back::symbol_export::ExportedSymbols; use base; use consts; -use rustc_incremental::{save_trans_partition, in_incr_comp_dir}; -use rustc::dep_graph::{DepGraph, WorkProductFileKind}; +use rustc_incremental::{create_trans_partition, in_incr_comp_dir}; +use rustc::dep_graph::{WorkProduct, WorkProductId, WorkProductFileKind}; use rustc::middle::cstore::{LinkMeta, EncodedMetadata}; use rustc::session::config::{self, OutputFilenames, OutputType, Passes, SomePasses, AllPasses, Sanitizer, Lto}; @@ -1021,11 +1021,13 @@ pub fn start_async_translation(tcx: TyCtxt, } } -fn copy_module_artifacts_into_incr_comp_cache(sess: &Session, - dep_graph: &DepGraph, - compiled_modules: &CompiledModules) { +fn generate_module_artifacts(sess: &Session, + compiled_modules: &CompiledModules) + -> FxHashMap { + let mut work_products = FxHashMap::default(); + if sess.opts.incremental.is_none() { - return; + return work_products; } for module in compiled_modules.modules.iter() { @@ -1041,8 +1043,12 @@ fn copy_module_artifacts_into_incr_comp_cache(sess: &Session, files.push((WorkProductFileKind::BytecodeCompressed, path.clone())); } - save_trans_partition(sess, dep_graph, &module.name, &files); + if let Some((id, product)) = create_trans_partition(sess, &module.name, &files) { + work_products.insert(id, product); + } } + + work_products } fn produce_final_output_artifacts(sess: &Session, @@ -2236,7 +2242,7 @@ pub struct OngoingCrateTranslation { } impl OngoingCrateTranslation { - pub(crate) fn join(self, sess: &Session, dep_graph: &DepGraph) -> CrateTranslation { + pub(crate) fn join(self, sess: &Session) -> (CrateTranslation, FxHashMap) { self.shared_emitter_main.check(sess, true); let compiled_modules = match self.future.join() { Ok(Ok(compiled_modules)) => compiled_modules, @@ -2255,9 +2261,8 @@ impl OngoingCrateTranslation { time_graph.dump(&format!("{}-timings", self.crate_name)); } - copy_module_artifacts_into_incr_comp_cache(sess, - dep_graph, - &compiled_modules); + let work_products = generate_module_artifacts(sess, &compiled_modules); + produce_final_output_artifacts(sess, &compiled_modules, &self.output_filenames); @@ -2281,7 +2286,7 @@ impl OngoingCrateTranslation { metadata_module: compiled_modules.metadata_module, }; - trans + (trans, work_products) } pub(crate) fn submit_pre_translated_module_to_llvm(&self, diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 7a152d6ded4c5..bc8747ca4f5c7 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -212,16 +212,16 @@ impl TransCrate for LlvmTransCrate { outputs: &OutputFilenames, ) -> Result<(), CompileIncomplete>{ use rustc::util::common::time; - let trans = trans.downcast::<::back::write::OngoingCrateTranslation>() + let (trans, work_products) = trans.downcast::<::back::write::OngoingCrateTranslation>() .expect("Expected LlvmTransCrate's OngoingCrateTranslation, found Box") - .join(sess, dep_graph); + .join(sess); if sess.opts.debugging_opts.incremental_info { back::write::dump_incremental_data(&trans); } time(sess, "serialize work products", - move || rustc_incremental::save_work_products(sess, &dep_graph)); + move || rustc_incremental::save_work_products(sess, &dep_graph, work_products)); sess.compile_status()?; From d23cbc3fbec44fe1ffbc468a396cf65755b56fc8 Mon Sep 17 00:00:00 2001 From: Isaac Whitfield Date: Tue, 8 May 2018 22:26:50 -0700 Subject: [PATCH 10/18] Catch a bad reference in use clauses --- src/librustc_incremental/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index a5e07bcec24bb..af33e87803264 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -36,8 +36,8 @@ pub use persist::dep_graph_tcx_init; pub use persist::load_dep_graph; pub use persist::load_query_result_cache; pub use persist::LoadResult; +pub use persist::create_trans_partition; pub use persist::save_dep_graph; -pub use persist::save_trans_partition; pub use persist::save_work_products; pub use persist::in_incr_comp_dir; pub use persist::prepare_session_directory; From 5c83422a5bdf8eacd4bbc727fb880b99ed66b04f Mon Sep 17 00:00:00 2001 From: Isaac Whitfield Date: Tue, 8 May 2018 23:10:03 -0700 Subject: [PATCH 11/18] Neaten a couple of long signatures --- src/librustc_trans/back/write.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 70b2796b7755d..afa9bca2ba98c 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -1021,9 +1021,10 @@ pub fn start_async_translation(tcx: TyCtxt, } } -fn generate_module_artifacts(sess: &Session, - compiled_modules: &CompiledModules) - -> FxHashMap { +fn generate_module_artifacts( + sess: &Session, + compiled_modules: &CompiledModules +) -> FxHashMap { let mut work_products = FxHashMap::default(); if sess.opts.incremental.is_none() { @@ -2242,7 +2243,10 @@ pub struct OngoingCrateTranslation { } impl OngoingCrateTranslation { - pub(crate) fn join(self, sess: &Session) -> (CrateTranslation, FxHashMap) { + pub(crate) fn join( + self, + sess: &Session + ) -> (CrateTranslation, FxHashMap) { self.shared_emitter_main.check(sess, true); let compiled_modules = match self.future.join() { Ok(Ok(compiled_modules)) => compiled_modules, From 0a4fbe326a4a05ff01d07d362cc554bd8414ce89 Mon Sep 17 00:00:00 2001 From: Isaac Whitfield Date: Wed, 9 May 2018 08:16:08 -0700 Subject: [PATCH 12/18] Update naming in line with PR comments --- src/librustc_incremental/lib.rs | 4 ++-- src/librustc_incremental/persist/mod.rs | 4 ++-- src/librustc_incremental/persist/save.rs | 14 +++++++------- src/librustc_incremental/persist/work_product.rs | 9 +++++---- src/librustc_trans/back/write.rs | 10 ++++++---- src/librustc_trans/lib.rs | 2 +- 6 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index af33e87803264..ababce69e3170 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -36,9 +36,9 @@ pub use persist::dep_graph_tcx_init; pub use persist::load_dep_graph; pub use persist::load_query_result_cache; pub use persist::LoadResult; -pub use persist::create_trans_partition; +pub use persist::copy_cgu_workproducts_to_incr_comp_cache_dir; pub use persist::save_dep_graph; -pub use persist::save_work_products; +pub use persist::save_work_product_index; pub use persist::in_incr_comp_dir; pub use persist::prepare_session_directory; pub use persist::finalize_session_directory; diff --git a/src/librustc_incremental/persist/mod.rs b/src/librustc_incremental/persist/mod.rs index 3c23b7c6417bc..e1f00db56d5cb 100644 --- a/src/librustc_incremental/persist/mod.rs +++ b/src/librustc_incremental/persist/mod.rs @@ -29,6 +29,6 @@ pub use self::load::load_dep_graph; pub use self::load::load_query_result_cache; pub use self::load::LoadResult; pub use self::save::save_dep_graph; -pub use self::save::save_work_products; -pub use self::work_product::create_trans_partition; +pub use self::save::save_work_product_index; +pub use self::work_product::copy_cgu_workproducts_to_incr_comp_cache_dir; pub use self::work_product::delete_workproduct_files; diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs index 497d24fae5bfe..be725b1793321 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/src/librustc_incremental/persist/save.rs @@ -55,17 +55,17 @@ pub fn save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { }) } -pub fn save_work_products(sess: &Session, - dep_graph: &DepGraph, - new_work_products: FxHashMap) { +pub fn save_work_product_index(sess: &Session, + dep_graph: &DepGraph, + new_work_products: FxHashMap) { if sess.opts.incremental.is_none() { return; } - debug!("save_work_products()"); + debug!("save_work_product_index()"); dep_graph.assert_ignored(); let path = work_products_path(sess); - save_in(sess, path, |e| encode_work_products(&new_work_products, e)); + save_in(sess, path, |e| encode_work_product_index(&new_work_products, e)); // We also need to clean out old work-products, as not all of them are // deleted during invalidation. Some object files don't change their @@ -234,8 +234,8 @@ fn encode_dep_graph(tcx: TyCtxt, Ok(()) } -fn encode_work_products(work_products: &FxHashMap, - encoder: &mut Encoder) -> io::Result<()> { +fn encode_work_product_index(work_products: &FxHashMap, + encoder: &mut Encoder) -> io::Result<()> { let serialized_products: Vec<_> = work_products .iter() .map(|(id, work_product)| { diff --git a/src/librustc_incremental/persist/work_product.rs b/src/librustc_incremental/persist/work_product.rs index 23e3664cdba13..d163ad1f3f322 100644 --- a/src/librustc_incremental/persist/work_product.rs +++ b/src/librustc_incremental/persist/work_product.rs @@ -17,10 +17,11 @@ use rustc::util::fs::link_or_copy; use std::path::PathBuf; use std::fs as std_fs; -pub fn create_trans_partition(sess: &Session, - cgu_name: &str, - files: &[(WorkProductFileKind, PathBuf)]) - -> Option<(WorkProductId, WorkProduct)> { +pub fn copy_cgu_workproducts_to_incr_comp_cache_dir( + sess: &Session, + cgu_name: &str, + files: &[(WorkProductFileKind, PathBuf)] +) -> Option<(WorkProductId, WorkProduct)> { debug!("create_trans_partition({:?},{:?})", cgu_name, files); diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index afa9bca2ba98c..888173d4fc515 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -17,7 +17,7 @@ use back::linker::LinkerInfo; use back::symbol_export::ExportedSymbols; use base; use consts; -use rustc_incremental::{create_trans_partition, in_incr_comp_dir}; +use rustc_incremental::{copy_cgu_workproducts_to_incr_comp_cache_dir, in_incr_comp_dir}; use rustc::dep_graph::{WorkProduct, WorkProductId, WorkProductFileKind}; use rustc::middle::cstore::{LinkMeta, EncodedMetadata}; use rustc::session::config::{self, OutputFilenames, OutputType, Passes, SomePasses, @@ -1021,7 +1021,7 @@ pub fn start_async_translation(tcx: TyCtxt, } } -fn generate_module_artifacts( +fn copy_all_cgu_workproducts_to_incr_comp_cache_dir( sess: &Session, compiled_modules: &CompiledModules ) -> FxHashMap { @@ -1044,7 +1044,8 @@ fn generate_module_artifacts( files.push((WorkProductFileKind::BytecodeCompressed, path.clone())); } - if let Some((id, product)) = create_trans_partition(sess, &module.name, &files) { + if let Some((id, product)) = + copy_cgu_workproducts_to_incr_comp_cache_dir(sess, &module.name, &files) { work_products.insert(id, product); } } @@ -2265,7 +2266,8 @@ impl OngoingCrateTranslation { time_graph.dump(&format!("{}-timings", self.crate_name)); } - let work_products = generate_module_artifacts(sess, &compiled_modules); + let work_products = copy_all_cgu_workproducts_to_incr_comp_cache_dir(sess, + &compiled_modules); produce_final_output_artifacts(sess, &compiled_modules, diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index bc8747ca4f5c7..30780b8c96563 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -221,7 +221,7 @@ impl TransCrate for LlvmTransCrate { time(sess, "serialize work products", - move || rustc_incremental::save_work_products(sess, &dep_graph, work_products)); + move || rustc_incremental::save_work_product_index(sess, &dep_graph, work_products)); sess.compile_status()?; From 8402a58528dc9f3c47208f3ed152132b67f7f217 Mon Sep 17 00:00:00 2001 From: Isaac Whitfield Date: Wed, 9 May 2018 08:32:04 -0700 Subject: [PATCH 13/18] Update an old method name in debug logging --- src/librustc_incremental/persist/work_product.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_incremental/persist/work_product.rs b/src/librustc_incremental/persist/work_product.rs index d163ad1f3f322..d0c7766cbae08 100644 --- a/src/librustc_incremental/persist/work_product.rs +++ b/src/librustc_incremental/persist/work_product.rs @@ -22,7 +22,7 @@ pub fn copy_cgu_workproducts_to_incr_comp_cache_dir( cgu_name: &str, files: &[(WorkProductFileKind, PathBuf)] ) -> Option<(WorkProductId, WorkProduct)> { - debug!("create_trans_partition({:?},{:?})", + debug!("copy_cgu_workproducts_to_incr_comp_cache_dir({:?},{:?})", cgu_name, files); if sess.opts.incremental.is_none() { From 0588bcadf81ef7ac88914c0f8dd2bbfbb164f09c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 11 May 2018 09:14:23 -0700 Subject: [PATCH 14/18] rustc: Allow an edition's feature on that edition This commit fixes a hard error where the `#![feature(rust_2018_preview)]` feature was forbidden to be mentioned when the `--edition 2018` flag was passed. This instead silently accepts that feature gate despite it not being necessary. It's intended that this will help ease the transition into the 2018 edition as users will, for the time being, start off with the `rust_2018_preview` feature and no longer immediately need to remove it. Closes #50662 --- src/libsyntax/feature_gate.rs | 87 +++++++++++---------- src/test/compile-fail/edition-feature-ok.rs | 16 ++++ 2 files changed, 62 insertions(+), 41 deletions(-) create mode 100644 src/test/compile-fail/edition-feature-ok.rs diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index a137faf689fb7..b27568a61f85c 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1861,56 +1861,61 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], continue } - match attr.meta_item_list() { + let list = match attr.meta_item_list() { + Some(list) => list, None => { span_err!(span_handler, attr.span, E0555, "malformed feature attribute, expected #![feature(...)]"); + continue + } + }; + + for mi in list { + let name = if let Some(word) = mi.word() { + word.name() + } else { + span_err!(span_handler, mi.span, E0556, + "malformed feature, expected just one word"); + continue + }; + + if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) { + set(&mut features, mi.span); + feature_checker.collect(&features, mi.span); + continue } - Some(list) => { - for mi in list { - let name = if let Some(word) = mi.word() { - word.name() - } else { - span_err!(span_handler, mi.span, E0556, - "malformed feature, expected just one word"); - continue - }; - - if let Some(&(_, _, _, _, set)) = ACTIVE_FEATURES.iter() - .find(|& &(n, ..)| name == n) { - set(&mut features, mi.span); - feature_checker.collect(&features, mi.span); - } - else if let Some(&(.., reason)) = REMOVED_FEATURES.iter() - .find(|& &(n, ..)| name == n) - .or_else(|| STABLE_REMOVED_FEATURES.iter() - .find(|& &(n, ..)| name == n)) { - feature_removed(span_handler, mi.span, reason); - } - else if let Some(&(..)) = ACCEPTED_FEATURES.iter() - .find(|& &(n, ..)| name == n) { - features.declared_stable_lang_features.push((name, mi.span)); - } else if let Some(&edition) = ALL_EDITIONS.iter() - .find(|e| name == e.feature_name()) { - if edition <= crate_edition { - feature_removed(span_handler, mi.span, None); - } else { - for &(.., f_edition, set) in ACTIVE_FEATURES.iter() { - if let Some(f_edition) = f_edition { - if edition >= f_edition { - // FIXME(Manishearth) there is currently no way to set - // lib features by edition - set(&mut features, DUMMY_SP); - } - } - } + let removed = REMOVED_FEATURES.iter().find(|f| name == f.0); + let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.0); + if let Some((.., reason)) = removed.or(stable_removed) { + feature_removed(span_handler, mi.span, *reason); + continue + } + + if ACCEPTED_FEATURES.iter().any(|f| name == f.0) { + features.declared_stable_lang_features.push((name, mi.span)); + continue + } + + if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) { + if *edition <= crate_edition { + continue + } + + for &(.., f_edition, set) in ACTIVE_FEATURES.iter() { + if let Some(f_edition) = f_edition { + if *edition >= f_edition { + // FIXME(Manishearth) there is currently no way to set + // lib features by edition + set(&mut features, DUMMY_SP); } - } else { - features.declared_lib_features.push((name, mi.span)); } } + + continue } + + features.declared_lib_features.push((name, mi.span)); } } diff --git a/src/test/compile-fail/edition-feature-ok.rs b/src/test/compile-fail/edition-feature-ok.rs new file mode 100644 index 0000000000000..3a3a6ff95f97e --- /dev/null +++ b/src/test/compile-fail/edition-feature-ok.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. + +// compile-flags:--edition 2018 +// compile-pass + +#![feature(rust_2018_preview)] + +fn main() {} From eab91ba8730157ce2b587f996286b2df9627c7a8 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 11 May 2018 10:02:17 -0700 Subject: [PATCH 15/18] rustc: Fix `crate` lint for single-item paths This commit fixes recommending the `crate` prefix when migrating to 2018 for paths that look like `use foo;` or `use {bar, baz}` Closes #50660 --- src/librustc_resolve/lib.rs | 95 +++++++++++++++++++-------- src/test/ui/edition-lint-paths.rs | 17 +++++ src/test/ui/edition-lint-paths.stderr | 33 +++++++++- 3 files changed, 115 insertions(+), 30 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 0f931d4374e59..d768b5e8edf9e 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3232,6 +3232,7 @@ impl<'a> Resolver<'a> { -> PathResult<'a> { let mut module = None; let mut allow_super = true; + let mut second_binding = None; for (i, &ident) in path.iter().enumerate() { debug!("resolve_path ident {} {:?}", i, ident); @@ -3334,6 +3335,9 @@ impl<'a> Resolver<'a> { match binding { Ok(binding) => { + if i == 1 { + second_binding = Some(binding); + } let def = binding.def(); let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(def); if let Some(next_module) = binding.module() { @@ -3341,6 +3345,12 @@ impl<'a> Resolver<'a> { } else if def == Def::Err { return PathResult::NonModule(err_path_resolution()); } else if opt_ns.is_some() && (is_last || maybe_assoc) { + self.lint_if_path_starts_with_module( + node_id, + path, + path_span, + second_binding, + ); return PathResult::NonModule(PathResolution::with_unresolved_segments( def, path.len() - i - 1 )); @@ -3349,33 +3359,6 @@ impl<'a> Resolver<'a> { format!("Not a module `{}`", ident), is_last); } - - if let Some(id) = node_id { - if i == 1 && self.session.features_untracked().crate_in_paths - && !self.session.rust_2018() { - let prev_name = path[0].name; - if prev_name == keywords::Extern.name() || - prev_name == keywords::CrateRoot.name() { - let mut is_crate = false; - if let NameBindingKind::Import { directive: d, .. } = binding.kind { - if let ImportDirectiveSubclass::ExternCrate(..) = d.subclass { - is_crate = true; - } - } - - if !is_crate { - let diag = lint::builtin::BuiltinLintDiagnostics - ::AbsPathWithModule(path_span); - self.session.buffer_lint_with_diagnostic( - lint::builtin::ABSOLUTE_PATH_STARTING_WITH_MODULE, - id, path_span, - "Absolute paths must start with `self`, `super`, \ - `crate`, or an external crate name in the 2018 edition", - diag); - } - } - } - } } Err(Undetermined) => return PathResult::Indeterminate, Err(Determined) => { @@ -3408,9 +3391,67 @@ impl<'a> Resolver<'a> { } } + self.lint_if_path_starts_with_module(node_id, path, path_span, second_binding); + PathResult::Module(module.unwrap_or(self.graph_root)) } + fn lint_if_path_starts_with_module(&self, + id: Option, + path: &[Ident], + path_span: Span, + second_binding: Option<&NameBinding>) { + // In the 2018 edition this lint is a hard error, so nothing to do + if self.session.rust_2018() { + return + } + // In the 2015 edition there's no use in emitting lints unless the + // crate's already enabled the feature that we're going to suggest + if !self.session.features_untracked().crate_in_paths { + return + } + let id = match id { + Some(id) => id, + None => return, + }; + let first_name = match path.get(0) { + Some(ident) => ident.name, + None => return, + }; + + // We're only interested in `use` paths which should start with + // `{{root}}` or `extern` currently. + if first_name != keywords::Extern.name() && first_name != keywords::CrateRoot.name() { + return + } + + if let Some(part) = path.get(1) { + if part.name == keywords::Crate.name() { + return + } + } + + // If the first element of our path was actually resolved to an + // `ExternCrate` (also used for `crate::...`) then no need to issue a + // warning, this looks all good! + if let Some(binding) = second_binding { + if let NameBindingKind::Import { directive: d, .. } = binding.kind { + if let ImportDirectiveSubclass::ExternCrate(..) = d.subclass { + return + } + } + } + + let diag = lint::builtin::BuiltinLintDiagnostics + ::AbsPathWithModule(path_span); + self.session.buffer_lint_with_diagnostic( + lint::builtin::ABSOLUTE_PATH_STARTING_WITH_MODULE, + id, path_span, + "Absolute paths must start with `self`, `super`, \ + `crate`, or an external crate name in the 2018 edition", + diag); + } + // Resolve a local definition, potentially adjusting for closures. fn adjust_local_def(&mut self, ns: Namespace, diff --git a/src/test/ui/edition-lint-paths.rs b/src/test/ui/edition-lint-paths.rs index 0b49e72ccd94c..e3bccfdc650ae 100644 --- a/src/test/ui/edition-lint-paths.rs +++ b/src/test/ui/edition-lint-paths.rs @@ -18,6 +18,22 @@ pub mod foo { //~| WARN this was previously accepted use super::bar::Bar2; use crate::bar::Bar3; + + use bar; + //~^ ERROR Absolute + //~| WARN this was previously accepted + use crate::{bar as something_else}; + + use {Bar as SomethingElse, main}; + //~^ ERROR Absolute + //~| WARN this was previously accepted + //~| ERROR Absolute + //~| WARN this was previously accepted + + use crate::{Bar as SomethingElse2, main as another_main}; + + pub fn test() { + } } @@ -38,4 +54,5 @@ fn main() { let x = bar::Bar; let x = ::crate::bar::Bar; let x = self::bar::Bar; + foo::test(); } diff --git a/src/test/ui/edition-lint-paths.stderr b/src/test/ui/edition-lint-paths.stderr index 509527e03743c..f2fdb8afaac4f 100644 --- a/src/test/ui/edition-lint-paths.stderr +++ b/src/test/ui/edition-lint-paths.stderr @@ -13,7 +13,34 @@ LL | #![deny(absolute_path_starting_with_module)] = note: for more information, see issue TBD error: Absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-paths.rs:24:5 + --> $DIR/edition-lint-paths.rs:22:9 + | +LL | use bar; + | ^^^ help: use `crate`: `crate::bar` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue TBD + +error: Absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition + --> $DIR/edition-lint-paths.rs:27:10 + | +LL | use {Bar as SomethingElse, main}; + | ^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::Bar as SomethingElse` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue TBD + +error: Absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition + --> $DIR/edition-lint-paths.rs:27:32 + | +LL | use {Bar as SomethingElse, main}; + | ^^^^ help: use `crate`: `crate::main` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue TBD + +error: Absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition + --> $DIR/edition-lint-paths.rs:40:5 | LL | use bar::Bar; | ^^^^^^^^ help: use `crate`: `crate::bar::Bar` @@ -22,7 +49,7 @@ LL | use bar::Bar; = note: for more information, see issue TBD error: Absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - --> $DIR/edition-lint-paths.rs:35:13 + --> $DIR/edition-lint-paths.rs:51:13 | LL | let x = ::bar::Bar; | ^^^^^^^^^^ help: use `crate`: `crate::bar::Bar` @@ -30,5 +57,5 @@ LL | let x = ::bar::Bar; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue TBD -error: aborting due to 3 previous errors +error: aborting due to 6 previous errors From adf2dce33a7a2a387f4e8c6fcc18a06a2ccb5423 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 11 May 2018 10:17:37 -0700 Subject: [PATCH 16/18] Rename lint to absolute_path_not_starting_with_crate --- src/librustc/lint/builtin.rs | 4 ++-- src/librustc_lint/lib.rs | 4 ++-- src/librustc_resolve/lib.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 4f015ed1ce161..5ebea52f3c5ad 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -261,7 +261,7 @@ declare_lint! { } declare_lint! { - pub ABSOLUTE_PATH_STARTING_WITH_MODULE, + pub ABSOLUTE_PATH_NOT_STARTING_WITH_CRATE, Allow, "fully qualified paths that start with a module name \ instead of `crate`, `self`, or an extern crate name" @@ -328,7 +328,7 @@ impl LintPass for HardwiredLints { TYVAR_BEHIND_RAW_POINTER, ELIDED_LIFETIME_IN_PATH, BARE_TRAIT_OBJECT, - ABSOLUTE_PATH_STARTING_WITH_MODULE, + ABSOLUTE_PATH_NOT_STARTING_WITH_CRATE, UNSTABLE_NAME_COLLISION, ) } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 39f550a4b459a..c2d2d3d8adbda 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -40,7 +40,7 @@ extern crate rustc_target; extern crate syntax_pos; use rustc::lint; -use rustc::lint::builtin::{BARE_TRAIT_OBJECT, ABSOLUTE_PATH_STARTING_WITH_MODULE}; +use rustc::lint::builtin::{BARE_TRAIT_OBJECT, ABSOLUTE_PATH_NOT_STARTING_WITH_CRATE}; use rustc::session; use rustc::util; @@ -282,7 +282,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { // standard library, and thus should never be removed or changed to an error. }, FutureIncompatibleInfo { - id: LintId::of(ABSOLUTE_PATH_STARTING_WITH_MODULE), + id: LintId::of(ABSOLUTE_PATH_NOT_STARTING_WITH_CRATE), reference: "issue TBD", edition: Some(Edition::Edition2018), }, diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index d768b5e8edf9e..780b567af8cbe 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3445,7 +3445,7 @@ impl<'a> Resolver<'a> { let diag = lint::builtin::BuiltinLintDiagnostics ::AbsPathWithModule(path_span); self.session.buffer_lint_with_diagnostic( - lint::builtin::ABSOLUTE_PATH_STARTING_WITH_MODULE, + lint::builtin::ABSOLUTE_PATH_NOT_STARTING_WITH_CRATE, id, path_span, "Absolute paths must start with `self`, `super`, \ `crate`, or an external crate name in the 2018 edition", From 43f6b9620e120eac53153c0f788f65bc004bdbec Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 11 May 2018 11:16:29 -0700 Subject: [PATCH 17/18] Clarify what the lexical resolutions are in resolve_path --- src/librustc_resolve/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 780b567af8cbe..6ff4c77507e35 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3322,7 +3322,9 @@ impl<'a> Resolver<'a> { .map(MacroBinding::binding) } else { match self.resolve_ident_in_lexical_scope(ident, ns, record_used, path_span) { + // we found a locally-imported or available item/module Some(LexicalScopeBinding::Item(binding)) => Ok(binding), + // we found a local variable or type param Some(LexicalScopeBinding::Def(def)) if opt_ns == Some(TypeNS) || opt_ns == Some(ValueNS) => { return PathResult::NonModule(PathResolution::with_unresolved_segments( From 094873c163834e4faa5a1b2ffca2b5a6e50aa2b4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 11 May 2018 11:36:30 -0700 Subject: [PATCH 18/18] Fixup some tests --- src/libstd/sys/unix/fd.rs | 2 ++ src/test/ui/edition-lint-paths.rs | 2 +- src/test/ui/edition-lint-paths.stderr | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs index d38c62d74d22d..67546d06b4e55 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -75,6 +75,7 @@ impl FileDesc { unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: usize, offset: i64) -> io::Result { + use convert::TryInto; use libc::pread64; // pread64 on emscripten actually takes a 32 bit offset if let Ok(o) = offset.try_into() { @@ -122,6 +123,7 @@ impl FileDesc { unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: usize, offset: i64) -> io::Result { + use convert::TryInto; use libc::pwrite64; // pwrite64 on emscripten actually takes a 32 bit offset if let Ok(o) = offset.try_into() { diff --git a/src/test/ui/edition-lint-paths.rs b/src/test/ui/edition-lint-paths.rs index e3bccfdc650ae..e063d88257563 100644 --- a/src/test/ui/edition-lint-paths.rs +++ b/src/test/ui/edition-lint-paths.rs @@ -9,7 +9,7 @@ // except according to those terms. #![feature(crate_in_paths)] -#![deny(absolute_path_starting_with_module)] +#![deny(absolute_path_not_starting_with_crate)] #![allow(unused)] pub mod foo { diff --git a/src/test/ui/edition-lint-paths.stderr b/src/test/ui/edition-lint-paths.stderr index f2fdb8afaac4f..29f70c30ea0be 100644 --- a/src/test/ui/edition-lint-paths.stderr +++ b/src/test/ui/edition-lint-paths.stderr @@ -7,8 +7,8 @@ LL | use ::bar::Bar; note: lint level defined here --> $DIR/edition-lint-paths.rs:12:9 | -LL | #![deny(absolute_path_starting_with_module)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(absolute_path_not_starting_with_crate)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue TBD