Rollup merge of #63657 - RalfJung:invalid_value, r=Centril
Crank up invalid value lint
* Warn against uninit `bool` and `char`.
* Warn against 0-init `NonNull` and friends
* Detect transmute-from-0 as zero-initialization ([seen in the wild](https://github.com/glium/glium/issues/1775#issuecomment-522144636))
diff --git a/Cargo.lock b/Cargo.lock
index 070858c..c784246 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -106,7 +106,7 @@
"cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-std-workspace-core 1.0.0",
]
@@ -2729,7 +2729,7 @@
[[package]]
name = "rustc-demangle"
-version = "0.1.15"
+version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2887,7 +2887,7 @@
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"punycode 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
- "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_data_structures 0.0.0",
"rustc_metadata 0.0.0",
"rustc_target 0.0.0",
@@ -4592,7 +4592,7 @@
"checksum rustc-ap-serialize 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "61673783f2089e01033ffa82d1988f55175402071b31253a358292e1624d4602"
"checksum rustc-ap-syntax 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "28f3dd1346d5b0269c07a4a78855e309a298ab569c9c1302d4d4f57f8eee4e84"
"checksum rustc-ap-syntax_pos 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45e67b526dbda3a0c7dab91c8947d43685e7697f52686a4949da3c179cd7c979"
-"checksum rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f4dccf6f4891ebcc0c39f9b6eb1a83b9bf5d747cb439ec6fba4f3b977038af"
+"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
"checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
"checksum rustc-rayon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d2e07e19601f21c59aad953c2632172ba70cb27e685771514ea66e4062b3363"
"checksum rustc-rayon-core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "79d38ca7cbc22fa59f09d8534ea4b27f67b0facf0cbe274433aceea227a02543"
diff --git a/config.toml.example b/config.toml.example
index cb9f388..a3ec4f2 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -141,10 +141,10 @@
# library and facade crates.
#compiler-docs = false
-# Indicate whether submodules are managed and updated automatically.
+# Indicate whether git submodules are managed and updated automatically.
#submodules = true
-# Update submodules only when the checked out commit in the submodules differs
+# Update git submodules only when the checked out commit in the submodules differs
# from what is committed in the main rustc repo.
#fast-submodules = true
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index 9c01de8..ce92ce0 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -37,7 +37,7 @@
let mut new = None;
if let Some(current_as_str) = args[i].to_str() {
if (&*args[i - 1] == "-C" && current_as_str.starts_with("metadata")) ||
- current_as_str.starts_with("-Cmetadata") {
+ current_as_str.starts_with("-Cmetadata") {
new = Some(format!("{}-{}", current_as_str, s));
}
}
@@ -89,7 +89,7 @@
if let Some(crate_name) = crate_name {
if let Some(target) = env::var_os("RUSTC_TIME") {
if target == "all" ||
- target.into_string().unwrap().split(",").any(|c| c.trim() == crate_name)
+ target.into_string().unwrap().split(",").any(|c| c.trim() == crate_name)
{
cmd.arg("-Ztime");
}
@@ -102,8 +102,13 @@
// FIXME: the fact that core here is excluded is due to core_arch from our stdarch submodule
// being broken on the beta compiler with bootstrap passed, so this is a temporary workaround
// (we've just snapped, so there are no cfg(bootstrap) related annotations in core).
- if stage == "0" && crate_name != Some("core") {
- cmd.arg("--cfg").arg("bootstrap");
+ if stage == "0" {
+ if crate_name != Some("core") {
+ cmd.arg("--cfg").arg("bootstrap");
+ } else {
+ // NOTE(eddyb) see FIXME above, except now we need annotations again in core.
+ cmd.arg("--cfg").arg("boostrap_stdarch_ignore_this");
+ }
}
// Print backtrace in case of ICE
@@ -276,10 +281,6 @@
cmd.arg("-C").arg("target-feature=-crt-static");
}
}
-
- if let Ok(map) = env::var("RUSTC_DEBUGINFO_MAP") {
- cmd.arg("--remap-path-prefix").arg(&map);
- }
} else {
// Override linker if necessary.
if let Ok(host_linker) = env::var("RUSTC_HOST_LINKER") {
@@ -296,6 +297,10 @@
}
}
+ if let Ok(map) = env::var("RUSTC_DEBUGINFO_MAP") {
+ cmd.arg("--remap-path-prefix").arg(&map);
+ }
+
// Force all crates compiled by this compiler to (a) be unstable and (b)
// allow the `rustc_private` feature to link to other unstable crates
// also in the sysroot. We also do this for host crates, since those
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 12eb2c8..96987d0 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -790,6 +790,9 @@
if builder.config.llvm_use_libcxx {
cargo.env("LLVM_USE_LIBCXX", "1");
}
+ if builder.config.llvm_optimize && !builder.config.llvm_release_debuginfo {
+ cargo.env("LLVM_NDEBUG", "1");
+ }
}
_ => panic!("unknown backend: {}", backend),
}
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index c92db51..c61e318 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -91,8 +91,10 @@
CoerceUnsized, DispatchFromDyn, Deref, DerefMut, Receiver, Generator, GeneratorState
};
use core::ptr::{self, NonNull, Unique};
+use core::slice;
use core::task::{Context, Poll};
+use crate::alloc::{self, Global, Alloc};
use crate::vec::Vec;
use crate::raw_vec::RawVec;
use crate::str::from_boxed_utf8_unchecked;
@@ -121,6 +123,34 @@
box x
}
+ /// Constructs a new box with uninitialized contents.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(new_uninit)]
+ ///
+ /// let mut five = Box::<u32>::new_uninit();
+ ///
+ /// let five = unsafe {
+ /// // Deferred initialization:
+ /// five.as_mut_ptr().write(5);
+ ///
+ /// five.assume_init()
+ /// };
+ ///
+ /// assert_eq!(*five, 5)
+ /// ```
+ #[unstable(feature = "new_uninit", issue = "63291")]
+ pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
+ let layout = alloc::Layout::new::<mem::MaybeUninit<T>>();
+ let ptr = unsafe {
+ Global.alloc(layout)
+ .unwrap_or_else(|_| alloc::handle_alloc_error(layout))
+ };
+ Box(ptr.cast().into())
+ }
+
/// Constructs a new `Pin<Box<T>>`. If `T` does not implement `Unpin`, then
/// `x` will be pinned in memory and unable to be moved.
#[stable(feature = "pin", since = "1.33.0")]
@@ -130,6 +160,111 @@
}
}
+impl<T> Box<[T]> {
+ /// Constructs a new boxed slice with uninitialized contents.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(new_uninit)]
+ ///
+ /// let mut values = Box::<[u32]>::new_uninit_slice(3);
+ ///
+ /// let values = unsafe {
+ /// // Deferred initialization:
+ /// values[0].as_mut_ptr().write(1);
+ /// values[1].as_mut_ptr().write(2);
+ /// values[2].as_mut_ptr().write(3);
+ ///
+ /// values.assume_init()
+ /// };
+ ///
+ /// assert_eq!(*values, [1, 2, 3])
+ /// ```
+ #[unstable(feature = "new_uninit", issue = "63291")]
+ pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
+ let layout = alloc::Layout::array::<mem::MaybeUninit<T>>(len).unwrap();
+ let ptr = unsafe { alloc::alloc(layout) };
+ let unique = Unique::new(ptr).unwrap_or_else(|| alloc::handle_alloc_error(layout));
+ let slice = unsafe { slice::from_raw_parts_mut(unique.cast().as_ptr(), len) };
+ Box(Unique::from(slice))
+ }
+}
+
+impl<T> Box<mem::MaybeUninit<T>> {
+ /// Converts to `Box<T>`.
+ ///
+ /// # Safety
+ ///
+ /// As with [`MaybeUninit::assume_init`],
+ /// it is up to the caller to guarantee that the value
+ /// really is in an initialized state.
+ /// Calling this when the content is not yet fully initialized
+ /// causes immediate undefined behavior.
+ ///
+ /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(new_uninit)]
+ ///
+ /// let mut five = Box::<u32>::new_uninit();
+ ///
+ /// let five: Box<u32> = unsafe {
+ /// // Deferred initialization:
+ /// five.as_mut_ptr().write(5);
+ ///
+ /// five.assume_init()
+ /// };
+ ///
+ /// assert_eq!(*five, 5)
+ /// ```
+ #[unstable(feature = "new_uninit", issue = "63291")]
+ #[inline]
+ pub unsafe fn assume_init(self) -> Box<T> {
+ Box(Box::into_unique(self).cast())
+ }
+}
+
+impl<T> Box<[mem::MaybeUninit<T>]> {
+ /// Converts to `Box<[T]>`.
+ ///
+ /// # Safety
+ ///
+ /// As with [`MaybeUninit::assume_init`],
+ /// it is up to the caller to guarantee that the values
+ /// really are in an initialized state.
+ /// Calling this when the content is not yet fully initialized
+ /// causes immediate undefined behavior.
+ ///
+ /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(new_uninit)]
+ ///
+ /// let mut values = Box::<[u32]>::new_uninit_slice(3);
+ ///
+ /// let values = unsafe {
+ /// // Deferred initialization:
+ /// values[0].as_mut_ptr().write(1);
+ /// values[1].as_mut_ptr().write(2);
+ /// values[2].as_mut_ptr().write(3);
+ ///
+ /// values.assume_init()
+ /// };
+ ///
+ /// assert_eq!(*values, [1, 2, 3])
+ /// ```
+ #[unstable(feature = "new_uninit", issue = "63291")]
+ #[inline]
+ pub unsafe fn assume_init(self) -> Box<[T]> {
+ Box(Unique::new_unchecked(Box::into_raw(self) as _))
+ }
+}
+
impl<T: ?Sized> Box<T> {
/// Constructs a box from a raw pointer.
///
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 0c406a9..2b222ca 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -327,6 +327,37 @@
}))
}
+ /// Constructs a new `Rc` with uninitialized contents.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(new_uninit)]
+ /// #![feature(get_mut_unchecked)]
+ ///
+ /// use std::rc::Rc;
+ ///
+ /// let mut five = Rc::<u32>::new_uninit();
+ ///
+ /// let five = unsafe {
+ /// // Deferred initialization:
+ /// Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
+ ///
+ /// five.assume_init()
+ /// };
+ ///
+ /// assert_eq!(*five, 5)
+ /// ```
+ #[unstable(feature = "new_uninit", issue = "63291")]
+ pub fn new_uninit() -> Rc<mem::MaybeUninit<T>> {
+ unsafe {
+ Rc::from_ptr(Rc::allocate_for_layout(
+ Layout::new::<T>(),
+ |mem| mem as *mut RcBox<mem::MaybeUninit<T>>,
+ ))
+ }
+ }
+
/// Constructs a new `Pin<Rc<T>>`. If `T` does not implement `Unpin`, then
/// `value` will be pinned in memory and unable to be moved.
#[stable(feature = "pin", since = "1.33.0")]
@@ -377,6 +408,118 @@
}
}
+impl<T> Rc<[T]> {
+ /// Constructs a new reference-counted slice with uninitialized contents.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(new_uninit)]
+ /// #![feature(get_mut_unchecked)]
+ ///
+ /// use std::rc::Rc;
+ ///
+ /// let mut values = Rc::<[u32]>::new_uninit_slice(3);
+ ///
+ /// let values = unsafe {
+ /// // Deferred initialization:
+ /// Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
+ /// Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
+ /// Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
+ ///
+ /// values.assume_init()
+ /// };
+ ///
+ /// assert_eq!(*values, [1, 2, 3])
+ /// ```
+ #[unstable(feature = "new_uninit", issue = "63291")]
+ pub fn new_uninit_slice(len: usize) -> Rc<[mem::MaybeUninit<T>]> {
+ unsafe {
+ Rc::from_ptr(Rc::allocate_for_slice(len))
+ }
+ }
+}
+
+impl<T> Rc<mem::MaybeUninit<T>> {
+ /// Converts to `Rc<T>`.
+ ///
+ /// # Safety
+ ///
+ /// As with [`MaybeUninit::assume_init`],
+ /// it is up to the caller to guarantee that the value
+ /// really is in an initialized state.
+ /// Calling this when the content is not yet fully initialized
+ /// causes immediate undefined behavior.
+ ///
+ /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(new_uninit)]
+ /// #![feature(get_mut_unchecked)]
+ ///
+ /// use std::rc::Rc;
+ ///
+ /// let mut five = Rc::<u32>::new_uninit();
+ ///
+ /// let five = unsafe {
+ /// // Deferred initialization:
+ /// Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
+ ///
+ /// five.assume_init()
+ /// };
+ ///
+ /// assert_eq!(*five, 5)
+ /// ```
+ #[unstable(feature = "new_uninit", issue = "63291")]
+ #[inline]
+ pub unsafe fn assume_init(self) -> Rc<T> {
+ Rc::from_inner(mem::ManuallyDrop::new(self).ptr.cast())
+ }
+}
+
+impl<T> Rc<[mem::MaybeUninit<T>]> {
+ /// Converts to `Rc<[T]>`.
+ ///
+ /// # Safety
+ ///
+ /// As with [`MaybeUninit::assume_init`],
+ /// it is up to the caller to guarantee that the value
+ /// really is in an initialized state.
+ /// Calling this when the content is not yet fully initialized
+ /// causes immediate undefined behavior.
+ ///
+ /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(new_uninit)]
+ /// #![feature(get_mut_unchecked)]
+ ///
+ /// use std::rc::Rc;
+ ///
+ /// let mut values = Rc::<[u32]>::new_uninit_slice(3);
+ ///
+ /// let values = unsafe {
+ /// // Deferred initialization:
+ /// Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
+ /// Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
+ /// Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
+ ///
+ /// values.assume_init()
+ /// };
+ ///
+ /// assert_eq!(*values, [1, 2, 3])
+ /// ```
+ #[unstable(feature = "new_uninit", issue = "63291")]
+ #[inline]
+ pub unsafe fn assume_init(self) -> Rc<[T]> {
+ Rc::from_ptr(mem::ManuallyDrop::new(self).ptr.as_ptr() as _)
+ }
+}
+
impl<T: ?Sized> Rc<T> {
/// Consumes the `Rc`, returning the wrapped pointer.
///
@@ -560,13 +703,46 @@
pub fn get_mut(this: &mut Self) -> Option<&mut T> {
if Rc::is_unique(this) {
unsafe {
- Some(&mut this.ptr.as_mut().value)
+ Some(Rc::get_mut_unchecked(this))
}
} else {
None
}
}
+ /// Returns a mutable reference to the inner value,
+ /// without any check.
+ ///
+ /// See also [`get_mut`], which is safe and does appropriate checks.
+ ///
+ /// [`get_mut`]: struct.Rc.html#method.get_mut
+ ///
+ /// # Safety
+ ///
+ /// Any other `Rc` or [`Weak`] pointers to the same value must not be dereferenced
+ /// for the duration of the returned borrow.
+ /// This is trivially the case if no such pointers exist,
+ /// for example immediately after `Rc::new`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(get_mut_unchecked)]
+ ///
+ /// use std::rc::Rc;
+ ///
+ /// let mut x = Rc::new(String::new());
+ /// unsafe {
+ /// Rc::get_mut_unchecked(&mut x).push_str("foo")
+ /// }
+ /// assert_eq!(*x, "foo");
+ /// ```
+ #[inline]
+ #[unstable(feature = "get_mut_unchecked", issue = "63292")]
+ pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
+ &mut this.ptr.as_mut().value
+ }
+
#[inline]
#[stable(feature = "ptr_eq", since = "1.17.0")]
/// Returns `true` if the two `Rc`s point to the same value (not
@@ -704,11 +880,11 @@
impl<T: ?Sized> Rc<T> {
/// Allocates an `RcBox<T>` with sufficient space for
- /// an unsized value where the value has the layout provided.
+ /// a possibly-unsized value where the value has the layout provided.
///
/// The function `mem_to_rcbox` is called with the data pointer
/// and must return back a (potentially fat)-pointer for the `RcBox<T>`.
- unsafe fn allocate_for_unsized(
+ unsafe fn allocate_for_layout(
value_layout: Layout,
mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcBox<T>
) -> *mut RcBox<T> {
@@ -737,7 +913,7 @@
/// Allocates an `RcBox<T>` with sufficient space for an unsized value
unsafe fn allocate_for_ptr(ptr: *const T) -> *mut RcBox<T> {
// Allocate for the `RcBox<T>` using the given value.
- Self::allocate_for_unsized(
+ Self::allocate_for_layout(
Layout::for_value(&*ptr),
|mem| set_data_ptr(ptr as *mut T, mem) as *mut RcBox<T>,
)
@@ -768,7 +944,7 @@
impl<T> Rc<[T]> {
/// Allocates an `RcBox<[T]>` with the given length.
unsafe fn allocate_for_slice(len: usize) -> *mut RcBox<[T]> {
- Self::allocate_for_unsized(
+ Self::allocate_for_layout(
Layout::array::<T>(len).unwrap(),
|mem| ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut RcBox<[T]>,
)
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 7d3b265..3411721 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -311,6 +311,37 @@
Self::from_inner(Box::into_raw_non_null(x))
}
+ /// Constructs a new `Arc` with uninitialized contents.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(new_uninit)]
+ /// #![feature(get_mut_unchecked)]
+ ///
+ /// use std::sync::Arc;
+ ///
+ /// let mut five = Arc::<u32>::new_uninit();
+ ///
+ /// let five = unsafe {
+ /// // Deferred initialization:
+ /// Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
+ ///
+ /// five.assume_init()
+ /// };
+ ///
+ /// assert_eq!(*five, 5)
+ /// ```
+ #[unstable(feature = "new_uninit", issue = "63291")]
+ pub fn new_uninit() -> Arc<mem::MaybeUninit<T>> {
+ unsafe {
+ Arc::from_ptr(Arc::allocate_for_layout(
+ Layout::new::<T>(),
+ |mem| mem as *mut ArcInner<mem::MaybeUninit<T>>,
+ ))
+ }
+ }
+
/// Constructs a new `Pin<Arc<T>>`. If `T` does not implement `Unpin`, then
/// `data` will be pinned in memory and unable to be moved.
#[stable(feature = "pin", since = "1.33.0")]
@@ -361,6 +392,118 @@
}
}
+impl<T> Arc<[T]> {
+ /// Constructs a new reference-counted slice with uninitialized contents.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(new_uninit)]
+ /// #![feature(get_mut_unchecked)]
+ ///
+ /// use std::sync::Arc;
+ ///
+ /// let mut values = Arc::<[u32]>::new_uninit_slice(3);
+ ///
+ /// let values = unsafe {
+ /// // Deferred initialization:
+ /// Arc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
+ /// Arc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
+ /// Arc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
+ ///
+ /// values.assume_init()
+ /// };
+ ///
+ /// assert_eq!(*values, [1, 2, 3])
+ /// ```
+ #[unstable(feature = "new_uninit", issue = "63291")]
+ pub fn new_uninit_slice(len: usize) -> Arc<[mem::MaybeUninit<T>]> {
+ unsafe {
+ Arc::from_ptr(Arc::allocate_for_slice(len))
+ }
+ }
+}
+
+impl<T> Arc<mem::MaybeUninit<T>> {
+ /// Converts to `Arc<T>`.
+ ///
+ /// # Safety
+ ///
+ /// As with [`MaybeUninit::assume_init`],
+ /// it is up to the caller to guarantee that the value
+ /// really is in an initialized state.
+ /// Calling this when the content is not yet fully initialized
+ /// causes immediate undefined behavior.
+ ///
+ /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(new_uninit)]
+ /// #![feature(get_mut_unchecked)]
+ ///
+ /// use std::sync::Arc;
+ ///
+ /// let mut five = Arc::<u32>::new_uninit();
+ ///
+ /// let five = unsafe {
+ /// // Deferred initialization:
+ /// Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
+ ///
+ /// five.assume_init()
+ /// };
+ ///
+ /// assert_eq!(*five, 5)
+ /// ```
+ #[unstable(feature = "new_uninit", issue = "63291")]
+ #[inline]
+ pub unsafe fn assume_init(self) -> Arc<T> {
+ Arc::from_inner(mem::ManuallyDrop::new(self).ptr.cast())
+ }
+}
+
+impl<T> Arc<[mem::MaybeUninit<T>]> {
+ /// Converts to `Arc<[T]>`.
+ ///
+ /// # Safety
+ ///
+ /// As with [`MaybeUninit::assume_init`],
+ /// it is up to the caller to guarantee that the value
+ /// really is in an initialized state.
+ /// Calling this when the content is not yet fully initialized
+ /// causes immediate undefined behavior.
+ ///
+ /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(new_uninit)]
+ /// #![feature(get_mut_unchecked)]
+ ///
+ /// use std::sync::Arc;
+ ///
+ /// let mut values = Arc::<[u32]>::new_uninit_slice(3);
+ ///
+ /// let values = unsafe {
+ /// // Deferred initialization:
+ /// Arc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
+ /// Arc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
+ /// Arc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
+ ///
+ /// values.assume_init()
+ /// };
+ ///
+ /// assert_eq!(*values, [1, 2, 3])
+ /// ```
+ #[unstable(feature = "new_uninit", issue = "63291")]
+ #[inline]
+ pub unsafe fn assume_init(self) -> Arc<[T]> {
+ Arc::from_ptr(mem::ManuallyDrop::new(self).ptr.as_ptr() as _)
+ }
+}
+
impl<T: ?Sized> Arc<T> {
/// Consumes the `Arc`, returning the wrapped pointer.
///
@@ -593,11 +736,11 @@
impl<T: ?Sized> Arc<T> {
/// Allocates an `ArcInner<T>` with sufficient space for
- /// an unsized value where the value has the layout provided.
+ /// a possibly-unsized value where the value has the layout provided.
///
/// The function `mem_to_arcinner` is called with the data pointer
/// and must return back a (potentially fat)-pointer for the `ArcInner<T>`.
- unsafe fn allocate_for_unsized(
+ unsafe fn allocate_for_layout(
value_layout: Layout,
mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner<T>
) -> *mut ArcInner<T> {
@@ -625,7 +768,7 @@
/// Allocates an `ArcInner<T>` with sufficient space for an unsized value.
unsafe fn allocate_for_ptr(ptr: *const T) -> *mut ArcInner<T> {
// Allocate for the `ArcInner<T>` using the given value.
- Self::allocate_for_unsized(
+ Self::allocate_for_layout(
Layout::for_value(&*ptr),
|mem| set_data_ptr(ptr as *mut T, mem) as *mut ArcInner<T>,
)
@@ -656,7 +799,7 @@
impl<T> Arc<[T]> {
/// Allocates an `ArcInner<[T]>` with the given length.
unsafe fn allocate_for_slice(len: usize) -> *mut ArcInner<[T]> {
- Self::allocate_for_unsized(
+ Self::allocate_for_layout(
Layout::array::<T>(len).unwrap(),
|mem| ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut ArcInner<[T]>,
)
@@ -945,13 +1088,46 @@
// the Arc itself to be `mut`, so we're returning the only possible
// reference to the inner data.
unsafe {
- Some(&mut this.ptr.as_mut().data)
+ Some(Arc::get_mut_unchecked(this))
}
} else {
None
}
}
+ /// Returns a mutable reference to the inner value,
+ /// without any check.
+ ///
+ /// See also [`get_mut`], which is safe and does appropriate checks.
+ ///
+ /// [`get_mut`]: struct.Arc.html#method.get_mut
+ ///
+ /// # Safety
+ ///
+ /// Any other `Arc` or [`Weak`] pointers to the same value must not be dereferenced
+ /// for the duration of the returned borrow.
+ /// This is trivially the case if no such pointers exist,
+ /// for example immediately after `Arc::new`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(get_mut_unchecked)]
+ ///
+ /// use std::sync::Arc;
+ ///
+ /// let mut x = Arc::new(String::new());
+ /// unsafe {
+ /// Arc::get_mut_unchecked(&mut x).push_str("foo")
+ /// }
+ /// assert_eq!(*x, "foo");
+ /// ```
+ #[inline]
+ #[unstable(feature = "get_mut_unchecked", issue = "63292")]
+ pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
+ &mut this.ptr.as_mut().data
+ }
+
/// Determine whether this is the unique reference (including weak refs) to
/// the underlying data.
///
diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs
index ec22a7c..ec70d39 100644
--- a/src/libcore/clone.rs
+++ b/src/libcore/clone.rs
@@ -135,7 +135,7 @@
/// Derive macro generating an impl of the trait `Clone`.
#[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics, derive_clone_copy)]
pub macro Clone($item:item) { /* compiler built-in */ }
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index b802216..cb9feb0 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -202,7 +202,7 @@
/// Derive macro generating an impl of the trait `PartialEq`.
#[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics)]
pub macro PartialEq($item:item) { /* compiler built-in */ }
@@ -265,7 +265,7 @@
/// Derive macro generating an impl of the trait `Eq`.
#[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics, derive_eq)]
pub macro Eq($item:item) { /* compiler built-in */ }
@@ -616,7 +616,7 @@
/// Derive macro generating an impl of the trait `Ord`.
#[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics)]
pub macro Ord($item:item) { /* compiler built-in */ }
@@ -865,7 +865,7 @@
/// Derive macro generating an impl of the trait `PartialOrd`.
#[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics)]
pub macro PartialOrd($item:item) { /* compiler built-in */ }
diff --git a/src/libcore/default.rs b/src/libcore/default.rs
index 9b1616c..66acc51 100644
--- a/src/libcore/default.rs
+++ b/src/libcore/default.rs
@@ -117,7 +117,7 @@
/// Derive macro generating an impl of the trait `Default`.
#[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics)]
pub macro Default($item:item) { /* compiler built-in */ }
diff --git a/src/libcore/fmt/builders.rs b/src/libcore/fmt/builders.rs
index cb4e326..15ce227 100644
--- a/src/libcore/fmt/builders.rs
+++ b/src/libcore/fmt/builders.rs
@@ -98,7 +98,7 @@
has_fields: bool,
}
-pub fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>,
+pub(super) fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>,
name: &str)
-> DebugStruct<'a, 'b> {
let result = fmt.write_str(name);
@@ -251,7 +251,10 @@
empty_name: bool,
}
-pub fn debug_tuple_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugTuple<'a, 'b> {
+pub(super) fn debug_tuple_new<'a, 'b>(
+ fmt: &'a mut fmt::Formatter<'b>,
+ name: &str,
+) -> DebugTuple<'a, 'b> {
let result = fmt.write_str(name);
DebugTuple {
fmt,
@@ -418,7 +421,7 @@
inner: DebugInner<'a, 'b>,
}
-pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
+pub(super) fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
let result = fmt.write_str("{");
DebugSet {
inner: DebugInner {
@@ -555,7 +558,7 @@
inner: DebugInner<'a, 'b>,
}
-pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
+pub(super) fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
let result = fmt.write_str("[");
DebugList {
inner: DebugInner {
@@ -697,7 +700,7 @@
state: PadAdapterState,
}
-pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
+pub(super) fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
let result = fmt.write_str("{");
DebugMap {
fmt,
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index d5fae9e..bd31d25 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -549,7 +549,7 @@
pub(crate) mod macros {
/// Derive macro generating an impl of the trait `Debug`.
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
+ #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics)]
pub macro Debug($item:item) { /* compiler built-in */ }
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index b397119..bf3daa3 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -202,7 +202,7 @@
pub(crate) mod macros {
/// Derive macro generating an impl of the trait `Hash`.
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
+ #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics)]
pub macro Hash($item:item) { /* compiler built-in */ }
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index ceaa870..d145f22 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -1293,18 +1293,40 @@
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `wrapping_add` method. For example,
/// [`std::u32::wrapping_add`](../../std/primitive.u32.html#method.wrapping_add)
+ #[cfg(boostrap_stdarch_ignore_this)]
pub fn overflowing_add<T>(a: T, b: T) -> T;
/// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `wrapping_sub` method. For example,
/// [`std::u32::wrapping_sub`](../../std/primitive.u32.html#method.wrapping_sub)
+ #[cfg(boostrap_stdarch_ignore_this)]
pub fn overflowing_sub<T>(a: T, b: T) -> T;
/// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `wrapping_mul` method. For example,
/// [`std::u32::wrapping_mul`](../../std/primitive.u32.html#method.wrapping_mul)
+ #[cfg(boostrap_stdarch_ignore_this)]
pub fn overflowing_mul<T>(a: T, b: T) -> T;
+ /// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
+ /// The stabilized versions of this intrinsic are available on the integer
+ /// primitives via the `wrapping_add` method. For example,
+ /// [`std::u32::wrapping_add`](../../std/primitive.u32.html#method.wrapping_add)
+ #[cfg(not(boostrap_stdarch_ignore_this))]
+ pub fn wrapping_add<T>(a: T, b: T) -> T;
+ /// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
+ /// The stabilized versions of this intrinsic are available on the integer
+ /// primitives via the `wrapping_sub` method. For example,
+ /// [`std::u32::wrapping_sub`](../../std/primitive.u32.html#method.wrapping_sub)
+ #[cfg(not(boostrap_stdarch_ignore_this))]
+ pub fn wrapping_sub<T>(a: T, b: T) -> T;
+ /// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
+ /// The stabilized versions of this intrinsic are available on the integer
+ /// primitives via the `wrapping_mul` method. For example,
+ /// [`std::u32::wrapping_mul`](../../std/primitive.u32.html#method.wrapping_mul)
+ #[cfg(not(boostrap_stdarch_ignore_this))]
+ pub fn wrapping_mul<T>(a: T, b: T) -> T;
+
/// Computes `a + b`, while saturating at numeric bounds.
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `saturating_add` method. For example,
diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs
index 58e0a70..a63434a 100644
--- a/src/libcore/iter/adapters/mod.rs
+++ b/src/libcore/iter/adapters/mod.rs
@@ -405,6 +405,36 @@
_ => (usize::MAX, None)
}
}
+
+ #[inline]
+ fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
+ where
+ F: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ // fully iterate the current iterator. this is necessary because
+ // `self.iter` may be empty even when `self.orig` isn't
+ acc = self.iter.try_fold(acc, &mut f)?;
+ self.iter = self.orig.clone();
+
+ // complete a full cycle, keeping track of whether the cycled
+ // iterator is empty or not. we need to return early in case
+ // of an empty iterator to prevent an infinite loop
+ let mut is_empty = true;
+ acc = self.iter.try_fold(acc, |acc, x| {
+ is_empty = false;
+ f(acc, x)
+ })?;
+
+ if is_empty {
+ return Try::from_ok(acc);
+ }
+
+ loop {
+ self.iter = self.orig.clone();
+ acc = self.iter.try_fold(acc, &mut f)?;
+ }
+ }
}
#[stable(feature = "fused", since = "1.26.0")]
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index e114f3a..6c88a76 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -1263,14 +1263,14 @@
/// Unstable implementation detail of the `rustc` compiler, do not use.
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
+ #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable(core_intrinsics, libstd_sys_internals)]
pub macro RustcDecodable($item:item) { /* compiler built-in */ }
/// Unstable implementation detail of the `rustc` compiler, do not use.
#[rustc_builtin_macro]
- #[rustc_macro_transparency = "semitransparent"]
+ #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable(core_intrinsics)]
pub macro RustcEncodable($item:item) { /* compiler built-in */ }
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 3befd42..89af252 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -290,7 +290,7 @@
/// Derive macro generating an impl of the trait `Copy`.
#[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics, derive_clone_copy)]
pub macro Copy($item:item) { /* compiler built-in */ }
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 67e30e7..b46e06f 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -1112,7 +1112,13 @@
without modifying the original"]
#[inline]
pub const fn wrapping_add(self, rhs: Self) -> Self {
- intrinsics::overflowing_add(self, rhs)
+ #[cfg(boostrap_stdarch_ignore_this)] {
+ intrinsics::overflowing_add(self, rhs)
+ }
+
+ #[cfg(not(boostrap_stdarch_ignore_this))] {
+ intrinsics::wrapping_add(self, rhs)
+ }
}
}
@@ -1135,7 +1141,13 @@
without modifying the original"]
#[inline]
pub const fn wrapping_sub(self, rhs: Self) -> Self {
- intrinsics::overflowing_sub(self, rhs)
+ #[cfg(boostrap_stdarch_ignore_this)] {
+ intrinsics::overflowing_sub(self, rhs)
+ }
+
+ #[cfg(not(boostrap_stdarch_ignore_this))] {
+ intrinsics::wrapping_sub(self, rhs)
+ }
}
}
@@ -1157,7 +1169,13 @@
without modifying the original"]
#[inline]
pub const fn wrapping_mul(self, rhs: Self) -> Self {
- intrinsics::overflowing_mul(self, rhs)
+ #[cfg(boostrap_stdarch_ignore_this)] {
+ intrinsics::overflowing_mul(self, rhs)
+ }
+
+ #[cfg(not(boostrap_stdarch_ignore_this))] {
+ intrinsics::wrapping_mul(self, rhs)
+ }
}
}
@@ -3031,7 +3049,13 @@
without modifying the original"]
#[inline]
pub const fn wrapping_add(self, rhs: Self) -> Self {
- intrinsics::overflowing_add(self, rhs)
+ #[cfg(boostrap_stdarch_ignore_this)] {
+ intrinsics::overflowing_add(self, rhs)
+ }
+
+ #[cfg(not(boostrap_stdarch_ignore_this))] {
+ intrinsics::wrapping_add(self, rhs)
+ }
}
}
@@ -3053,7 +3077,13 @@
without modifying the original"]
#[inline]
pub const fn wrapping_sub(self, rhs: Self) -> Self {
- intrinsics::overflowing_sub(self, rhs)
+ #[cfg(boostrap_stdarch_ignore_this)] {
+ intrinsics::overflowing_sub(self, rhs)
+ }
+
+ #[cfg(not(boostrap_stdarch_ignore_this))] {
+ intrinsics::wrapping_sub(self, rhs)
+ }
}
}
@@ -3076,7 +3106,13 @@
without modifying the original"]
#[inline]
pub const fn wrapping_mul(self, rhs: Self) -> Self {
- intrinsics::overflowing_mul(self, rhs)
+ #[cfg(boostrap_stdarch_ignore_this)] {
+ intrinsics::overflowing_mul(self, rhs)
+ }
+
+ #[cfg(not(boostrap_stdarch_ignore_this))] {
+ intrinsics::wrapping_mul(self, rhs)
+ }
}
doc_comment! {
diff --git a/src/libcore/ptr/unique.rs b/src/libcore/ptr/unique.rs
index f0d011f..3521dd7 100644
--- a/src/libcore/ptr/unique.rs
+++ b/src/libcore/ptr/unique.rs
@@ -122,6 +122,14 @@
pub unsafe fn as_mut(&mut self) -> &mut T {
&mut *self.as_ptr()
}
+
+ /// Casts to a pointer of another type.
+ #[inline]
+ pub const fn cast<U>(self) -> Unique<U> {
+ unsafe {
+ Unique::new_unchecked(self.as_ptr() as *mut U)
+ }
+ }
}
#[unstable(feature = "ptr_internals", issue = "0")]
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index bff7813..a1a27e1 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -1152,6 +1152,18 @@
assert_eq!(empty::<i32>().cycle().fold(0, |acc, x| acc + x), 0);
assert_eq!(once(1).cycle().skip(1).take(4).fold(0, |acc, x| acc + x), 4);
+
+ assert_eq!((0..10).cycle().take(5).sum::<i32>(), 10);
+ assert_eq!((0..10).cycle().take(15).sum::<i32>(), 55);
+ assert_eq!((0..10).cycle().take(25).sum::<i32>(), 100);
+
+ let mut iter = (0..10).cycle();
+ iter.nth(14);
+ assert_eq!(iter.take(8).sum::<i32>(), 38);
+
+ let mut iter = (0..10).cycle();
+ iter.nth(9);
+ assert_eq!(iter.take(3).sum::<i32>(), 3);
}
#[test]
diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs
index 4ba61e9..ff0c44a 100644
--- a/src/librustc/hir/lowering/expr.rs
+++ b/src/librustc/hir/lowering/expr.rs
@@ -984,7 +984,6 @@
volatile: asm.volatile,
alignstack: asm.alignstack,
dialect: asm.dialect,
- ctxt: asm.ctxt,
};
let outputs = asm.outputs
diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs
index 51a0c41..4f9a9ed 100644
--- a/src/librustc/hir/lowering/item.rs
+++ b/src/librustc/hir/lowering/item.rs
@@ -750,10 +750,7 @@
}
fn lower_global_asm(&mut self, ga: &GlobalAsm) -> P<hir::GlobalAsm> {
- P(hir::GlobalAsm {
- asm: ga.asm,
- ctxt: ga.ctxt,
- })
+ P(hir::GlobalAsm { asm: ga.asm })
}
fn lower_variant(&mut self, v: &Variant) -> hir::Variant {
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 57fd0be..e5ada1f 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -23,7 +23,6 @@
use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect};
use syntax::ast::{Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy};
use syntax::attr::{InlineAttr, OptimizeAttr};
-use syntax::ext::hygiene::SyntaxContext;
use syntax::symbol::{Symbol, kw};
use syntax::tokenstream::TokenStream;
use syntax::util::parser::ExprPrecedence;
@@ -2004,8 +2003,6 @@
pub volatile: bool,
pub alignstack: bool,
pub dialect: AsmDialect,
- #[stable_hasher(ignore)] // This is used for error reporting
- pub ctxt: SyntaxContext,
}
/// Represents an argument in a function header.
@@ -2184,8 +2181,6 @@
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct GlobalAsm {
pub asm: Symbol,
- #[stable_hasher(ignore)] // This is used for error reporting
- pub ctxt: SyntaxContext,
}
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 3536b2a..8e3b910 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -395,7 +395,7 @@
output_types: OutputTypes [TRACKED],
search_paths: Vec<SearchPath> [UNTRACKED],
libs: Vec<(String, Option<String>, Option<cstore::NativeLibraryKind>)> [TRACKED],
- maybe_sysroot: Option<PathBuf> [TRACKED],
+ maybe_sysroot: Option<PathBuf> [UNTRACKED],
target_triple: TargetTriple [TRACKED],
diff --git a/src/librustc_codegen_llvm/asm.rs b/src/librustc_codegen_llvm/asm.rs
index 9763d52..b68ee2c 100644
--- a/src/librustc_codegen_llvm/asm.rs
+++ b/src/librustc_codegen_llvm/asm.rs
@@ -6,9 +6,9 @@
use rustc::hir;
use rustc_codegen_ssa::traits::*;
-
use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::mir::operand::OperandValue;
+use syntax_pos::Span;
use std::ffi::{CStr, CString};
use libc::{c_uint, c_char};
@@ -19,7 +19,8 @@
&mut self,
ia: &hir::InlineAsm,
outputs: Vec<PlaceRef<'tcx, &'ll Value>>,
- mut inputs: Vec<&'ll Value>
+ mut inputs: Vec<&'ll Value>,
+ span: Span,
) -> bool {
let mut ext_constraints = vec![];
let mut output_types = vec![];
@@ -102,7 +103,7 @@
let kind = llvm::LLVMGetMDKindIDInContext(self.llcx,
key.as_ptr() as *const c_char, key.len() as c_uint);
- let val: &'ll Value = self.const_i32(ia.ctxt.outer_expn().as_u32() as i32);
+ let val: &'ll Value = self.const_i32(span.ctxt().outer_expn().as_u32() as i32);
llvm::LLVMSetMetadata(r, kind,
llvm::LLVMMDNodeInContext(self.llcx, &val, 1));
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index a9b8962..9483ffc 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -328,7 +328,7 @@
},
"ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "ctpop" | "bswap" |
"bitreverse" | "add_with_overflow" | "sub_with_overflow" |
- "mul_with_overflow" | "overflowing_add" | "overflowing_sub" | "overflowing_mul" |
+ "mul_with_overflow" | "wrapping_add" | "wrapping_sub" | "wrapping_mul" |
"unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" |
"unchecked_add" | "unchecked_sub" | "unchecked_mul" | "exact_div" |
"rotate_left" | "rotate_right" | "saturating_add" | "saturating_sub" => {
@@ -398,9 +398,9 @@
return;
},
- "overflowing_add" => self.add(args[0].immediate(), args[1].immediate()),
- "overflowing_sub" => self.sub(args[0].immediate(), args[1].immediate()),
- "overflowing_mul" => self.mul(args[0].immediate(), args[1].immediate()),
+ "wrapping_add" => self.add(args[0].immediate(), args[1].immediate()),
+ "wrapping_sub" => self.sub(args[0].immediate(), args[1].immediate()),
+ "wrapping_mul" => self.mul(args[0].immediate(), args[1].immediate()),
"exact_div" =>
if signed {
self.exactsdiv(args[0].immediate(), args[1].immediate())
diff --git a/src/librustc_codegen_ssa/mir/statement.rs b/src/librustc_codegen_ssa/mir/statement.rs
index 3717be4..3617f3a 100644
--- a/src/librustc_codegen_ssa/mir/statement.rs
+++ b/src/librustc_codegen_ssa/mir/statement.rs
@@ -89,7 +89,12 @@
});
if input_vals.len() == asm.inputs.len() {
- let res = bx.codegen_inline_asm(&asm.asm, outputs, input_vals);
+ let res = bx.codegen_inline_asm(
+ &asm.asm,
+ outputs,
+ input_vals,
+ statement.source_info.span,
+ );
if !res {
span_err!(bx.sess(), statement.source_info.span, E0668,
"malformed inline assembly");
diff --git a/src/librustc_codegen_ssa/traits/asm.rs b/src/librustc_codegen_ssa/traits/asm.rs
index fd3c868..c9e1ed8 100644
--- a/src/librustc_codegen_ssa/traits/asm.rs
+++ b/src/librustc_codegen_ssa/traits/asm.rs
@@ -1,6 +1,7 @@
use super::BackendTypes;
use crate::mir::place::PlaceRef;
use rustc::hir::{GlobalAsm, InlineAsm};
+use syntax_pos::Span;
pub trait AsmBuilderMethods<'tcx>: BackendTypes {
/// Take an inline assembly expression and splat it out via LLVM
@@ -9,6 +10,7 @@
ia: &InlineAsm,
outputs: Vec<PlaceRef<'tcx, Self::Value>>,
inputs: Vec<Self::Value>,
+ span: Span,
) -> bool;
}
diff --git a/src/librustc_codegen_utils/Cargo.toml b/src/librustc_codegen_utils/Cargo.toml
index d93589e..89b50c5 100644
--- a/src/librustc_codegen_utils/Cargo.toml
+++ b/src/librustc_codegen_utils/Cargo.toml
@@ -13,7 +13,7 @@
flate2 = "1.0"
log = "0.4"
punycode = "0.4.0"
-rustc-demangle = "0.1.15"
+rustc-demangle = "0.1.16"
syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/librustc_codegen_utils/symbol_names/v0.rs b/src/librustc_codegen_utils/symbol_names/v0.rs
index 47601da..8d6a1d7 100644
--- a/src/librustc_codegen_utils/symbol_names/v0.rs
+++ b/src/librustc_codegen_utils/symbol_names/v0.rs
@@ -198,10 +198,14 @@
let lifetimes = regions.into_iter().map(|br| {
match br {
- ty::BrAnon(i) => i + 1,
+ ty::BrAnon(i) => {
+ // FIXME(eddyb) for some reason, `anonymize_late_bound_regions` starts at `1`.
+ assert_ne!(i, 0);
+ i - 1
+ },
_ => bug!("symbol_names: non-anonymized region `{:?}` in `{:?}`", br, value),
}
- }).max().unwrap_or(0);
+ }).max().map_or(0, |max| max + 1);
self.push_opt_integer_62("G", lifetimes as u64);
lifetime_depths.end += lifetimes;
@@ -297,6 +301,10 @@
// Late-bound lifetimes use indices starting at 1,
// see `BinderLevel` for more details.
ty::ReLateBound(debruijn, ty::BrAnon(i)) => {
+ // FIXME(eddyb) for some reason, `anonymize_late_bound_regions` starts at `1`.
+ assert_ne!(i, 0);
+ let i = i - 1;
+
let binder = &self.binders[self.binders.len() - 1 - debruijn.index()];
let depth = binder.lifetime_depths.start + i;
diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs
index 8391822..40ddd65 100644
--- a/src/librustc_llvm/build.rs
+++ b/src/librustc_llvm/build.rs
@@ -151,6 +151,10 @@
cfg.define("LLVM_RUSTLLVM", None);
}
+ if env::var_os("LLVM_NDEBUG").is_some() {
+ cfg.define("NDEBUG", None);
+ }
+
build_helper::rerun_if_changed_anything_in_dir(Path::new("../rustllvm"));
cfg.file("../rustllvm/PassWrapper.cpp")
.file("../rustllvm/RustWrapper.cpp")
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 0bec31d..772b2d3 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -348,6 +348,14 @@
}
}
+impl SpecializedDecoder<Ident> for DecodeContext<'_, '_> {
+ fn specialized_decode(&mut self) -> Result<Ident, Self::Error> {
+ // FIXME(jseyfried): intercrate hygiene
+
+ Ok(Ident::with_dummy_span(Symbol::decode(self)?))
+ }
+}
+
impl<'a, 'tcx> SpecializedDecoder<Fingerprint> for DecodeContext<'a, 'tcx> {
fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
Fingerprint::decode_opaque(&mut self.opaque)
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index fb675d7..e2de055 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -31,7 +31,7 @@
use syntax::ast;
use syntax::attr;
use syntax::source_map::Spanned;
-use syntax::symbol::{kw, sym};
+use syntax::symbol::{kw, sym, Ident};
use syntax_pos::{self, FileName, SourceFile, Span};
use log::{debug, trace};
@@ -173,6 +173,13 @@
}
}
+impl SpecializedEncoder<Ident> for EncodeContext<'tcx> {
+ fn specialized_encode(&mut self, ident: &Ident) -> Result<(), Self::Error> {
+ // FIXME(jseyfried): intercrate hygiene
+ ident.name.encode(self)
+ }
+}
+
impl<'tcx> SpecializedEncoder<LocalDefId> for EncodeContext<'tcx> {
#[inline]
fn specialized_encode(&mut self, def_id: &LocalDefId) -> Result<(), Self::Error> {
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index 89c5be1..ee105fe 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -110,18 +110,18 @@
};
self.write_scalar(out_val, dest)?;
}
- | "overflowing_add"
- | "overflowing_sub"
- | "overflowing_mul"
+ | "wrapping_add"
+ | "wrapping_sub"
+ | "wrapping_mul"
| "add_with_overflow"
| "sub_with_overflow"
| "mul_with_overflow" => {
let lhs = self.read_immediate(args[0])?;
let rhs = self.read_immediate(args[1])?;
let (bin_op, ignore_overflow) = match intrinsic_name {
- "overflowing_add" => (BinOp::Add, true),
- "overflowing_sub" => (BinOp::Sub, true),
- "overflowing_mul" => (BinOp::Mul, true),
+ "wrapping_add" => (BinOp::Add, true),
+ "wrapping_sub" => (BinOp::Sub, true),
+ "wrapping_mul" => (BinOp::Mul, true),
"add_with_overflow" => (BinOp::Add, false),
"sub_with_overflow" => (BinOp::Sub, false),
"mul_with_overflow" => (BinOp::Mul, false),
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 0eed43b..649cccc 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -537,9 +537,9 @@
| "cttz_nonzero"
| "ctlz"
| "ctlz_nonzero"
- | "overflowing_add"
- | "overflowing_sub"
- | "overflowing_mul"
+ | "wrapping_add"
+ | "wrapping_sub"
+ | "wrapping_mul"
| "unchecked_shl"
| "unchecked_shr"
| "rotate_left"
diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs
index b84bc31..334d0ce 100644
--- a/src/librustc_mir/transform/qualify_min_const_fn.rs
+++ b/src/librustc_mir/transform/qualify_min_const_fn.rs
@@ -379,9 +379,9 @@
| "add_with_overflow" // ~> .overflowing_add
| "sub_with_overflow" // ~> .overflowing_sub
| "mul_with_overflow" // ~> .overflowing_mul
- | "overflowing_add" // ~> .wrapping_add
- | "overflowing_sub" // ~> .wrapping_sub
- | "overflowing_mul" // ~> .wrapping_mul
+ | "wrapping_add" // ~> .wrapping_add
+ | "wrapping_sub" // ~> .wrapping_sub
+ | "wrapping_mul" // ~> .wrapping_mul
| "saturating_add" // ~> .saturating_add
| "saturating_sub" // ~> .saturating_sub
| "unchecked_shl" // ~> .wrapping_shl
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 539e4a3..1510d74 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -16,6 +16,7 @@
use rustc::bug;
use rustc::hir::def::{self, *};
use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
+use rustc::hir::map::DefCollector;
use rustc::ty;
use rustc::middle::cstore::CrateStore;
use rustc_metadata::cstore::LoadedMacro;
@@ -159,26 +160,23 @@
Some(ext)
}
- /// Ensures that the reduced graph rooted at the given external module
- /// is built, building it if it is not.
- crate fn populate_module_if_necessary(&mut self, module: Module<'a>) {
- if module.populated.get() { return }
- let def_id = module.def_id().unwrap();
- for child in self.cstore.item_children_untracked(def_id, self.session) {
- let child = child.map_id(|_| panic!("unexpected id"));
- BuildReducedGraphVisitor { parent_scope: ParentScope::module(module), r: self }
- .build_reduced_graph_for_external_crate_res(child);
- }
- module.populated.set(true)
- }
-
crate fn build_reduced_graph(
&mut self, fragment: &AstFragment, parent_scope: ParentScope<'a>
) -> LegacyScope<'a> {
+ fragment.visit_with(&mut DefCollector::new(&mut self.definitions, parent_scope.expansion));
let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope };
fragment.visit_with(&mut visitor);
visitor.parent_scope.legacy
}
+
+ crate fn build_reduced_graph_external(&mut self, module: Module<'a>) {
+ let def_id = module.def_id().expect("unpopulated module without a def-id");
+ for child in self.cstore.item_children_untracked(def_id, self.session) {
+ let child = child.map_id(|_| panic!("unexpected id"));
+ BuildReducedGraphVisitor { r: self, parent_scope: ParentScope::module(module) }
+ .build_reduced_graph_for_external_crate_res(child);
+ }
+ }
}
struct BuildReducedGraphVisitor<'a, 'b> {
@@ -186,6 +184,10 @@
parent_scope: ParentScope<'a>,
}
+impl<'a> AsMut<Resolver<'a>> for BuildReducedGraphVisitor<'a, '_> {
+ fn as_mut(&mut self) -> &mut Resolver<'a> { self.r }
+}
+
impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility {
let parent_scope = &self.parent_scope;
@@ -603,8 +605,6 @@
self.r.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX })
};
- self.r.populate_module_if_necessary(module);
-
let used = self.process_legacy_macro_imports(item, module);
let binding =
(module, ty::Visibility::Public, sp, expansion).to_name_binding(self.r.arenas);
@@ -879,9 +879,11 @@
// This is only a guess, two equivalent idents may incorrectly get different gensyms here.
let ident = ident.gensym_if_underscore();
let expansion = ExpnId::root(); // FIXME(jseyfried) intercrate hygiene
+ // Record primary definitions.
match res {
Res::Def(kind @ DefKind::Mod, def_id)
- | Res::Def(kind @ DefKind::Enum, def_id) => {
+ | Res::Def(kind @ DefKind::Enum, def_id)
+ | Res::Def(kind @ DefKind::Trait, def_id) => {
let module = self.r.new_module(parent,
ModuleKind::Def(kind, def_id, ident.name),
def_id,
@@ -889,70 +891,55 @@
span);
self.r.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion));
}
- Res::Def(DefKind::Variant, _)
+ Res::Def(DefKind::Struct, _)
+ | Res::Def(DefKind::Union, _)
+ | Res::Def(DefKind::Variant, _)
| Res::Def(DefKind::TyAlias, _)
| Res::Def(DefKind::ForeignTy, _)
| Res::Def(DefKind::OpaqueTy, _)
| Res::Def(DefKind::TraitAlias, _)
+ | Res::Def(DefKind::AssocTy, _)
+ | Res::Def(DefKind::AssocOpaqueTy, _)
| Res::PrimTy(..)
- | Res::ToolMod => {
- self.r.define(parent, ident, TypeNS, (res, vis, DUMMY_SP, expansion));
- }
+ | Res::ToolMod =>
+ self.r.define(parent, ident, TypeNS, (res, vis, DUMMY_SP, expansion)),
Res::Def(DefKind::Fn, _)
+ | Res::Def(DefKind::Method, _)
| Res::Def(DefKind::Static, _)
| Res::Def(DefKind::Const, _)
- | Res::Def(DefKind::Ctor(CtorOf::Variant, ..), _) => {
- self.r.define(parent, ident, ValueNS, (res, vis, DUMMY_SP, expansion));
- }
- Res::Def(DefKind::Ctor(CtorOf::Struct, ..), def_id) => {
- self.r.define(parent, ident, ValueNS, (res, vis, DUMMY_SP, expansion));
-
- if let Some(struct_def_id) =
- self.r.cstore.def_key(def_id).parent
- .map(|index| DefId { krate: def_id.krate, index: index }) {
- self.r.struct_constructors.insert(struct_def_id, (res, vis));
- }
- }
- Res::Def(DefKind::Trait, def_id) => {
- let module_kind = ModuleKind::Def(DefKind::Trait, def_id, ident.name);
- let module = self.r.new_module(parent,
- module_kind,
- parent.normal_ancestor_id,
- expansion,
- span);
- self.r.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion));
-
- for child in self.r.cstore.item_children_untracked(def_id, self.r.session) {
- let res = child.res.map_id(|_| panic!("unexpected id"));
- let ns = if let Res::Def(DefKind::AssocTy, _) = res {
- TypeNS
- } else { ValueNS };
- self.r.define(module, child.ident, ns,
- (res, ty::Visibility::Public, DUMMY_SP, expansion));
-
- if self.r.cstore.associated_item_cloned_untracked(child.res.def_id())
- .method_has_self_argument {
- self.r.has_self.insert(res.def_id());
- }
- }
- module.populated.set(true);
- }
+ | Res::Def(DefKind::AssocConst, _)
+ | Res::Def(DefKind::Ctor(..), _) =>
+ self.r.define(parent, ident, ValueNS, (res, vis, DUMMY_SP, expansion)),
+ Res::Def(DefKind::Macro(..), _)
+ | Res::NonMacroAttr(..) =>
+ self.r.define(parent, ident, MacroNS, (res, vis, DUMMY_SP, expansion)),
+ Res::Def(DefKind::TyParam, _) | Res::Def(DefKind::ConstParam, _)
+ | Res::Local(..) | Res::SelfTy(..) | Res::SelfCtor(..) | Res::Err =>
+ bug!("unexpected resolution: {:?}", res)
+ }
+ // Record some extra data for better diagnostics.
+ match res {
Res::Def(DefKind::Struct, def_id) | Res::Def(DefKind::Union, def_id) => {
- self.r.define(parent, ident, TypeNS, (res, vis, DUMMY_SP, expansion));
-
- // Record field names for error reporting.
let field_names = self.r.cstore.struct_field_names_untracked(def_id);
self.insert_field_names(def_id, field_names);
}
- Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => {
- self.r.define(parent, ident, MacroNS, (res, vis, DUMMY_SP, expansion));
+ Res::Def(DefKind::Method, def_id) => {
+ if self.r.cstore.associated_item_cloned_untracked(def_id).method_has_self_argument {
+ self.r.has_self.insert(def_id);
+ }
}
- _ => bug!("unexpected resolution: {:?}", res)
+ Res::Def(DefKind::Ctor(CtorOf::Struct, ..), def_id) => {
+ let parent = self.r.cstore.def_key(def_id).parent;
+ if let Some(struct_def_id) = parent.map(|index| DefId { index, ..def_id }) {
+ self.r.struct_constructors.insert(struct_def_id, (res, vis));
+ }
+ }
+ _ => {}
}
}
fn legacy_import_macro(&mut self,
- name: Name,
+ name: ast::Name,
binding: &'a NameBinding<'a>,
span: Span,
allow_shadowing: bool) {
@@ -1021,9 +1008,9 @@
if let Some(span) = import_all {
let directive = macro_use_directive(self, span);
self.r.potentially_unused_imports.push(directive);
- module.for_each_child(|ident, ns, binding| if ns == MacroNS {
- let imported_binding = self.r.import(binding, directive);
- self.legacy_import_macro(ident.name, imported_binding, span, allow_shadowing);
+ module.for_each_child(self, |this, ident, ns, binding| if ns == MacroNS {
+ let imported_binding = this.r.import(binding, directive);
+ this.legacy_import_macro(ident.name, imported_binding, span, allow_shadowing);
});
} else {
for ident in single_imports.iter().cloned() {
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 861b0fd..b79e0c2 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -73,20 +73,23 @@
false
}
-crate fn add_module_candidates(
- module: Module<'_>, names: &mut Vec<TypoSuggestion>, filter_fn: &impl Fn(Res) -> bool
-) {
- for (&(ident, _), resolution) in module.resolutions.borrow().iter() {
- if let Some(binding) = resolution.borrow().binding {
- let res = binding.res();
- if filter_fn(res) {
- names.push(TypoSuggestion::from_res(ident.name, res));
+impl<'a> Resolver<'a> {
+ crate fn add_module_candidates(
+ &mut self,
+ module: Module<'a>,
+ names: &mut Vec<TypoSuggestion>,
+ filter_fn: &impl Fn(Res) -> bool,
+ ) {
+ for (&(ident, _), resolution) in self.resolutions(module).borrow().iter() {
+ if let Some(binding) = resolution.borrow().binding {
+ let res = binding.res();
+ if filter_fn(res) {
+ names.push(TypoSuggestion::from_res(ident.name, res));
+ }
}
}
}
-}
-impl<'a> Resolver<'a> {
/// Combines an error with provided span and emits it.
///
/// This takes the error provided, combines it with the span and any additional spans inside the
@@ -166,12 +169,14 @@
err
}
ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => {
- let mut err = struct_span_err!(self.session,
- span,
- E0403,
- "the name `{}` is already used for a generic \
- parameter in this list of generic parameters",
- name);
+ let mut err = struct_span_err!(
+ self.session,
+ span,
+ E0403,
+ "the name `{}` is already used for a generic \
+ parameter in this item's generic parameters",
+ name,
+ );
err.span_label(span, "already used");
err.span_label(first_use_span, format!("first use of `{}`", name));
err
@@ -402,10 +407,10 @@
Scope::CrateRoot => {
let root_ident = Ident::new(kw::PathRoot, ident.span);
let root_module = this.resolve_crate_root(root_ident);
- add_module_candidates(root_module, &mut suggestions, filter_fn);
+ this.add_module_candidates(root_module, &mut suggestions, filter_fn);
}
Scope::Module(module) => {
- add_module_candidates(module, &mut suggestions, filter_fn);
+ this.add_module_candidates(module, &mut suggestions, filter_fn);
}
Scope::MacroUsePrelude => {
suggestions.extend(this.macro_use_prelude.iter().filter_map(|(name, binding)| {
@@ -453,7 +458,7 @@
Scope::StdLibPrelude => {
if let Some(prelude) = this.prelude {
let mut tmp_suggestions = Vec::new();
- add_module_candidates(prelude, &mut tmp_suggestions, filter_fn);
+ this.add_module_candidates(prelude, &mut tmp_suggestions, filter_fn);
suggestions.extend(tmp_suggestions.into_iter().filter(|s| {
use_prelude || this.is_builtin_macro(s.res)
}));
@@ -509,11 +514,9 @@
while let Some((in_module,
path_segments,
in_module_is_extern)) = worklist.pop() {
- self.populate_module_if_necessary(in_module);
-
// We have to visit module children in deterministic order to avoid
// instabilities in reported imports (#43552).
- in_module.for_each_child_stable(|ident, ns, name_binding| {
+ in_module.for_each_child_stable(self, |this, ident, ns, name_binding| {
// avoid imports entirely
if name_binding.is_import() && !name_binding.is_extern_crate() { return; }
// avoid non-importable candidates as well
@@ -547,7 +550,7 @@
// outside crate private modules => no need to check this)
if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
let did = match res {
- Res::Def(DefKind::Ctor(..), did) => self.parent(did),
+ Res::Def(DefKind::Ctor(..), did) => this.parent(did),
_ => res.opt_def_id(),
};
candidates.push(ImportSuggestion { did, path });
@@ -607,8 +610,6 @@
krate: crate_id,
index: CRATE_DEF_INDEX,
});
- self.populate_module_if_necessary(&crate_root);
-
suggestions.extend(self.lookup_import_candidates_from_module(
lookup_ident, namespace, crate_root, ident, &filter_fn));
}
@@ -805,7 +806,7 @@
/// at the root of the crate instead of the module where it is defined
/// ```
pub(crate) fn check_for_module_export_macro(
- &self,
+ &mut self,
directive: &'b ImportDirective<'b>,
module: ModuleOrUniformRoot<'b>,
ident: Ident,
@@ -826,7 +827,7 @@
return None;
}
- let resolutions = crate_module.resolutions.borrow();
+ let resolutions = self.r.resolutions(crate_module).borrow();
let resolution = resolutions.get(&(ident, MacroNS))?;
let binding = resolution.borrow().binding()?;
if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() {
diff --git a/src/librustc_resolve/error_codes.rs b/src/librustc_resolve/error_codes.rs
index e01f537..1faaf97 100644
--- a/src/librustc_resolve/error_codes.rs
+++ b/src/librustc_resolve/error_codes.rs
@@ -526,15 +526,25 @@
Erroneous code example:
```compile_fail,E0403
-fn foo<T, T>(s: T, u: T) {} // error: the name `T` is already used for a type
- // parameter in this type parameter list
+fn f<T, T>(s: T, u: T) {} // error: the name `T` is already used for a generic
+ // parameter in this item's generic parameters
```
Please verify that none of the type parameters are misspelled, and rename any
clashing parameters. Example:
```
-fn foo<T, Y>(s: T, u: Y) {} // ok!
+fn f<T, Y>(s: T, u: Y) {} // ok!
+```
+
+Type parameters in an associated item also cannot shadow parameters from the
+containing item:
+
+```compile_fail,E0403
+trait Foo<T> {
+ fn do_something(&self) -> T;
+ fn do_something_else<T: Clone>(&self, bar: T);
+}
```
"##,
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index ffdfd85..e15d02a 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -111,6 +111,24 @@
TyParamAsConstParamTy,
}
+impl RibKind<'_> {
+ // Whether this rib kind contains generic parameters, as opposed to local
+ // variables.
+ crate fn contains_params(&self) -> bool {
+ match self {
+ NormalRibKind
+ | FnItemRibKind
+ | ConstantItemRibKind
+ | ModuleRibKind(_)
+ | MacroDefinition(_) => false,
+ AssocItemRibKind
+ | ItemRibKind
+ | ForwardTyParamBanRibKind
+ | TyParamAsConstParamTy => true,
+ }
+ }
+}
+
/// A single local scope.
///
/// A rib represents a scope names can live in. Note that these appear in many places, not just
@@ -798,6 +816,19 @@
let mut function_type_rib = Rib::new(rib_kind);
let mut function_value_rib = Rib::new(rib_kind);
let mut seen_bindings = FxHashMap::default();
+ // We also can't shadow bindings from the parent item
+ if let AssocItemRibKind = rib_kind {
+ let mut add_bindings_for_ns = |ns| {
+ let parent_rib = self.ribs[ns].iter()
+ .rfind(|rib| if let ItemRibKind = rib.kind { true } else { false })
+ .expect("associated item outside of an item");
+ seen_bindings.extend(
+ parent_rib.bindings.iter().map(|(ident, _)| (*ident, ident.span)),
+ );
+ };
+ add_bindings_for_ns(ValueNS);
+ add_bindings_for_ns(TypeNS);
+ }
for param in &generics.params {
match param.kind {
GenericParamKind::Lifetime { .. } => {}
@@ -1929,7 +1960,7 @@
let mut traits = module.traits.borrow_mut();
if traits.is_none() {
let mut collected_traits = Vec::new();
- module.for_each_child(|name, ns, binding| {
+ module.for_each_child(self.r, |_, name, ns, binding| {
if ns != TypeNS { return }
match binding.res() {
Res::Def(DefKind::Trait, _) |
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index 68f9c16..a822fa0 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -1,8 +1,7 @@
use crate::{CrateLint, Module, ModuleKind, ModuleOrUniformRoot};
use crate::{PathResult, PathSource, Segment};
use crate::path_names_to_string;
-use crate::diagnostics::{add_typo_suggestion, add_module_candidates};
-use crate::diagnostics::{ImportSuggestion, TypoSuggestion};
+use crate::diagnostics::{add_typo_suggestion, ImportSuggestion, TypoSuggestion};
use crate::late::{LateResolutionVisitor, RibKind};
use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
@@ -548,7 +547,7 @@
// Items in scope
if let RibKind::ModuleRibKind(module) = rib.kind {
// Items from this module
- add_module_candidates(module, &mut names, &filter_fn);
+ self.r.add_module_candidates(module, &mut names, &filter_fn);
if let ModuleKind::Block(..) = module.kind {
// We can see through blocks
@@ -577,7 +576,7 @@
}));
if let Some(prelude) = self.r.prelude {
- add_module_candidates(prelude, &mut names, &filter_fn);
+ self.r.add_module_candidates(prelude, &mut names, &filter_fn);
}
}
break;
@@ -599,7 +598,7 @@
mod_path, Some(TypeNS), false, span, CrateLint::No
) {
if let ModuleOrUniformRoot::Module(module) = module {
- add_module_candidates(module, &mut names, &filter_fn);
+ self.r.add_module_candidates(module, &mut names, &filter_fn);
}
}
}
@@ -717,9 +716,7 @@
// abort if the module is already found
if result.is_some() { break; }
- self.r.populate_module_if_necessary(in_module);
-
- in_module.for_each_child_stable(|ident, _, name_binding| {
+ in_module.for_each_child_stable(self.r, |_, ident, _, name_binding| {
// abort if the module is already found or if name_binding is private external
if result.is_some() || !name_binding.vis.is_visible_locally() {
return
@@ -750,10 +747,8 @@
fn collect_enum_variants(&mut self, def_id: DefId) -> Option<Vec<Path>> {
self.find_module(def_id).map(|(enum_module, enum_import_suggestion)| {
- self.r.populate_module_if_necessary(enum_module);
-
let mut variants = Vec::new();
- enum_module.for_each_child_stable(|ident, _, name_binding| {
+ enum_module.for_each_child_stable(self.r, |_, ident, _, name_binding| {
if let Res::Def(DefKind::Variant, _) = name_binding.res() {
let mut segms = enum_import_suggestion.path.segments.clone();
segms.push(ast::PathSegment::from_ident(ident));
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 9b5eb51..984473d 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -431,6 +431,8 @@
}
}
+type Resolutions<'a> = RefCell<FxHashMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>;
+
/// One node in the tree of modules.
pub struct ModuleData<'a> {
parent: Option<Module<'a>>,
@@ -439,7 +441,11 @@
// The def id of the closest normal module (`mod`) ancestor (including this module).
normal_ancestor_id: DefId,
- resolutions: RefCell<FxHashMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>,
+ // Mapping between names and their (possibly in-progress) resolutions in this module.
+ // Resolutions in modules from other crates are not populated until accessed.
+ lazy_resolutions: Resolutions<'a>,
+ // True if this is a module from other crate that needs to be populated on access.
+ populate_on_access: Cell<bool>,
// Macro invocations that can expand into items in this module.
unresolved_invocations: RefCell<FxHashSet<ExpnId>>,
@@ -452,11 +458,6 @@
// Used to memoize the traits in this module for faster searches through all traits in scope.
traits: RefCell<Option<Box<[(Ident, &'a NameBinding<'a>)]>>>,
- // Whether this module is populated. If not populated, any attempt to
- // access the children must be preceded with a
- // `populate_module_if_necessary` call.
- populated: Cell<bool>,
-
/// Span of the module itself. Used for error reporting.
span: Span,
@@ -475,30 +476,34 @@
parent,
kind,
normal_ancestor_id,
- resolutions: Default::default(),
+ lazy_resolutions: Default::default(),
+ populate_on_access: Cell::new(!normal_ancestor_id.is_local()),
unresolved_invocations: Default::default(),
no_implicit_prelude: false,
glob_importers: RefCell::new(Vec::new()),
globs: RefCell::new(Vec::new()),
traits: RefCell::new(None),
- populated: Cell::new(normal_ancestor_id.is_local()),
span,
expansion,
}
}
- fn for_each_child<F: FnMut(Ident, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
- for (&(ident, ns), name_resolution) in self.resolutions.borrow().iter() {
- name_resolution.borrow().binding.map(|binding| f(ident, ns, binding));
+ fn for_each_child<R, F>(&'a self, resolver: &mut R, mut f: F)
+ where R: AsMut<Resolver<'a>>, F: FnMut(&mut R, Ident, Namespace, &'a NameBinding<'a>)
+ {
+ for (&(ident, ns), name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() {
+ name_resolution.borrow().binding.map(|binding| f(resolver, ident, ns, binding));
}
}
- fn for_each_child_stable<F: FnMut(Ident, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
- let resolutions = self.resolutions.borrow();
+ fn for_each_child_stable<R, F>(&'a self, resolver: &mut R, mut f: F)
+ where R: AsMut<Resolver<'a>>, F: FnMut(&mut R, Ident, Namespace, &'a NameBinding<'a>)
+ {
+ let resolutions = resolver.as_mut().resolutions(self).borrow();
let mut resolutions = resolutions.iter().collect::<Vec<_>>();
resolutions.sort_by_cached_key(|&(&(ident, ns), _)| (ident.as_str(), ns));
for &(&(ident, ns), &resolution) in resolutions.iter() {
- resolution.borrow().binding.map(|binding| f(ident, ns, binding));
+ resolution.borrow().binding.map(|binding| f(resolver, ident, ns, binding));
}
}
@@ -983,6 +988,10 @@
}
}
+impl<'a> AsMut<Resolver<'a>> for Resolver<'a> {
+ fn as_mut(&mut self) -> &mut Resolver<'a> { self }
+}
+
impl<'a, 'b> ty::DefIdTree for &'a Resolver<'b> {
fn parent(self, id: DefId) -> Option<DefId> {
match id.krate {
@@ -1248,6 +1257,20 @@
self.arenas.alloc_module(module)
}
+ fn resolutions(&mut self, module: Module<'a>) -> &'a Resolutions<'a> {
+ if module.populate_on_access.get() {
+ module.populate_on_access.set(false);
+ self.build_reduced_graph_external(module);
+ }
+ &module.lazy_resolutions
+ }
+
+ fn resolution(&mut self, module: Module<'a>, ident: Ident, ns: Namespace)
+ -> &'a RefCell<NameResolution<'a>> {
+ *self.resolutions(module).borrow_mut().entry((ident.modern(), ns))
+ .or_insert_with(|| self.arenas.alloc_name_resolution())
+ }
+
fn record_use(&mut self, ident: Ident, ns: Namespace,
used_binding: &'a NameBinding<'a>, is_lexical_scope: bool) {
if let Some((b2, kind)) = used_binding.ambiguity {
@@ -1476,7 +1499,7 @@
debug!("walk rib\n{:?}", ribs[i].bindings);
// Use the rib kind to determine whether we are resolving parameters
// (modern hygiene) or local variables (legacy hygiene).
- let rib_ident = if let AssocItemRibKind | ItemRibKind = ribs[i].kind {
+ let rib_ident = if ribs[i].kind.contains_params() {
modern_ident
} else {
ident
@@ -2634,7 +2657,6 @@
return None;
};
let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
- self.populate_module_if_necessary(&crate_root);
Some((crate_root, ty::Visibility::Public, DUMMY_SP, ExpnId::root())
.to_name_binding(self.arenas))
}
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 079145e..6f49377 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -8,7 +8,6 @@
use crate::Namespace::*;
use crate::resolve_imports::ImportResolver;
use rustc::hir::def::{self, DefKind, NonMacroAttrKind};
-use rustc::hir::map::DefCollector;
use rustc::middle::stability;
use rustc::{ty, lint, span_bug};
use syntax::ast::{self, Ident};
@@ -131,7 +130,6 @@
parent_scope.module.unresolved_invocations.borrow_mut().extend(derives);
// Integrate the new AST fragment into all the definition and module structures.
- fragment.visit_with(&mut DefCollector::new(&mut self.definitions, expansion));
let output_legacy_scope = self.build_reduced_graph(fragment, parent_scope);
self.output_legacy_scopes.insert(expansion, output_legacy_scope);
}
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 693893e..b49f186 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -7,9 +7,8 @@
use crate::Determinacy::{self, *};
use crate::Namespace::{self, TypeNS, MacroNS};
use crate::{NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError};
-use crate::{Resolver, ResolutionError, Segment};
+use crate::{Resolver, ResolutionError, Segment, ModuleKind};
use crate::{names_to_string, module_to_string};
-use crate::ModuleKind;
use crate::diagnostics::Suggestion;
use errors::Applicability;
@@ -37,7 +36,7 @@
use log::*;
-use std::cell::{Cell, RefCell};
+use std::cell::Cell;
use std::{mem, ptr};
type Res = def::Res<NodeId>;
@@ -161,12 +160,6 @@
}
impl<'a> Resolver<'a> {
- crate fn resolution(&self, module: Module<'a>, ident: Ident, ns: Namespace)
- -> &'a RefCell<NameResolution<'a>> {
- *module.resolutions.borrow_mut().entry((ident.modern(), ns))
- .or_insert_with(|| self.arenas.alloc_name_resolution())
- }
-
crate fn resolve_ident_in_module_unadjusted(
&mut self,
module: ModuleOrUniformRoot<'a>,
@@ -242,8 +235,6 @@
}
};
- self.populate_module_if_necessary(module);
-
let resolution = self.resolution(module, ident, ns)
.try_borrow_mut()
.map_err(|_| (Determined, Weak::No))?; // This happens when there is a cycle of imports.
@@ -1027,7 +1018,8 @@
return if all_ns_failed {
let resolutions = match module {
- ModuleOrUniformRoot::Module(module) => Some(module.resolutions.borrow()),
+ ModuleOrUniformRoot::Module(module) =>
+ Some(self.r.resolutions(module).borrow()),
_ => None,
};
let resolutions = resolutions.as_ref().into_iter().flat_map(|r| r.iter());
@@ -1265,8 +1257,6 @@
}
};
- self.r.populate_module_if_necessary(module);
-
if module.is_trait() {
self.r.session.span_err(directive.span, "items in traits are not importable.");
return;
@@ -1282,8 +1272,8 @@
// Ensure that `resolutions` isn't borrowed during `try_define`,
// since it might get updated via a glob cycle.
- let bindings = module.resolutions.borrow().iter().filter_map(|(&ident, resolution)| {
- resolution.borrow().binding().map(|binding| (ident, binding))
+ let bindings = self.r.resolutions(module).borrow().iter().filter_map(|(ident, resolution)| {
+ resolution.borrow().binding().map(|binding| (*ident, binding))
}).collect::<Vec<_>>();
for ((mut ident, ns), binding) in bindings {
let scope = match ident.span.reverse_glob_adjust(module.expansion, directive.span) {
@@ -1310,7 +1300,7 @@
let mut reexports = Vec::new();
- for (&(ident, ns), resolution) in module.resolutions.borrow().iter() {
+ for (&(ident, ns), resolution) in self.r.resolutions(module).borrow().iter() {
let resolution = &mut *resolution.borrow_mut();
let binding = match resolution.binding {
Some(binding) => binding,
@@ -1369,8 +1359,8 @@
Some(ModuleOrUniformRoot::Module(module)) => module,
_ => bug!("module should exist"),
};
- let resolutions = imported_module.parent.expect("parent should exist")
- .resolutions.borrow();
+ let parent_module = imported_module.parent.expect("parent should exist");
+ let resolutions = self.r.resolutions(parent_module).borrow();
let enum_path_segment_index = directive.module_path.len() - 1;
let enum_ident = directive.module_path[enum_path_segment_index].ident;
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index 8bb24ee..dfbf8bc 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -67,7 +67,7 @@
match intrinsic {
"size_of" | "min_align_of" | "needs_drop" |
"add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" |
- "overflowing_add" | "overflowing_sub" | "overflowing_mul" |
+ "wrapping_add" | "wrapping_sub" | "wrapping_mul" |
"saturating_add" | "saturating_sub" |
"rotate_left" | "rotate_right" |
"ctpop" | "ctlz" | "cttz" | "bswap" | "bitreverse" |
@@ -314,7 +314,7 @@
(1, vec![param(0), param(0)], param(0)),
"unchecked_add" | "unchecked_sub" | "unchecked_mul" =>
(1, vec![param(0), param(0)], param(0)),
- "overflowing_add" | "overflowing_sub" | "overflowing_mul" =>
+ "wrapping_add" | "wrapping_sub" | "wrapping_mul" =>
(1, vec![param(0), param(0)], param(0)),
"saturating_add" | "saturating_sub" =>
(1, vec![param(0), param(0)], param(0)),
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index b2c0e34..28a1ccd 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -203,7 +203,6 @@
fcx.register_wf_obligation(ty, span, code.clone());
}
ty::AssocKind::Method => {
- reject_shadowing_parameters(fcx.tcx, item.def_id);
let sig = fcx.tcx.fn_sig(item.def_id);
let sig = fcx.normalize_associated_types_in(span, &sig);
check_fn_or_method(tcx, fcx, span, sig,
@@ -998,34 +997,6 @@
err.emit();
}
-fn reject_shadowing_parameters(tcx: TyCtxt<'_>, def_id: DefId) {
- let generics = tcx.generics_of(def_id);
- let parent = tcx.generics_of(generics.parent.unwrap());
- let impl_params: FxHashMap<_, _> = parent.params.iter().flat_map(|param| match param.kind {
- GenericParamDefKind::Lifetime => None,
- GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => {
- Some((param.name, param.def_id))
- }
- }).collect();
-
- for method_param in &generics.params {
- // Shadowing is checked in `resolve_lifetime`.
- if let GenericParamDefKind::Lifetime = method_param.kind {
- continue
- }
- if impl_params.contains_key(&method_param.name) {
- // Tighten up the span to focus on only the shadowing type.
- let type_span = tcx.def_span(method_param.def_id);
-
- // The expectation here is that the original trait declaration is
- // local so it should be okay to just unwrap everything.
- let trait_def_id = impl_params[&method_param.name];
- let trait_decl_span = tcx.def_span(trait_def_id);
- error_194(tcx, type_span, trait_decl_span, &method_param.name.as_str()[..]);
- }
- }
-}
-
/// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
/// aren't true.
fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, span: Span, id: hir::HirId) {
@@ -1152,12 +1123,3 @@
err.span_label(span, "unused parameter");
err
}
-
-fn error_194(tcx: TyCtxt<'_>, span: Span, trait_decl_span: Span, name: &str) {
- struct_span_err!(tcx.sess, span, E0194,
- "type parameter `{}` shadows another type parameter of the same name",
- name)
- .span_label(span, "shadows another type parameter")
- .span_label(trait_decl_span, format!("first `{}` declared here", name))
- .emit();
-}
diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs
index 90118a9..ca9ce3d 100644
--- a/src/librustc_typeck/error_codes.rs
+++ b/src/librustc_typeck/error_codes.rs
@@ -1718,22 +1718,6 @@
reason to also specify it in a `where` clause.
"##,
-E0194: r##"
-A type parameter was declared which shadows an existing one. An example of this
-error:
-
-```compile_fail,E0194
-trait Foo<T> {
- fn do_something(&self) -> T;
- fn do_something_else<T: Clone>(&self, bar: T);
-}
-```
-
-In this example, the trait `Foo` and the trait method `do_something_else` both
-define a type parameter `T`. This is not allowed: if the method wishes to
-define a type parameter, it must use a different name for it.
-"##,
-
E0195: r##"
Your method's lifetime parameters do not match the trait declaration.
Erroneous code example:
@@ -4837,6 +4821,7 @@
// E0188, // can not cast an immutable reference to a mutable pointer
// E0189, // deprecated: can only cast a boxed pointer to a boxed object
// E0190, // deprecated: can only cast a &-pointer to an &-object
+// E0194, // merged into E0403
// E0196, // cannot determine a type for this closure
E0203, // type parameter has more than one relaxed default bound,
// and only one is supported
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 3ae37f7..9091607 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -5,7 +5,7 @@
pub use crate::symbol::{Ident, Symbol as Name};
pub use crate::util::parser::ExprPrecedence;
-use crate::ext::hygiene::{ExpnId, SyntaxContext};
+use crate::ext::hygiene::ExpnId;
use crate::parse::token::{self, DelimToken};
use crate::print::pprust;
use crate::ptr::P;
@@ -1782,7 +1782,6 @@
pub volatile: bool,
pub alignstack: bool,
pub dialect: AsmDialect,
- pub ctxt: SyntaxContext,
}
/// An argument in a function header.
@@ -2030,7 +2029,6 @@
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
pub struct GlobalAsm {
pub asm: Symbol,
- pub ctxt: SyntaxContext,
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 8a56ae1..1a87a90 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -30,7 +30,6 @@
use errors::{Applicability, DiagnosticBuilder, Handler};
use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sync::Lock;
use rustc_target::spec::abi::Abi;
use syntax_pos::{Span, DUMMY_SP, MultiSpan};
use log::debug;
@@ -2088,11 +2087,6 @@
"type ascription is experimental");
}
}
- ast::ExprKind::Yield(..) => {
- gate_feature_post!(&self, generators,
- e.span,
- "yield syntax is experimental");
- }
ast::ExprKind::TryBlock(_) => {
gate_feature_post!(&self, try_blocks, e.span, "`try` expression is experimental");
}
@@ -2427,10 +2421,6 @@
features
}
-fn for_each_in_lock<T>(vec: &Lock<Vec<T>>, f: impl Fn(&T)) {
- vec.borrow().iter().for_each(f);
-}
-
pub fn check_crate(krate: &ast::Crate,
sess: &ParseSess,
features: &Features,
@@ -2443,26 +2433,16 @@
plugin_attributes,
};
- for_each_in_lock(&sess.param_attr_spans, |span| gate_feature!(
- &ctx,
- param_attrs,
- *span,
- "attributes on function parameters are unstable"
- ));
+ macro_rules! gate_all {
+ ($spans:ident, $gate:ident, $msg:literal) => {
+ for span in &*sess.$spans.borrow() { gate_feature!(&ctx, $gate, *span, $msg); }
+ }
+ }
- for_each_in_lock(&sess.let_chains_spans, |span| gate_feature!(
- &ctx,
- let_chains,
- *span,
- "`let` expressions in this position are experimental"
- ));
-
- for_each_in_lock(&sess.async_closure_spans, |span| gate_feature!(
- &ctx,
- async_closure,
- *span,
- "async closures are unstable"
- ));
+ gate_all!(param_attr_spans, param_attrs, "attributes on function parameters are unstable");
+ gate_all!(let_chains_spans, let_chains, "`let` expressions in this position are experimental");
+ gate_all!(async_closure_spans, async_closure, "async closures are unstable");
+ gate_all!(yield_spans, generators, "yield syntax is experimental");
let visitor = &mut PostExpansionVisitor {
context: &ctx,
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index acafe32..18d4a64 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -1182,7 +1182,7 @@
}
ExprKind::InlineAsm(asm) => {
let InlineAsm { asm: _, asm_str_style: _, outputs, inputs, clobbers: _, volatile: _,
- alignstack: _, dialect: _, ctxt: _ } = asm.deref_mut();
+ alignstack: _, dialect: _ } = asm.deref_mut();
for out in outputs {
let InlineAsmOutput { constraint: _, expr, is_rw: _, is_indirect: _ } = out;
vis.visit_expr(expr);
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 26f78b9..9088f92 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -63,6 +63,8 @@
pub let_chains_spans: Lock<Vec<Span>>,
// Places where `async || ..` exprs were used and should be feature gated.
pub async_closure_spans: Lock<Vec<Span>>,
+ // Places where `yield e?` exprs were used and should be feature gated.
+ pub yield_spans: Lock<Vec<Span>>,
pub injected_crate_name: Once<Symbol>,
}
@@ -92,6 +94,7 @@
param_attr_spans: Lock::new(Vec::new()),
let_chains_spans: Lock::new(Vec::new()),
async_closure_spans: Lock::new(Vec::new()),
+ yield_spans: Lock::new(Vec::new()),
injected_crate_name: Once::new(),
}
}
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index f4b6a92..ccc6bd150 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -997,6 +997,9 @@
} else {
ex = ExprKind::Yield(None);
}
+
+ let span = lo.to(hi);
+ self.sess.yield_spans.borrow_mut().push(span);
} else if self.eat_keyword(kw::Let) {
return self.parse_let_expr(attrs);
} else if is_span_rust_2018 && self.eat_keyword(kw::Await) {
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs
index 950166f..644a44f 100644
--- a/src/libsyntax_ext/asm.rs
+++ b/src/libsyntax_ext/asm.rs
@@ -63,7 +63,7 @@
MacEager::expr(P(ast::Expr {
id: ast::DUMMY_NODE_ID,
node: ast::ExprKind::InlineAsm(P(inline_asm)),
- span: sp,
+ span: sp.with_ctxt(cx.backtrace()),
attrs: ThinVec::new(),
}))
}
@@ -277,6 +277,5 @@
volatile,
alignstack,
dialect,
- ctxt: cx.backtrace(),
}))
}
diff --git a/src/libsyntax_ext/deriving/cmp/ord.rs b/src/libsyntax_ext/deriving/cmp/ord.rs
index 885cfee..55687c3 100644
--- a/src/libsyntax_ext/deriving/cmp/ord.rs
+++ b/src/libsyntax_ext/deriving/cmp/ord.rs
@@ -43,17 +43,18 @@
}
-pub fn ordering_collapsed(cx: &mut ExtCtxt<'_>,
- span: Span,
- self_arg_tags: &[ast::Ident])
- -> P<ast::Expr> {
+pub fn ordering_collapsed(
+ cx: &mut ExtCtxt<'_>,
+ span: Span,
+ self_arg_tags: &[ast::Ident],
+) -> P<ast::Expr> {
let lft = cx.expr_ident(span, self_arg_tags[0]);
let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
- cx.expr_method_call(span, lft, cx.ident_of("cmp"), vec![rgt])
+ cx.expr_method_call(span, lft, ast::Ident::new(sym::cmp, span), vec![rgt])
}
pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> {
- let test_id = cx.ident_of("cmp").gensym();
+ let test_id = ast::Ident::new(sym::cmp, span);
let equals_path = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
let cmp_path = cx.std_path(&[sym::cmp, sym::Ord, sym::cmp]);
@@ -75,34 +76,34 @@
// as the outermost one, and the last as the innermost.
false,
|cx, span, old, self_f, other_fs| {
- // match new {
- // ::std::cmp::Ordering::Equal => old,
- // cmp => cmp
- // }
+ // match new {
+ // ::std::cmp::Ordering::Equal => old,
+ // cmp => cmp
+ // }
- let new = {
- let other_f = match other_fs {
- [o_f] => o_f,
- _ => cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`"),
- };
+ let new = {
+ let other_f = match other_fs {
+ [o_f] => o_f,
+ _ => cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`"),
+ };
- let args = vec![
- cx.expr_addr_of(span, self_f),
- cx.expr_addr_of(span, other_f.clone()),
- ];
+ let args = vec![
+ cx.expr_addr_of(span, self_f),
+ cx.expr_addr_of(span, other_f.clone()),
+ ];
- cx.expr_call_global(span, cmp_path.clone(), args)
- };
+ cx.expr_call_global(span, cmp_path.clone(), args)
+ };
- let eq_arm = cx.arm(span,
- vec![cx.pat_path(span, equals_path.clone())],
- old);
- let neq_arm = cx.arm(span,
- vec![cx.pat_ident(span, test_id)],
- cx.expr_ident(span, test_id));
+ let eq_arm = cx.arm(span,
+ vec![cx.pat_path(span, equals_path.clone())],
+ old);
+ let neq_arm = cx.arm(span,
+ vec![cx.pat_ident(span, test_id)],
+ cx.expr_ident(span, test_id));
- cx.expr_match(span, new, vec![eq_arm, neq_arm])
- },
+ cx.expr_match(span, new, vec![eq_arm, neq_arm])
+ },
cx.expr_path(equals_path.clone()),
Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
if self_args.len() != 2 {
diff --git a/src/libsyntax_ext/deriving/cmp/partial_ord.rs b/src/libsyntax_ext/deriving/cmp/partial_ord.rs
index 0ec30f5..740b92a 100644
--- a/src/libsyntax_ext/deriving/cmp/partial_ord.rs
+++ b/src/libsyntax_ext/deriving/cmp/partial_ord.rs
@@ -94,11 +94,12 @@
GeOp,
}
-pub fn some_ordering_collapsed(cx: &mut ExtCtxt<'_>,
- span: Span,
- op: OrderingOp,
- self_arg_tags: &[ast::Ident])
- -> P<ast::Expr> {
+pub fn some_ordering_collapsed(
+ cx: &mut ExtCtxt<'_>,
+ span: Span,
+ op: OrderingOp,
+ self_arg_tags: &[ast::Ident],
+) -> P<ast::Expr> {
let lft = cx.expr_ident(span, self_arg_tags[0]);
let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
let op_str = match op {
@@ -108,11 +109,11 @@
GtOp => "gt",
GeOp => "ge",
};
- cx.expr_method_call(span, lft, cx.ident_of(op_str), vec![rgt])
+ cx.expr_method_call(span, lft, ast::Ident::from_str_and_span(op_str, span), vec![rgt])
}
pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> {
- let test_id = cx.ident_of("cmp").gensym();
+ let test_id = ast::Ident::new(sym::cmp, span);
let ordering = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
let ordering_expr = cx.expr_path(ordering.clone());
let equals_expr = cx.expr_some(span, ordering_expr);
diff --git a/src/libsyntax_ext/deriving/debug.rs b/src/libsyntax_ext/deriving/debug.rs
index 1d5234a..4415354 100644
--- a/src/libsyntax_ext/deriving/debug.rs
+++ b/src/libsyntax_ext/deriving/debug.rs
@@ -62,7 +62,7 @@
// We want to make sure we have the ctxt set so that we can use unstable methods
let span = span.with_ctxt(cx.backtrace());
let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
- let builder = Ident::from_str("debug_trait_builder").gensym();
+ let builder = Ident::from_str_and_span("debug_trait_builder", span);
let builder_expr = cx.expr_ident(span, builder.clone());
let fmt = substr.nonself_args[0].clone();
@@ -73,7 +73,7 @@
// tuple struct/"normal" variant
let expr =
cx.expr_method_call(span, fmt, Ident::from_str("debug_tuple"), vec![name]);
- stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr));
+ stmts.push(cx.stmt_let(span, true, builder, expr));
for field in fields {
// Use double indirection to make sure this works for unsized types
@@ -82,7 +82,7 @@
let expr = cx.expr_method_call(span,
builder_expr.clone(),
- Ident::with_dummy_span(sym::field),
+ Ident::new(sym::field, span),
vec![field]);
// Use `let _ = expr;` to avoid triggering the
@@ -106,7 +106,7 @@
let field = cx.expr_addr_of(field.span, field);
let expr = cx.expr_method_call(span,
builder_expr.clone(),
- Ident::with_dummy_span(sym::field),
+ Ident::new(sym::field, span),
vec![name, field]);
stmts.push(stmt_let_undescore(cx, span, expr));
}
diff --git a/src/libsyntax_ext/deriving/decodable.rs b/src/libsyntax_ext/deriving/decodable.rs
index 293c5a1..9b6f851 100644
--- a/src/libsyntax_ext/deriving/decodable.rs
+++ b/src/libsyntax_ext/deriving/decodable.rs
@@ -1,6 +1,6 @@
-//! The compiler code necessary for `#[derive(Decodable)]`. See encodable.rs for more.
+//! The compiler code necessary for `#[derive(RustcDecodable)]`. See encodable.rs for more.
-use crate::deriving::{self, pathvec_std};
+use crate::deriving::pathvec_std;
use crate::deriving::generic::*;
use crate::deriving::generic::ty::*;
@@ -17,7 +17,7 @@
item: &Annotatable,
push: &mut dyn FnMut(Annotatable)) {
let krate = "rustc_serialize";
- let typaram = &*deriving::hygienic_type_parameter(item, "__D");
+ let typaram = "__D";
let trait_def = TraitDef {
span,
diff --git a/src/libsyntax_ext/deriving/encodable.rs b/src/libsyntax_ext/deriving/encodable.rs
index 52e74a7..8b18fb2 100644
--- a/src/libsyntax_ext/deriving/encodable.rs
+++ b/src/libsyntax_ext/deriving/encodable.rs
@@ -1,11 +1,12 @@
-//! The compiler code necessary to implement the `#[derive(Encodable)]`
-//! (and `Decodable`, in `decodable.rs`) extension. The idea here is that
-//! type-defining items may be tagged with `#[derive(Encodable, Decodable)]`.
+//! The compiler code necessary to implement the `#[derive(RustcEncodable)]`
+//! (and `RustcDecodable`, in `decodable.rs`) extension. The idea here is that
+//! type-defining items may be tagged with
+//! `#[derive(RustcEncodable, RustcDecodable)]`.
//!
//! For example, a type like:
//!
//! ```
-//! #[derive(Encodable, Decodable)]
+//! #[derive(RustcEncodable, RustcDecodable)]
//! struct Node { id: usize }
//! ```
//!
@@ -40,15 +41,17 @@
//! references other non-built-in types. A type definition like:
//!
//! ```
-//! # #[derive(Encodable, Decodable)] struct Span;
-//! #[derive(Encodable, Decodable)]
+//! # #[derive(RustcEncodable, RustcDecodable)]
+//! # struct Span;
+//! #[derive(RustcEncodable, RustcDecodable)]
//! struct Spanned<T> { node: T, span: Span }
//! ```
//!
//! would yield functions like:
//!
//! ```
-//! # #[derive(Encodable, Decodable)] struct Span;
+//! # #[derive(RustcEncodable, RustcDecodable)]
+//! # struct Span;
//! # struct Spanned<T> { node: T, span: Span }
//! impl<
//! S: Encoder<E>,
@@ -82,7 +85,7 @@
//! }
//! ```
-use crate::deriving::{self, pathvec_std};
+use crate::deriving::pathvec_std;
use crate::deriving::generic::*;
use crate::deriving::generic::ty::*;
@@ -98,7 +101,7 @@
item: &Annotatable,
push: &mut dyn FnMut(Annotatable)) {
let krate = "rustc_serialize";
- let typaram = &*deriving::hygienic_type_parameter(item, "__S");
+ let typaram = "__S";
let trait_def = TraitDef {
span,
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index 55fb767..1475bac 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -890,7 +890,7 @@
for (ty, name) in self.args.iter() {
let ast_ty = ty.to_ty(cx, trait_.span, type_ident, generics);
- let ident = cx.ident_of(name).gensym();
+ let ident = ast::Ident::from_str_and_span(name, trait_.span);
arg_tys.push((ident, ast_ty));
let arg_expr = cx.expr_ident(trait_.span, ident);
@@ -1210,7 +1210,7 @@
let vi_idents = self_arg_names.iter()
.map(|name| {
let vi_suffix = format!("{}_vi", &name[..]);
- cx.ident_of(&vi_suffix[..]).gensym()
+ ast::Ident::from_str_and_span(&vi_suffix[..], trait_.span)
})
.collect::<Vec<ast::Ident>>();
@@ -1387,7 +1387,10 @@
let variant_value =
deriving::call_intrinsic(cx, sp, "discriminant_value", vec![self_addr]);
- let target_ty = cx.ty_ident(sp, cx.ident_of(target_type_name));
+ let target_ty = cx.ty_ident(
+ sp,
+ ast::Ident::from_str_and_span(target_type_name, sp),
+ );
let variant_disr = cx.expr_cast(sp, variant_value, target_ty);
let let_stmt = cx.stmt_let(sp, false, ident, variant_disr);
index_let_stmts.push(let_stmt);
@@ -1588,7 +1591,7 @@
let mut ident_exprs = Vec::new();
for (i, struct_field) in struct_def.fields().iter().enumerate() {
let sp = struct_field.span.with_ctxt(self.span.ctxt());
- let ident = cx.ident_of(&format!("{}_{}", prefix, i)).gensym();
+ let ident = ast::Ident::from_str_and_span(&format!("{}_{}", prefix, i), self.span);
paths.push(ident.with_span_pos(sp));
let val = cx.expr_path(cx.path_ident(sp, ident));
let val = if use_temporaries {
diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs
index 399829e..7fcf036 100644
--- a/src/libsyntax_ext/deriving/generic/ty.rs
+++ b/src/libsyntax_ext/deriving/generic/ty.rs
@@ -72,7 +72,7 @@
self_ty: Ident,
self_generics: &Generics)
-> ast::Path {
- let mut idents = self.path.iter().map(|s| cx.ident_of(*s)).collect();
+ let mut idents = self.path.iter().map(|s| Ident::from_str_and_span(*s, span)).collect();
let lt = mk_lifetimes(cx, span, &self.lifetime);
let tys: Vec<P<ast::Ty>> =
self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
@@ -209,7 +209,7 @@
cx.trait_bound(path)
})
.collect();
- cx.typaram(span, cx.ident_of(name), attrs.to_owned(), bounds, None)
+ cx.typaram(span, ast::Ident::from_str_and_span(name, span), attrs.to_owned(), bounds, None)
}
fn mk_generics(params: Vec<ast::GenericParam>, span: Span) -> Generics {
diff --git a/src/libsyntax_ext/deriving/hash.rs b/src/libsyntax_ext/deriving/hash.rs
index 9787722..2fc594a 100644
--- a/src/libsyntax_ext/deriving/hash.rs
+++ b/src/libsyntax_ext/deriving/hash.rs
@@ -16,7 +16,7 @@
let path = Path::new_(pathvec_std!(cx, hash::Hash), None, vec![], PathKind::Std);
- let typaram = &*deriving::hygienic_type_parameter(item, "__H");
+ let typaram = "__H";
let arg = Path::new_local(typaram);
let hash_trait_def = TraitDef {
diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs
index 8cd2853..da68eea 100644
--- a/src/libsyntax_ext/deriving/mod.rs
+++ b/src/libsyntax_ext/deriving/mod.rs
@@ -54,33 +54,6 @@
}
}
-/// Construct a name for the inner type parameter that can't collide with any type parameters of
-/// the item. This is achieved by starting with a base and then concatenating the names of all
-/// other type parameters.
-// FIXME(aburka): use real hygiene when that becomes possible
-fn hygienic_type_parameter(item: &Annotatable, base: &str) -> String {
- let mut typaram = String::from(base);
- if let Annotatable::Item(ref item) = *item {
- match item.node {
- ast::ItemKind::Struct(_, ast::Generics { ref params, .. }) |
- ast::ItemKind::Enum(_, ast::Generics { ref params, .. }) => {
- for param in params {
- match param.kind {
- ast::GenericParamKind::Type { .. } => {
- typaram.push_str(¶m.ident.as_str());
- }
- _ => {}
- }
- }
- }
-
- _ => {}
- }
- }
-
- typaram
-}
-
/// Constructs an expression that calls an intrinsic
fn call_intrinsic(cx: &ExtCtxt<'_>,
span: Span,
diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs
index 112192f..73ebeae 100644
--- a/src/libsyntax_ext/global_asm.rs
+++ b/src/libsyntax_ext/global_asm.rs
@@ -30,7 +30,7 @@
id: ast::DUMMY_NODE_ID,
node: ast::ItemKind::GlobalAsm(P(global_asm)),
vis: respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited),
- span: sp,
+ span: sp.with_ctxt(cx.backtrace()),
tokens: None,
})])
}
@@ -61,8 +61,5 @@
None => return Ok(None),
};
- Ok(Some(ast::GlobalAsm {
- asm,
- ctxt: cx.backtrace(),
- }))
+ Ok(Some(ast::GlobalAsm { asm }))
}
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index 87d930f..ebfb076 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -750,15 +750,3 @@
Ok(ExpnId::root()) // FIXME(jseyfried) intercrate hygiene
}
}
-
-impl Encodable for SyntaxContext {
- fn encode<E: Encoder>(&self, _: &mut E) -> Result<(), E::Error> {
- Ok(()) // FIXME(jseyfried) intercrate hygiene
- }
-}
-
-impl Decodable for SyntaxContext {
- fn decode<D: Decoder>(_: &mut D) -> Result<Self, D::Error> {
- Ok(SyntaxContext::root()) // FIXME(jseyfried) intercrate hygiene
- }
-}
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 27fc66d..bed898f 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -8,6 +8,7 @@
use rustc_data_structures::newtype_index;
use rustc_macros::symbols;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
+use rustc_serialize::{UseSpecializedDecodable, UseSpecializedEncodable};
use std::cmp::{PartialEq, Ordering, PartialOrd, Ord};
use std::fmt;
@@ -847,28 +848,9 @@
}
}
-impl Encodable for Ident {
- fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
- if !self.span.modern().from_expansion() {
- s.emit_str(&self.as_str())
- } else { // FIXME(jseyfried): intercrate hygiene
- let mut string = "#".to_owned();
- string.push_str(&self.as_str());
- s.emit_str(&string)
- }
- }
-}
+impl UseSpecializedEncodable for Ident {}
-impl Decodable for Ident {
- fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> {
- let string = d.read_str()?;
- Ok(if !string.starts_with('#') {
- Ident::from_str(&string)
- } else { // FIXME(jseyfried): intercrate hygiene
- Ident::from_str(&string[1..]).gensym()
- })
- }
-}
+impl UseSpecializedDecodable for Ident {}
/// A symbol is an interned or gensymed string. A gensym is a symbol that is
/// never equal to any other symbol.
diff --git a/src/test/pretty/stmt_expr_attributes.rs b/src/test/pretty/stmt_expr_attributes.rs
index 02d9323..619cce6 100644
--- a/src/test/pretty/stmt_expr_attributes.rs
+++ b/src/test/pretty/stmt_expr_attributes.rs
@@ -259,8 +259,6 @@
}
}
-/////////////////
-
fn foo() { }
fn foo3(_: i32, _: (), _: ()) { }
fn qux(_: i32) { }
diff --git a/src/test/run-make-fulldeps/reproducible-build-2/Makefile b/src/test/run-make-fulldeps/reproducible-build-2/Makefile
index b96954f..45c9a74 100644
--- a/src/test/run-make-fulldeps/reproducible-build-2/Makefile
+++ b/src/test/run-make-fulldeps/reproducible-build-2/Makefile
@@ -5,7 +5,8 @@
# Objects are reproducible but their path is not.
all: \
- fat_lto
+ fat_lto \
+ sysroot
fat_lto:
rm -rf $(TMPDIR) && mkdir $(TMPDIR)
@@ -14,3 +15,12 @@
cp $(TMPDIR)/reproducible-build $(TMPDIR)/reproducible-build-a
$(RUSTC) reproducible-build.rs -C lto=fat
cmp "$(TMPDIR)/reproducible-build-a" "$(TMPDIR)/reproducible-build" || exit 1
+
+sysroot:
+ rm -rf $(TMPDIR) && mkdir $(TMPDIR)
+ $(RUSTC) reproducible-build-aux.rs
+ $(RUSTC) reproducible-build.rs --crate-type rlib --sysroot $(shell $(RUSTC) --print sysroot) --remap-path-prefix=$(shell $(RUSTC) --print sysroot)=/sysroot
+ cp -r $(shell $(RUSTC) --print sysroot) $(TMPDIR)/sysroot
+ cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfoo.rlib
+ $(RUSTC) reproducible-build.rs --crate-type rlib --sysroot $(TMPDIR)/sysroot --remap-path-prefix=$(TMPDIR)/sysroot=/sysroot
+ cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1
diff --git a/src/test/ui/associated-type/associated-type-projection-from-supertrait.rs b/src/test/ui/associated-type/associated-type-projection-from-supertrait.rs
index 06dfe49..7e05bcd 100644
--- a/src/test/ui/associated-type/associated-type-projection-from-supertrait.rs
+++ b/src/test/ui/associated-type/associated-type-projection-from-supertrait.rs
@@ -12,30 +12,22 @@
fn chip_paint(&self, c: Self::Color) { }
}
-///////////////////////////////////////////////////////////////////////////
-
struct Black;
struct ModelT;
impl Vehicle for ModelT { type Color = Black; }
impl Car for ModelT { }
-///////////////////////////////////////////////////////////////////////////
-
struct Blue;
struct ModelU;
impl Vehicle for ModelU { type Color = Blue; }
impl Car for ModelU { }
-///////////////////////////////////////////////////////////////////////////
-
fn dent<C:Car>(c: C, color: C::Color) { c.chip_paint(color) }
fn a() { dent(ModelT, Black); }
fn b() { dent(ModelT, Blue); } //~ ERROR mismatched types
fn c() { dent(ModelU, Black); } //~ ERROR mismatched types
fn d() { dent(ModelU, Blue); }
-///////////////////////////////////////////////////////////////////////////
-
fn e() { ModelT.chip_paint(Black); }
fn f() { ModelT.chip_paint(Blue); } //~ ERROR mismatched types
fn g() { ModelU.chip_paint(Black); } //~ ERROR mismatched types
diff --git a/src/test/ui/associated-type/associated-type-projection-from-supertrait.stderr b/src/test/ui/associated-type/associated-type-projection-from-supertrait.stderr
index 06f1a1c..4ba4925 100644
--- a/src/test/ui/associated-type/associated-type-projection-from-supertrait.stderr
+++ b/src/test/ui/associated-type/associated-type-projection-from-supertrait.stderr
@@ -1,5 +1,5 @@
error[E0308]: mismatched types
- --> $DIR/associated-type-projection-from-supertrait.rs:33:23
+ --> $DIR/associated-type-projection-from-supertrait.rs:27:23
|
LL | fn b() { dent(ModelT, Blue); }
| ^^^^ expected struct `Black`, found struct `Blue`
@@ -8,7 +8,7 @@
found type `Blue`
error[E0308]: mismatched types
- --> $DIR/associated-type-projection-from-supertrait.rs:34:23
+ --> $DIR/associated-type-projection-from-supertrait.rs:28:23
|
LL | fn c() { dent(ModelU, Black); }
| ^^^^^ expected struct `Blue`, found struct `Black`
@@ -17,7 +17,7 @@
found type `Black`
error[E0308]: mismatched types
- --> $DIR/associated-type-projection-from-supertrait.rs:40:28
+ --> $DIR/associated-type-projection-from-supertrait.rs:32:28
|
LL | fn f() { ModelT.chip_paint(Blue); }
| ^^^^ expected struct `Black`, found struct `Blue`
@@ -26,7 +26,7 @@
found type `Blue`
error[E0308]: mismatched types
- --> $DIR/associated-type-projection-from-supertrait.rs:41:28
+ --> $DIR/associated-type-projection-from-supertrait.rs:33:28
|
LL | fn g() { ModelU.chip_paint(Black); }
| ^^^^^ expected struct `Blue`, found struct `Black`
diff --git a/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.rs b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.rs
index 6531308..6b2bbbe 100644
--- a/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.rs
+++ b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.rs
@@ -11,22 +11,16 @@
fn honk(&self) { }
}
-///////////////////////////////////////////////////////////////////////////
-
struct Black;
struct ModelT;
impl Vehicle for ModelT { type Color = Black; }
impl Car for ModelT { }
-///////////////////////////////////////////////////////////////////////////
-
struct Blue;
struct ModelU;
impl Vehicle for ModelU { type Color = Blue; }
impl Car for ModelU { }
-///////////////////////////////////////////////////////////////////////////
-
fn black_car<C:Car<Color=Black>>(c: C) {
}
diff --git a/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr
index 4b54860..89c48d5 100644
--- a/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr
+++ b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr
@@ -1,5 +1,5 @@
error[E0271]: type mismatch resolving `<ModelT as Vehicle>::Color == Blue`
- --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:37:10
+ --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:31:10
|
LL | fn b() { blue_car(ModelT); }
| ^^^^^^^^ expected struct `Black`, found struct `Blue`
@@ -7,13 +7,13 @@
= note: expected type `Black`
found type `Blue`
note: required by `blue_car`
- --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:33:1
+ --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:27:1
|
LL | fn blue_car<C:Car<Color=Blue>>(c: C) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0271]: type mismatch resolving `<ModelU as Vehicle>::Color == Black`
- --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:38:10
+ --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:32:10
|
LL | fn c() { black_car(ModelU); }
| ^^^^^^^^^ expected struct `Blue`, found struct `Black`
@@ -21,7 +21,7 @@
= note: expected type `Blue`
found type `Black`
note: required by `black_car`
- --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:30:1
+ --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:24:1
|
LL | fn black_car<C:Car<Color=Black>>(c: C) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/associated-types/associated-types-ref-from-struct.rs b/src/test/ui/associated-types/associated-types-ref-from-struct.rs
index 3ccba28..c89f604 100644
--- a/src/test/ui/associated-types/associated-types-ref-from-struct.rs
+++ b/src/test/ui/associated-types/associated-types-ref-from-struct.rs
@@ -9,8 +9,6 @@
fn test(&self, value: &Self::V) -> bool;
}
-///////////////////////////////////////////////////////////////////////////
-
struct TesterPair<T:Test> {
tester: T,
value: T::V,
@@ -26,8 +24,6 @@
}
}
-///////////////////////////////////////////////////////////////////////////
-
struct EqU32(u32);
impl Test for EqU32 {
type V = u32;
diff --git a/src/test/ui/derives/derive-hygiene.rs b/src/test/ui/derives/derive-hygiene.rs
new file mode 100644
index 0000000..4fa83c4
--- /dev/null
+++ b/src/test/ui/derives/derive-hygiene.rs
@@ -0,0 +1,121 @@
+// Make sure that built-in derives don't rely on the user not declaring certain
+// names to work properly.
+
+// check-pass
+
+#![allow(nonstandard_style)]
+#![feature(decl_macro)]
+
+use std::prelude::v1::test as inline;
+
+static f: () = ();
+static cmp: () = ();
+static other: () = ();
+static state: () = ();
+static __self_0_0: () = ();
+static __self_1_0: () = ();
+static __self_vi: () = ();
+static __arg_1_0: () = ();
+static debug_trait_builder: () = ();
+
+struct isize;
+trait i16 {}
+
+trait MethodsInDerives: Sized {
+ fn debug_tuple(self) {}
+ fn debug_struct(self) {}
+ fn field(self) {}
+ fn finish(self) {}
+ fn clone(self) {}
+ fn cmp(self) {}
+ fn partial_cmp(self) {}
+ fn eq(self) {}
+ fn ne(self) {}
+ fn le(self) {}
+ fn lt(self) {}
+ fn ge(self) {}
+ fn gt(self) {}
+ fn hash(self) {}
+}
+
+trait GenericAny<T, U> {}
+impl<S, T, U> GenericAny<T, U> for S {}
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+enum __H { V(i32), }
+
+#[repr(i16)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+enum W { A, B }
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
+struct X<A: GenericAny<A, self::X<i32>>> {
+ A: A,
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
+struct Y<B>(B)
+where
+ B: From<B>;
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+enum Z<C> {
+ C(C),
+ B { C: C },
+}
+
+// Make sure that we aren't using `self::` in paths, since it doesn't work in
+// non-module scopes.
+const NON_MODULE: () = {
+ #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+ enum __H { V(i32), }
+
+ #[repr(i16)]
+ #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+ enum W { A, B }
+
+ #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
+ struct X<A: Fn(A) -> self::X<i32>> {
+ A: A,
+ }
+
+ #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
+ struct Y<B>(B)
+ where
+ B: From<B>;
+
+ #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+ enum Z<C> {
+ C(C),
+ B { C: C },
+ }
+};
+
+macro m() {
+ #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+ enum __H { V(i32), }
+
+ #[repr(i16)]
+ #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+ enum W { A, B }
+
+ #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
+ struct X<A: GenericAny<A, self::X<i32>>> {
+ A: A,
+ }
+
+ #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
+ struct Y<B>(B)
+ where
+ B: From<B>;
+
+ #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+ enum Z<C> {
+ C(C),
+ B { C: C },
+ }
+}
+
+m!();
+
+fn main() {}
diff --git a/src/test/ui/duplicate/duplicate-type-parameter.stderr b/src/test/ui/duplicate/duplicate-type-parameter.stderr
index 8606479..6754574 100644
--- a/src/test/ui/duplicate/duplicate-type-parameter.stderr
+++ b/src/test/ui/duplicate/duplicate-type-parameter.stderr
@@ -1,4 +1,4 @@
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
--> $DIR/duplicate-type-parameter.rs:1:12
|
LL | type Foo<T,T> = Option<T>;
@@ -6,7 +6,7 @@
| |
| first use of `T`
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
--> $DIR/duplicate-type-parameter.rs:4:14
|
LL | struct Bar<T,T>(T);
@@ -14,7 +14,7 @@
| |
| first use of `T`
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
--> $DIR/duplicate-type-parameter.rs:7:14
|
LL | struct Baz<T,T> {
@@ -22,7 +22,7 @@
| |
| first use of `T`
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
--> $DIR/duplicate-type-parameter.rs:12:12
|
LL | enum Boo<T,T> {
@@ -30,7 +30,7 @@
| |
| first use of `T`
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
--> $DIR/duplicate-type-parameter.rs:18:11
|
LL | fn quux<T,T>(x: T) {}
@@ -38,7 +38,7 @@
| |
| first use of `T`
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
--> $DIR/duplicate-type-parameter.rs:21:13
|
LL | trait Qux<T,T> {}
@@ -46,7 +46,7 @@
| |
| first use of `T`
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
--> $DIR/duplicate-type-parameter.rs:24:8
|
LL | impl<T,T> Qux<T,T> for Option<T> {}
diff --git a/src/test/ui/error-codes/E0194.rs b/src/test/ui/error-codes/E0194.rs
index 71eff0e..8a43f38 100644
--- a/src/test/ui/error-codes/E0194.rs
+++ b/src/test/ui/error-codes/E0194.rs
@@ -1,7 +1,7 @@
trait Foo<T> {
fn do_something(&self) -> T;
fn do_something_else<T: Clone>(&self, bar: T);
- //~^ ERROR E0194
+ //~^ ERROR E0403
}
fn main() {
diff --git a/src/test/ui/error-codes/E0194.stderr b/src/test/ui/error-codes/E0194.stderr
index ab4918a..f2c908e 100644
--- a/src/test/ui/error-codes/E0194.stderr
+++ b/src/test/ui/error-codes/E0194.stderr
@@ -1,12 +1,12 @@
-error[E0194]: type parameter `T` shadows another type parameter of the same name
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
--> $DIR/E0194.rs:3:26
|
LL | trait Foo<T> {
- | - first `T` declared here
+ | - first use of `T`
LL | fn do_something(&self) -> T;
LL | fn do_something_else<T: Clone>(&self, bar: T);
- | ^ shadows another type parameter
+ | ^ already used
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0194`.
+For more information about this error, try `rustc --explain E0403`.
diff --git a/src/test/ui/error-codes/E0403.stderr b/src/test/ui/error-codes/E0403.stderr
index 2bd7de6..d76a58a 100644
--- a/src/test/ui/error-codes/E0403.stderr
+++ b/src/test/ui/error-codes/E0403.stderr
@@ -1,4 +1,4 @@
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
--> $DIR/E0403.rs:1:11
|
LL | fn foo<T, T>(s: T, u: T) {}
diff --git a/src/test/ui/feature-gates/feature-gate-generators.rs b/src/test/ui/feature-gates/feature-gate-generators.rs
index cee930f..382d891 100644
--- a/src/test/ui/feature-gates/feature-gate-generators.rs
+++ b/src/test/ui/feature-gates/feature-gate-generators.rs
@@ -2,3 +2,9 @@
yield true; //~ ERROR yield syntax is experimental
//~^ ERROR yield statement outside of generator literal
}
+
+#[cfg(FALSE)]
+fn foo() {
+ yield; //~ ERROR yield syntax is experimental
+ yield 0; //~ ERROR yield syntax is experimental
+}
diff --git a/src/test/ui/feature-gates/feature-gate-generators.stderr b/src/test/ui/feature-gates/feature-gate-generators.stderr
index cdb0560..24b814b 100644
--- a/src/test/ui/feature-gates/feature-gate-generators.stderr
+++ b/src/test/ui/feature-gates/feature-gate-generators.stderr
@@ -7,12 +7,30 @@
= note: for more information, see https://github.com/rust-lang/rust/issues/43122
= help: add `#![feature(generators)]` to the crate attributes to enable
+error[E0658]: yield syntax is experimental
+ --> $DIR/feature-gate-generators.rs:8:5
+ |
+LL | yield;
+ | ^^^^^
+ |
+ = note: for more information, see https://github.com/rust-lang/rust/issues/43122
+ = help: add `#![feature(generators)]` to the crate attributes to enable
+
+error[E0658]: yield syntax is experimental
+ --> $DIR/feature-gate-generators.rs:9:5
+ |
+LL | yield 0;
+ | ^^^^^^^
+ |
+ = note: for more information, see https://github.com/rust-lang/rust/issues/43122
+ = help: add `#![feature(generators)]` to the crate attributes to enable
+
error[E0627]: yield statement outside of generator literal
--> $DIR/feature-gate-generators.rs:2:5
|
LL | yield true;
| ^^^^^^^^^^
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs
index a8f3818..88d3961 100644
--- a/src/test/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs
@@ -14,7 +14,6 @@
{
}
-///////////////////////////////////////////////////////////////////////////
// Expressed as a where clause
struct SomeStruct<X> {
@@ -30,7 +29,6 @@
want_foo::<SomeStruct<usize>>();
}
-///////////////////////////////////////////////////////////////////////////
// Expressed as shorthand
struct AnotherStruct<X> {
diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.rs b/src/test/ui/hrtb/hrtb-conflate-regions.rs
index 3913036..004d62a 100644
--- a/src/test/ui/hrtb/hrtb-conflate-regions.rs
+++ b/src/test/ui/hrtb/hrtb-conflate-regions.rs
@@ -15,7 +15,6 @@
{
}
-///////////////////////////////////////////////////////////////////////////
// Expressed as a where clause
struct SomeStruct;
diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.stderr b/src/test/ui/hrtb/hrtb-conflate-regions.stderr
index 3fb6baa..20265d6 100644
--- a/src/test/ui/hrtb/hrtb-conflate-regions.stderr
+++ b/src/test/ui/hrtb/hrtb-conflate-regions.stderr
@@ -1,5 +1,5 @@
error[E0277]: the trait bound `for<'a, 'b> SomeStruct: Foo<(&'a isize, &'b isize)>` is not satisfied
- --> $DIR/hrtb-conflate-regions.rs:28:10
+ --> $DIR/hrtb-conflate-regions.rs:27:10
|
LL | fn b() { want_foo2::<SomeStruct>(); }
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a, 'b> Foo<(&'a isize, &'b isize)>` is not implemented for `SomeStruct`
diff --git a/src/test/ui/hygiene/auxiliary/codegen-attrs.rs b/src/test/ui/hygiene/auxiliary/codegen-attrs.rs
new file mode 100644
index 0000000..74afedb
--- /dev/null
+++ b/src/test/ui/hygiene/auxiliary/codegen-attrs.rs
@@ -0,0 +1,10 @@
+#![feature(decl_macro)]
+
+macro m($f:ident) {
+ #[export_name = "export_function_name"]
+ pub fn $f() -> i32 {
+ 2
+ }
+}
+
+m!(rust_function_name);
diff --git a/src/test/ui/hygiene/cross-crate-codegen-attrs.rs b/src/test/ui/hygiene/cross-crate-codegen-attrs.rs
new file mode 100644
index 0000000..af6b133
--- /dev/null
+++ b/src/test/ui/hygiene/cross-crate-codegen-attrs.rs
@@ -0,0 +1,12 @@
+// Make sure that macro expanded codegen attributes work across crates.
+// We used to gensym the identifiers in attributes, which stopped dependent
+// crates from seeing them, resulting in linker errors in cases like this one.
+
+// run-pass
+// aux-build:codegen-attrs.rs
+
+extern crate codegen_attrs;
+
+fn main() {
+ assert_eq!(codegen_attrs::rust_function_name(), 2);
+}
diff --git a/src/test/ui/impl-trait/bound-normalization-fail.rs b/src/test/ui/impl-trait/bound-normalization-fail.rs
index 9ba7c91..ce15505 100644
--- a/src/test/ui/impl-trait/bound-normalization-fail.rs
+++ b/src/test/ui/impl-trait/bound-normalization-fail.rs
@@ -8,7 +8,6 @@
// See issue 60414
-/////////////////////////////////////////////
// Reduction to `impl Trait`
struct Foo<T>(T);
@@ -33,7 +32,6 @@
}
}
-/////////////////////////////////////////////
// Same with lifetimes in the trait
mod lifetimes {
diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr
index b5c8e07..4811b1e 100644
--- a/src/test/ui/impl-trait/bound-normalization-fail.stderr
+++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr
@@ -7,7 +7,7 @@
= note: `#[warn(incomplete_features)]` on by default
error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc`
- --> $DIR/bound-normalization-fail.rs:30:32
+ --> $DIR/bound-normalization-fail.rs:29:32
|
LL | fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found associated type
@@ -17,13 +17,13 @@
= note: the return type of a function must have a statically known size
error: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
- --> $DIR/bound-normalization-fail.rs:47:41
+ --> $DIR/bound-normalization-fail.rs:45:41
|
LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc`
- --> $DIR/bound-normalization-fail.rs:47:41
+ --> $DIR/bound-normalization-fail.rs:45:41
|
LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found associated type
diff --git a/src/test/ui/impl-trait/bound-normalization-pass.rs b/src/test/ui/impl-trait/bound-normalization-pass.rs
index 5b634e3..b0ed4be 100644
--- a/src/test/ui/impl-trait/bound-normalization-pass.rs
+++ b/src/test/ui/impl-trait/bound-normalization-pass.rs
@@ -8,7 +8,6 @@
// See issue 60414
-/////////////////////////////////////////////
// Reduction to `impl Trait`
struct Foo<T>(T);
@@ -32,7 +31,6 @@
}
}
-/////////////////////////////////////////////
// Same with lifetimes in the trait
mod lifetimes {
@@ -59,7 +57,6 @@
}
}
-/////////////////////////////////////////////
// Reduction using `impl Trait` in bindings
mod impl_trait_in_bindings {
@@ -80,7 +77,6 @@
}
}
-/////////////////////////////////////////////
// The same applied to `type Foo = impl Bar`s
mod opaque_types {
diff --git a/src/test/ui/issues/issue-12028.rs b/src/test/ui/issues/issue-12028.rs
index d553545..7c2b0d6 100644
--- a/src/test/ui/issues/issue-12028.rs
+++ b/src/test/ui/issues/issue-12028.rs
@@ -17,8 +17,6 @@
fn stream(&self) -> Self::S;
}
-//////////////////////////////////////////////////////////////////////////////
-
trait StreamHash<H: StreamHasher>: Hash<H> {
fn input_stream(&self, stream: &mut H::S);
}
diff --git a/src/test/ui/issues/issue-12028.stderr b/src/test/ui/issues/issue-12028.stderr
index 64694c7..24aa88c 100644
--- a/src/test/ui/issues/issue-12028.stderr
+++ b/src/test/ui/issues/issue-12028.stderr
@@ -1,5 +1,5 @@
error[E0284]: type annotations required: cannot resolve `<_ as StreamHasher>::S == <H as StreamHasher>::S`
- --> $DIR/issue-12028.rs:29:14
+ --> $DIR/issue-12028.rs:27:14
|
LL | self.input_stream(&mut stream);
| ^^^^^^^^^^^^
diff --git a/src/test/ui/issues/issue-16739.rs b/src/test/ui/issues/issue-16739.rs
index 54ad8fd..94da2ca 100644
--- a/src/test/ui/issues/issue-16739.rs
+++ b/src/test/ui/issues/issue-16739.rs
@@ -16,8 +16,6 @@
extern "rust-call" fn call_once(mut self, _: ()) -> u32 { self.call_mut(()) }
}
-/////////////////////////////////////////////////////////////////////////
-
impl FnMut<(u32,)> for Foo {
extern "rust-call" fn call_mut(&mut self, (x,): (u32,)) -> u32 { self.foo + x }
}
@@ -27,8 +25,6 @@
extern "rust-call" fn call_once(mut self, args: (u32,)) -> u32 { self.call_mut(args) }
}
-/////////////////////////////////////////////////////////////////////////
-
impl FnMut<(u32,u32)> for Foo {
extern "rust-call" fn call_mut(&mut self, (x, y): (u32, u32)) -> u32 { self.foo + x + y }
}
diff --git a/src/test/ui/methods/method-projection.rs b/src/test/ui/methods/method-projection.rs
index cf33d53..21d983f 100644
--- a/src/test/ui/methods/method-projection.rs
+++ b/src/test/ui/methods/method-projection.rs
@@ -2,9 +2,6 @@
// Test that we can use method notation to call methods based on a
// projection bound from a trait. Issue #20469.
-///////////////////////////////////////////////////////////////////////////
-
-
trait MakeString {
fn make_string(&self) -> String;
}
@@ -21,8 +18,6 @@
}
}
-///////////////////////////////////////////////////////////////////////////
-
trait Foo {
type F: MakeString;
@@ -33,8 +28,6 @@
f.get().make_string()
}
-///////////////////////////////////////////////////////////////////////////
-
struct SomeStruct {
field: isize,
}
@@ -47,8 +40,6 @@
}
}
-///////////////////////////////////////////////////////////////////////////
-
struct SomeOtherStruct {
field: usize,
}
diff --git a/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.nll.stderr b/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.nll.stderr
index 5028663..eed9934 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.nll.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.nll.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/regions-outlives-projection-container-hrtb.rs:35:12
+ --> $DIR/regions-outlives-projection-container-hrtb.rs:30:12
|
LL | fn with_assoc<'a,'b>() {
| -- -- lifetime `'b` defined here
@@ -10,7 +10,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
error: lifetime may not live long enough
- --> $DIR/regions-outlives-projection-container-hrtb.rs:57:12
+ --> $DIR/regions-outlives-projection-container-hrtb.rs:50:12
|
LL | fn with_assoc_sub<'a,'b>() {
| -- -- lifetime `'b` defined here
diff --git a/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.stderr b/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.stderr
index d833018..ed58009 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.stderr
@@ -1,33 +1,33 @@
error[E0491]: in type `&'a WithHrAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
- --> $DIR/regions-outlives-projection-container-hrtb.rs:35:12
+ --> $DIR/regions-outlives-projection-container-hrtb.rs:30:12
|
LL | let _: &'a WithHrAssoc<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the function body at 32:15
- --> $DIR/regions-outlives-projection-container-hrtb.rs:32:15
+note: the pointer is valid for the lifetime 'a as defined on the function body at 27:15
+ --> $DIR/regions-outlives-projection-container-hrtb.rs:27:15
|
LL | fn with_assoc<'a,'b>() {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 32:18
- --> $DIR/regions-outlives-projection-container-hrtb.rs:32:18
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 27:18
+ --> $DIR/regions-outlives-projection-container-hrtb.rs:27:18
|
LL | fn with_assoc<'a,'b>() {
| ^^
error[E0491]: in type `&'a WithHrAssocSub<TheType<'b>>`, reference has a longer lifetime than the data it references
- --> $DIR/regions-outlives-projection-container-hrtb.rs:57:12
+ --> $DIR/regions-outlives-projection-container-hrtb.rs:50:12
|
LL | let _: &'a WithHrAssocSub<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the function body at 53:19
- --> $DIR/regions-outlives-projection-container-hrtb.rs:53:19
+note: the pointer is valid for the lifetime 'a as defined on the function body at 46:19
+ --> $DIR/regions-outlives-projection-container-hrtb.rs:46:19
|
LL | fn with_assoc_sub<'a,'b>() {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 53:22
- --> $DIR/regions-outlives-projection-container-hrtb.rs:53:22
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 46:22
+ --> $DIR/regions-outlives-projection-container-hrtb.rs:46:22
|
LL | fn with_assoc_sub<'a,'b>() {
| ^^
diff --git a/src/test/ui/regions/regions-outlives-projection-container-hrtb.nll.stderr b/src/test/ui/regions/regions-outlives-projection-container-hrtb.nll.stderr
index 5028663..eed9934 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-hrtb.nll.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container-hrtb.nll.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/regions-outlives-projection-container-hrtb.rs:35:12
+ --> $DIR/regions-outlives-projection-container-hrtb.rs:30:12
|
LL | fn with_assoc<'a,'b>() {
| -- -- lifetime `'b` defined here
@@ -10,7 +10,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
error: lifetime may not live long enough
- --> $DIR/regions-outlives-projection-container-hrtb.rs:57:12
+ --> $DIR/regions-outlives-projection-container-hrtb.rs:50:12
|
LL | fn with_assoc_sub<'a,'b>() {
| -- -- lifetime `'b` defined here
diff --git a/src/test/ui/regions/regions-outlives-projection-container-hrtb.rs b/src/test/ui/regions/regions-outlives-projection-container-hrtb.rs
index 407a4fd..cee7411 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-hrtb.rs
+++ b/src/test/ui/regions/regions-outlives-projection-container-hrtb.rs
@@ -6,9 +6,6 @@
#![allow(dead_code)]
-
-///////////////////////////////////////////////////////////////////////////
-
pub trait TheTrait<'b> {
type TheAssocType;
}
@@ -21,8 +18,6 @@
type TheAssocType = &'b ();
}
-///////////////////////////////////////////////////////////////////////////
-
pub struct WithHrAssoc<T>
where for<'a> T : TheTrait<'a>
{
@@ -37,8 +32,6 @@
//[nll]~^^ ERROR lifetime may not live long enough
}
-///////////////////////////////////////////////////////////////////////////
-
pub trait TheSubTrait : for<'a> TheTrait<'a> {
}
diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.nll.stderr b/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.nll.stderr
index 880fe17..8c54d8d 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.nll.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.nll.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/regions-outlives-projection-container-wc.rs:37:12
+ --> $DIR/regions-outlives-projection-container-wc.rs:33:12
|
LL | fn with_assoc<'a,'b>() {
| -- -- lifetime `'b` defined here
diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.stderr b/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.stderr
index 9e31065..152e6c5 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.stderr
@@ -1,16 +1,16 @@
error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
- --> $DIR/regions-outlives-projection-container-wc.rs:37:12
+ --> $DIR/regions-outlives-projection-container-wc.rs:33:12
|
LL | let _: &'a WithAssoc<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the function body at 31:15
- --> $DIR/regions-outlives-projection-container-wc.rs:31:15
+note: the pointer is valid for the lifetime 'a as defined on the function body at 27:15
+ --> $DIR/regions-outlives-projection-container-wc.rs:27:15
|
LL | fn with_assoc<'a,'b>() {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 31:18
- --> $DIR/regions-outlives-projection-container-wc.rs:31:18
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 27:18
+ --> $DIR/regions-outlives-projection-container-wc.rs:27:18
|
LL | fn with_assoc<'a,'b>() {
| ^^
diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr b/src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr
index 880fe17..8c54d8d 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/regions-outlives-projection-container-wc.rs:37:12
+ --> $DIR/regions-outlives-projection-container-wc.rs:33:12
|
LL | fn with_assoc<'a,'b>() {
| -- -- lifetime `'b` defined here
diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.rs b/src/test/ui/regions/regions-outlives-projection-container-wc.rs
index 5037ea5..99965f3 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-wc.rs
+++ b/src/test/ui/regions/regions-outlives-projection-container-wc.rs
@@ -8,8 +8,6 @@
#![allow(dead_code)]
-///////////////////////////////////////////////////////////////////////////
-
pub trait TheTrait {
type TheAssocType;
}
@@ -22,8 +20,6 @@
type TheAssocType = &'b ();
}
-///////////////////////////////////////////////////////////////////////////
-
pub struct WithAssoc<T> where T : TheTrait {
m: [T; 0]
}
diff --git a/src/test/ui/regions/regions-outlives-projection-container.nll.stderr b/src/test/ui/regions/regions-outlives-projection-container.nll.stderr
index ef87d02..2cf6e24 100644
--- a/src/test/ui/regions/regions-outlives-projection-container.nll.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container.nll.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/regions-outlives-projection-container.rs:40:13
+ --> $DIR/regions-outlives-projection-container.rs:36:13
|
LL | fn with_assoc<'a,'b>() {
| -- -- lifetime `'b` defined here
@@ -10,7 +10,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
error: lifetime may not live long enough
- --> $DIR/regions-outlives-projection-container.rs:58:13
+ --> $DIR/regions-outlives-projection-container.rs:54:13
|
LL | fn without_assoc<'a,'b>() {
| -- -- lifetime `'b` defined here
@@ -21,7 +21,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
error: lifetime may not live long enough
- --> $DIR/regions-outlives-projection-container.rs:67:5
+ --> $DIR/regions-outlives-projection-container.rs:63:5
|
LL | fn call_with_assoc<'a,'b>() {
| -- -- lifetime `'b` defined here
@@ -32,7 +32,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
error: lifetime may not live long enough
- --> $DIR/regions-outlives-projection-container.rs:74:5
+ --> $DIR/regions-outlives-projection-container.rs:70:5
|
LL | fn call_without_assoc<'a,'b>() {
| -- -- lifetime `'b` defined here
diff --git a/src/test/ui/regions/regions-outlives-projection-container.rs b/src/test/ui/regions/regions-outlives-projection-container.rs
index 78305c0..3afc600 100644
--- a/src/test/ui/regions/regions-outlives-projection-container.rs
+++ b/src/test/ui/regions/regions-outlives-projection-container.rs
@@ -5,8 +5,6 @@
#![allow(dead_code)]
#![feature(rustc_attrs)]
-///////////////////////////////////////////////////////////////////////////
-
pub trait TheTrait {
type TheAssocType;
}
@@ -19,8 +17,6 @@
type TheAssocType = &'b ();
}
-///////////////////////////////////////////////////////////////////////////
-
pub struct WithAssoc<T:TheTrait> {
m: [T; 0]
}
diff --git a/src/test/ui/regions/regions-outlives-projection-container.stderr b/src/test/ui/regions/regions-outlives-projection-container.stderr
index b50347a..3c1a98a 100644
--- a/src/test/ui/regions/regions-outlives-projection-container.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container.stderr
@@ -1,67 +1,67 @@
error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
- --> $DIR/regions-outlives-projection-container.rs:40:13
+ --> $DIR/regions-outlives-projection-container.rs:36:13
|
LL | let _x: &'a WithAssoc<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the function body at 32:15
- --> $DIR/regions-outlives-projection-container.rs:32:15
+note: the pointer is valid for the lifetime 'a as defined on the function body at 28:15
+ --> $DIR/regions-outlives-projection-container.rs:28:15
|
LL | fn with_assoc<'a,'b>() {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 32:18
- --> $DIR/regions-outlives-projection-container.rs:32:18
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 28:18
+ --> $DIR/regions-outlives-projection-container.rs:28:18
|
LL | fn with_assoc<'a,'b>() {
| ^^
error[E0491]: in type `&'a WithoutAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
- --> $DIR/regions-outlives-projection-container.rs:58:13
+ --> $DIR/regions-outlives-projection-container.rs:54:13
|
LL | let _x: &'a WithoutAssoc<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the function body at 54:18
- --> $DIR/regions-outlives-projection-container.rs:54:18
+note: the pointer is valid for the lifetime 'a as defined on the function body at 50:18
+ --> $DIR/regions-outlives-projection-container.rs:50:18
|
LL | fn without_assoc<'a,'b>() {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 54:21
- --> $DIR/regions-outlives-projection-container.rs:54:21
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 50:21
+ --> $DIR/regions-outlives-projection-container.rs:50:21
|
LL | fn without_assoc<'a,'b>() {
| ^^
error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
- --> $DIR/regions-outlives-projection-container.rs:67:12
+ --> $DIR/regions-outlives-projection-container.rs:63:12
|
LL | call::<&'a WithAssoc<TheType<'b>>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the function body at 62:20
- --> $DIR/regions-outlives-projection-container.rs:62:20
+note: the pointer is valid for the lifetime 'a as defined on the function body at 58:20
+ --> $DIR/regions-outlives-projection-container.rs:58:20
|
LL | fn call_with_assoc<'a,'b>() {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 62:23
- --> $DIR/regions-outlives-projection-container.rs:62:23
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 58:23
+ --> $DIR/regions-outlives-projection-container.rs:58:23
|
LL | fn call_with_assoc<'a,'b>() {
| ^^
error[E0491]: in type `&'a WithoutAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
- --> $DIR/regions-outlives-projection-container.rs:74:12
+ --> $DIR/regions-outlives-projection-container.rs:70:12
|
LL | call::<&'a WithoutAssoc<TheType<'b>>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the function body at 71:23
- --> $DIR/regions-outlives-projection-container.rs:71:23
+note: the pointer is valid for the lifetime 'a as defined on the function body at 67:23
+ --> $DIR/regions-outlives-projection-container.rs:67:23
|
LL | fn call_without_assoc<'a,'b>() {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 71:26
- --> $DIR/regions-outlives-projection-container.rs:71:26
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 67:26
+ --> $DIR/regions-outlives-projection-container.rs:67:26
|
LL | fn call_without_assoc<'a,'b>() {
| ^^
diff --git a/src/test/ui/rfc1598-generic-associated-types/shadowing.rs b/src/test/ui/rfc1598-generic-associated-types/shadowing.rs
index 0349263..f5197fd 100644
--- a/src/test/ui/rfc1598-generic-associated-types/shadowing.rs
+++ b/src/test/ui/rfc1598-generic-associated-types/shadowing.rs
@@ -1,12 +1,9 @@
+#![allow(incomplete_features)]
#![feature(generic_associated_types)]
-//FIXME(#44265): The lifetime shadowing and type parameter shadowing
-// should cause an error. Now it compiles (erroneously) and this will be addressed
-// by a future PR. Then remove the following:
-// build-pass (FIXME(62277): could be check-pass?)
-
trait Shadow<'a> {
- type Bar<'a>; // Error: shadowed lifetime
+ //FIXME(#44265): The lifetime parameter shadowing should cause an error.
+ type Bar<'a>;
}
trait NoShadow<'a> {
@@ -14,11 +11,12 @@
}
impl<'a> NoShadow<'a> for &'a u32 {
- type Bar<'a> = i32; // Error: shadowed lifetime
+ //FIXME(#44265): The lifetime parameter shadowing should cause an error.
+ type Bar<'a> = i32;
}
trait ShadowT<T> {
- type Bar<T>; // Error: shadowed type parameter
+ type Bar<T>; //~ ERROR the name `T` is already used
}
trait NoShadowT<T> {
@@ -26,7 +24,7 @@
}
impl<T> NoShadowT<T> for Option<T> {
- type Bar<T> = i32; // Error: shadowed type parameter
+ type Bar<T> = i32; //~ ERROR the name `T` is already used
}
fn main() {}
diff --git a/src/test/ui/rfc1598-generic-associated-types/shadowing.stderr b/src/test/ui/rfc1598-generic-associated-types/shadowing.stderr
index 9526df2..a06c635 100644
--- a/src/test/ui/rfc1598-generic-associated-types/shadowing.stderr
+++ b/src/test/ui/rfc1598-generic-associated-types/shadowing.stderr
@@ -1,8 +1,19 @@
-warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash
- --> $DIR/shadowing.rs:1:12
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
+ --> $DIR/shadowing.rs:19:14
|
-LL | #![feature(generic_associated_types)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
+LL | trait ShadowT<T> {
+ | - first use of `T`
+LL | type Bar<T>;
+ | ^ already used
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
+ --> $DIR/shadowing.rs:27:14
+ |
+LL | impl<T> NoShadowT<T> for Option<T> {
+ | - first use of `T`
+LL | type Bar<T> = i32;
+ | ^ already used
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0403`.
diff --git a/src/test/ui/shadowed/shadowed-type-parameter.rs b/src/test/ui/shadowed/shadowed-type-parameter.rs
index ba9f3ab..e74620f 100644
--- a/src/test/ui/shadowed/shadowed-type-parameter.rs
+++ b/src/test/ui/shadowed/shadowed-type-parameter.rs
@@ -6,7 +6,7 @@
impl<T> Foo<T> {
fn shadow_in_method<T>(&self) {}
- //~^ ERROR type parameter `T` shadows another type parameter
+ //~^ ERROR the name `T` is already used
fn not_shadow_in_item<U>(&self) {
struct Bar<T, U>(T,U); // not a shadow, separate item
@@ -18,10 +18,10 @@
fn dummy(&self) -> T;
fn shadow_in_required<T>(&self);
- //~^ ERROR type parameter `T` shadows another type parameter
+ //~^ ERROR the name `T` is already used
fn shadow_in_provided<T>(&self) {}
- //~^ ERROR type parameter `T` shadows another type parameter
+ //~^ ERROR the name `T` is already used
fn not_shadow_in_required<U>(&self);
fn not_shadow_in_provided<U>(&self) {}
diff --git a/src/test/ui/shadowed/shadowed-type-parameter.stderr b/src/test/ui/shadowed/shadowed-type-parameter.stderr
index 6b4d1fa..0ea82f9 100644
--- a/src/test/ui/shadowed/shadowed-type-parameter.stderr
+++ b/src/test/ui/shadowed/shadowed-type-parameter.stderr
@@ -1,29 +1,29 @@
-error[E0194]: type parameter `T` shadows another type parameter of the same name
- --> $DIR/shadowed-type-parameter.rs:20:27
- |
-LL | trait Bar<T> {
- | - first `T` declared here
-...
-LL | fn shadow_in_required<T>(&self);
- | ^ shadows another type parameter
-
-error[E0194]: type parameter `T` shadows another type parameter of the same name
- --> $DIR/shadowed-type-parameter.rs:23:27
- |
-LL | trait Bar<T> {
- | - first `T` declared here
-...
-LL | fn shadow_in_provided<T>(&self) {}
- | ^ shadows another type parameter
-
-error[E0194]: type parameter `T` shadows another type parameter of the same name
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
--> $DIR/shadowed-type-parameter.rs:8:25
|
LL | impl<T> Foo<T> {
- | - first `T` declared here
+ | - first use of `T`
LL | fn shadow_in_method<T>(&self) {}
- | ^ shadows another type parameter
+ | ^ already used
+
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
+ --> $DIR/shadowed-type-parameter.rs:20:27
+ |
+LL | trait Bar<T> {
+ | - first use of `T`
+...
+LL | fn shadow_in_required<T>(&self);
+ | ^ already used
+
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
+ --> $DIR/shadowed-type-parameter.rs:23:27
+ |
+LL | trait Bar<T> {
+ | - first use of `T`
+...
+LL | fn shadow_in_provided<T>(&self) {}
+ | ^ already used
error: aborting due to 3 previous errors
-For more information about this error, try `rustc --explain E0194`.
+For more information about this error, try `rustc --explain E0403`.
diff --git a/src/test/ui/specialization/defaultimpl/specialization-no-default.rs b/src/test/ui/specialization/defaultimpl/specialization-no-default.rs
index 7ea79a9..37005f83 100644
--- a/src/test/ui/specialization/defaultimpl/specialization-no-default.rs
+++ b/src/test/ui/specialization/defaultimpl/specialization-no-default.rs
@@ -3,9 +3,7 @@
// Check a number of scenarios in which one impl tries to override another,
// without correctly using `default`.
-////////////////////////////////////////////////////////////////////////////////
// Test 1: one layer of specialization, multiple methods, missing `default`
-////////////////////////////////////////////////////////////////////////////////
trait Foo {
fn foo(&self);
@@ -25,9 +23,7 @@
fn bar(&self) {} //~ ERROR E0520
}
-////////////////////////////////////////////////////////////////////////////////
// Test 2: one layer of specialization, missing `default` on associated type
-////////////////////////////////////////////////////////////////////////////////
trait Bar {
type T;
@@ -41,9 +37,7 @@
type T = (); //~ ERROR E0520
}
-////////////////////////////////////////////////////////////////////////////////
// Test 3a: multiple layers of specialization, missing interior `default`
-////////////////////////////////////////////////////////////////////////////////
trait Baz {
fn baz(&self);
@@ -61,10 +55,8 @@
fn baz(&self) {} //~ ERROR E0520
}
-////////////////////////////////////////////////////////////////////////////////
// Test 3b: multiple layers of specialization, missing interior `default`,
// redundant `default` in bottom layer.
-////////////////////////////////////////////////////////////////////////////////
trait Redundant {
fn redundant(&self);
diff --git a/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr b/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr
index 91690f6..13636b2 100644
--- a/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr
+++ b/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr
@@ -1,5 +1,5 @@
error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
- --> $DIR/specialization-no-default.rs:22:5
+ --> $DIR/specialization-no-default.rs:20:5
|
LL | / impl<T> Foo for T {
LL | | fn foo(&self) {}
@@ -13,7 +13,7 @@
= note: to specialize, `foo` in the parent `impl` must be marked `default`
error[E0520]: `bar` specializes an item from a parent `impl`, but that item is not marked `default`
- --> $DIR/specialization-no-default.rs:25:5
+ --> $DIR/specialization-no-default.rs:23:5
|
LL | / impl<T> Foo for T {
LL | | fn foo(&self) {}
@@ -27,7 +27,7 @@
= note: to specialize, `bar` in the parent `impl` must be marked `default`
error[E0520]: `T` specializes an item from a parent `impl`, but that item is not marked `default`
- --> $DIR/specialization-no-default.rs:41:5
+ --> $DIR/specialization-no-default.rs:37:5
|
LL | / impl<T> Bar for T {
LL | | type T = u8;
@@ -40,7 +40,7 @@
= note: to specialize, `T` in the parent `impl` must be marked `default`
error[E0520]: `baz` specializes an item from a parent `impl`, but that item is not marked `default`
- --> $DIR/specialization-no-default.rs:61:5
+ --> $DIR/specialization-no-default.rs:55:5
|
LL | / impl<T: Clone> Baz for T {
LL | | fn baz(&self) {}
@@ -53,7 +53,7 @@
= note: to specialize, `baz` in the parent `impl` must be marked `default`
error[E0520]: `redundant` specializes an item from a parent `impl`, but that item is not marked `default`
- --> $DIR/specialization-no-default.rs:82:5
+ --> $DIR/specialization-no-default.rs:74:5
|
LL | / impl<T: Clone> Redundant for T {
LL | | fn redundant(&self) {}
diff --git a/src/test/ui/specialization/specialization-no-default.rs b/src/test/ui/specialization/specialization-no-default.rs
index 29afbbd9..57346b2 100644
--- a/src/test/ui/specialization/specialization-no-default.rs
+++ b/src/test/ui/specialization/specialization-no-default.rs
@@ -3,9 +3,7 @@
// Check a number of scenarios in which one impl tries to override another,
// without correctly using `default`.
-////////////////////////////////////////////////////////////////////////////////
// Test 1: one layer of specialization, multiple methods, missing `default`
-////////////////////////////////////////////////////////////////////////////////
trait Foo {
fn foo(&self);
@@ -25,9 +23,7 @@
fn bar(&self) {} //~ ERROR E0520
}
-////////////////////////////////////////////////////////////////////////////////
// Test 2: one layer of specialization, missing `default` on associated type
-////////////////////////////////////////////////////////////////////////////////
trait Bar {
type T;
@@ -41,9 +37,7 @@
type T = (); //~ ERROR E0520
}
-////////////////////////////////////////////////////////////////////////////////
// Test 3a: multiple layers of specialization, missing interior `default`
-////////////////////////////////////////////////////////////////////////////////
trait Baz {
fn baz(&self);
@@ -61,10 +55,8 @@
fn baz(&self) {} //~ ERROR E0520
}
-////////////////////////////////////////////////////////////////////////////////
// Test 3b: multiple layers of specialization, missing interior `default`,
// redundant `default` in bottom layer.
-////////////////////////////////////////////////////////////////////////////////
trait Redundant {
fn redundant(&self);
diff --git a/src/test/ui/specialization/specialization-no-default.stderr b/src/test/ui/specialization/specialization-no-default.stderr
index c39986d..992e9ab 100644
--- a/src/test/ui/specialization/specialization-no-default.stderr
+++ b/src/test/ui/specialization/specialization-no-default.stderr
@@ -1,5 +1,5 @@
error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
- --> $DIR/specialization-no-default.rs:22:5
+ --> $DIR/specialization-no-default.rs:20:5
|
LL | / impl<T> Foo for T {
LL | | fn foo(&self) {}
@@ -13,7 +13,7 @@
= note: to specialize, `foo` in the parent `impl` must be marked `default`
error[E0520]: `bar` specializes an item from a parent `impl`, but that item is not marked `default`
- --> $DIR/specialization-no-default.rs:25:5
+ --> $DIR/specialization-no-default.rs:23:5
|
LL | / impl<T> Foo for T {
LL | | fn foo(&self) {}
@@ -27,7 +27,7 @@
= note: to specialize, `bar` in the parent `impl` must be marked `default`
error[E0520]: `T` specializes an item from a parent `impl`, but that item is not marked `default`
- --> $DIR/specialization-no-default.rs:41:5
+ --> $DIR/specialization-no-default.rs:37:5
|
LL | / impl<T> Bar for T {
LL | | type T = u8;
@@ -40,7 +40,7 @@
= note: to specialize, `T` in the parent `impl` must be marked `default`
error[E0520]: `baz` specializes an item from a parent `impl`, but that item is not marked `default`
- --> $DIR/specialization-no-default.rs:61:5
+ --> $DIR/specialization-no-default.rs:55:5
|
LL | / impl<T: Clone> Baz for T {
LL | | fn baz(&self) {}
@@ -53,7 +53,7 @@
= note: to specialize, `baz` in the parent `impl` must be marked `default`
error[E0520]: `redundant` specializes an item from a parent `impl`, but that item is not marked `default`
- --> $DIR/specialization-no-default.rs:82:5
+ --> $DIR/specialization-no-default.rs:74:5
|
LL | / impl<T: Clone> Redundant for T {
LL | | fn redundant(&self) {}
diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs
index 52bb118..137b72d 100644
--- a/src/test/ui/symbol-names/impl1.rs
+++ b/src/test/ui/symbol-names/impl1.rs
@@ -64,9 +64,9 @@
//[legacy]~^ ERROR symbol-name(_ZN198_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$RP$$u2b$impl1..AutoTrait$u3b$$u20$_$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method
//[legacy]~| ERROR demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method
//[legacy]~| ERROR demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method)
- //[v0]~^^^^ ERROR symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG0_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method)
- //[v0]~| ERROR demangling(<[&dyn impl1[317d481089b8c8fe]::Foo<Assoc = for<'a, 'b> extern "C" fn(&'b u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method)
- //[v0]~| ERROR demangling-alt(<[&dyn impl1::Foo<Assoc = for<'a, 'b> extern "C" fn(&'b u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method)
+ //[v0]~^^^^ ERROR symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method)
+ //[v0]~| ERROR demangling(<[&dyn impl1[317d481089b8c8fe]::Foo<Assoc = for<'a> extern "C" fn(&'a u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method)
+ //[v0]~| ERROR demangling-alt(<[&dyn impl1::Foo<Assoc = for<'a> extern "C" fn(&'a u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method)
#[rustc_def_path]
//[legacy]~^ ERROR def-path(<[&dyn Foo<Assoc = for<'r> extern "C" fn(&'r u8)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method)
//[v0]~^^ ERROR def-path(<[&dyn Foo<Assoc = for<'r> extern "C" fn(&'r u8)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method)
diff --git a/src/test/ui/symbol-names/impl1.v0.stderr b/src/test/ui/symbol-names/impl1.v0.stderr
index 1c4b256..e024799 100644
--- a/src/test/ui/symbol-names/impl1.v0.stderr
+++ b/src/test/ui/symbol-names/impl1.v0.stderr
@@ -46,19 +46,19 @@
LL | #[rustc_def_path]
| ^^^^^^^^^^^^^^^^^
-error: symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG0_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method)
+error: symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method)
--> $DIR/impl1.rs:63:13
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
-error: demangling(<[&dyn impl1[317d481089b8c8fe]::Foo<Assoc = for<'a, 'b> extern "C" fn(&'b u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method)
+error: demangling(<[&dyn impl1[317d481089b8c8fe]::Foo<Assoc = for<'a> extern "C" fn(&'a u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method)
--> $DIR/impl1.rs:63:13
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
-error: demangling-alt(<[&dyn impl1::Foo<Assoc = for<'a, 'b> extern "C" fn(&'b u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method)
+error: demangling-alt(<[&dyn impl1::Foo<Assoc = for<'a> extern "C" fn(&'a u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method)
--> $DIR/impl1.rs:63:13
|
LL | #[rustc_symbol_name]
diff --git a/src/test/ui/symbol-names/issue-60925.legacy.stderr b/src/test/ui/symbol-names/issue-60925.legacy.stderr
index 7fcd2ed..de8efdd 100644
--- a/src/test/ui/symbol-names/issue-60925.legacy.stderr
+++ b/src/test/ui/symbol-names/issue-60925.legacy.stderr
@@ -4,13 +4,13 @@
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
-error: demangling(issue_60925::foo::Foo<issue_60925::llv$u6d$..Foo$GT$::foo::h059a991a004536ad)
+error: demangling(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo::h059a991a004536ad)
--> $DIR/issue-60925.rs:21:9
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
-error: demangling-alt(issue_60925::foo::Foo<issue_60925::llv$u6d$..Foo$GT$::foo)
+error: demangling-alt(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo)
--> $DIR/issue-60925.rs:21:9
|
LL | #[rustc_symbol_name]
diff --git a/src/test/ui/symbol-names/issue-60925.rs b/src/test/ui/symbol-names/issue-60925.rs
index 89de15c..0243835 100644
--- a/src/test/ui/symbol-names/issue-60925.rs
+++ b/src/test/ui/symbol-names/issue-60925.rs
@@ -20,8 +20,8 @@
impl Foo<::llvm::Foo> {
#[rustc_symbol_name]
//[legacy]~^ ERROR symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo
- //[legacy]~| ERROR demangling(issue_60925::foo::Foo<issue_60925::llv$u6d$..Foo$GT$::foo
- //[legacy]~| ERROR demangling-alt(issue_60925::foo::Foo<issue_60925::llv$u6d$..Foo$GT$::foo)
+ //[legacy]~| ERROR demangling(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo
+ //[legacy]~| ERROR demangling-alt(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo)
//[v0]~^^^^ ERROR symbol-name(_RNvMNtCs4fqI2P2rA04_11issue_609253fooINtB2_3FooNtNtB4_4llvm3FooE3foo)
//[v0]~| ERROR demangling(<issue_60925[317d481089b8c8fe]::foo::Foo<issue_60925[317d481089b8c8fe]::llvm::Foo>>::foo)
//[v0]~| ERROR demangling-alt(<issue_60925::foo::Foo<issue_60925::llvm::Foo>>::foo)
diff --git a/src/test/ui/traits/traits-conditional-model-fn.rs b/src/test/ui/traits/traits-conditional-model-fn.rs
index 27ce6d9..afdfb96 100644
--- a/src/test/ui/traits/traits-conditional-model-fn.rs
+++ b/src/test/ui/traits/traits-conditional-model-fn.rs
@@ -14,8 +14,6 @@
use std::rc::Rc;
use std::cell::Cell;
-///////////////////////////////////////////////////////////////////////////
-
struct SomeGoableThing {
counter: Rc<Cell<isize>>
}
@@ -26,8 +24,6 @@
}
}
-///////////////////////////////////////////////////////////////////////////
-
struct SomeGoOnceableThing {
counter: Rc<Cell<isize>>
}
@@ -38,8 +34,6 @@
}
}
-///////////////////////////////////////////////////////////////////////////
-
fn main() {
let counter = Rc::new(Cell::new(0));
let mut x = SomeGoableThing { counter: counter.clone() };
diff --git a/src/tools/rls b/src/tools/rls
index 7b0a20b..496c892 160000
--- a/src/tools/rls
+++ b/src/tools/rls
@@ -1 +1 @@
-Subproject commit 7b0a20bf13b7061b1eb31a058117ac5517ff8cc9
+Subproject commit 496c89275221303a4b0c2779cb8203fb3ce2a136