Auto merge of #61708 - dlrobertson:or-patterns-0, r=centril
Initial implementation of or-patterns
An incomplete implementation of or-patterns (e.g. `Some(0 | 1)` as a pattern). This patch set aims to implement initial parsing of `or-patterns`.
Related to: #54883
CC @alexreg @varkor
r? @Centril
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index da37278..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");
}
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/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/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/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/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index df9bd3a..d725afa 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -74,7 +74,7 @@
})
}
- fn visit_macro_invoc(&mut self, id: NodeId) {
+ pub fn visit_macro_invoc(&mut self, id: NodeId) {
self.definitions.set_invocation_parent(id.placeholder_to_expn_id(), self.parent_def);
}
}
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 5b15cf9..b469b70 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;
@@ -2009,8 +2008,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.
@@ -2189,8 +2186,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/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index ce04cca..84b4cd9 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -306,7 +306,7 @@
///
/// zsts can't be read out of two reasons:
/// * byteorder cannot work with zero element buffers
- /// * in oder to obtain a `Pointer` we need to check for ZSTness anyway due to integer pointers
+ /// * in order to obtain a `Pointer` we need to check for ZSTness anyway due to integer pointers
/// being valid for ZSTs
///
/// It is the caller's responsibility to check bounds and alignment beforehand.
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_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_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 8216008..ce7681c 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -1876,16 +1876,70 @@
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &hir::Expr) {
- const ZEROED_PATH: &[Symbol] = &[sym::core, sym::mem, sym::zeroed];
- const UININIT_PATH: &[Symbol] = &[sym::core, sym::mem, sym::uninitialized];
+ #[derive(Debug, Copy, Clone, PartialEq)]
+ enum InitKind { Zeroed, Uninit };
/// Information about why a type cannot be initialized this way.
/// Contains an error message and optionally a span to point at.
type InitError = (String, Option<Span>);
+ /// Test if this constant is all-0.
+ fn is_zero(expr: &hir::Expr) -> bool {
+ use hir::ExprKind::*;
+ use syntax::ast::LitKind::*;
+ match &expr.node {
+ Lit(lit) =>
+ if let Int(i, _) = lit.node {
+ i == 0
+ } else {
+ false
+ },
+ Tup(tup) =>
+ tup.iter().all(is_zero),
+ _ =>
+ false
+ }
+ }
+
+ /// Determine if this expression is a "dangerous initialization".
+ fn is_dangerous_init(cx: &LateContext<'_, '_>, expr: &hir::Expr) -> Option<InitKind> {
+ const ZEROED_PATH: &[Symbol] = &[sym::core, sym::mem, sym::zeroed];
+ const UININIT_PATH: &[Symbol] = &[sym::core, sym::mem, sym::uninitialized];
+ // `transmute` is inside an anonymous module (the `extern` block?);
+ // `Invalid` represents the empty string and matches that.
+ const TRANSMUTE_PATH: &[Symbol] =
+ &[sym::core, sym::intrinsics, kw::Invalid, sym::transmute];
+
+ if let hir::ExprKind::Call(ref path_expr, ref args) = expr.node {
+ if let hir::ExprKind::Path(ref qpath) = path_expr.node {
+ let def_id = cx.tables.qpath_res(qpath, path_expr.hir_id).opt_def_id()?;
+
+ if cx.match_def_path(def_id, ZEROED_PATH) {
+ return Some(InitKind::Zeroed);
+ }
+ if cx.match_def_path(def_id, UININIT_PATH) {
+ return Some(InitKind::Uninit);
+ }
+ if cx.match_def_path(def_id, TRANSMUTE_PATH) {
+ if is_zero(&args[0]) {
+ return Some(InitKind::Zeroed);
+ }
+ }
+ // FIXME: Also detect `MaybeUninit::zeroed().assume_init()` and
+ // `MaybeUninit::uninit().assume_init()`.
+ }
+ }
+
+ None
+ }
+
/// Return `Some` only if we are sure this type does *not*
/// allow zero initialization.
- fn ty_find_init_error<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<InitError> {
+ fn ty_find_init_error<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ ty: Ty<'tcx>,
+ init: InitKind,
+ ) -> Option<InitError> {
use rustc::ty::TyKind::*;
match ty.sty {
// Primitive types that don't like 0 as a value.
@@ -1893,8 +1947,30 @@
Adt(..) if ty.is_box() => Some((format!("`Box` must be non-null"), None)),
FnPtr(..) => Some((format!("Function pointers must be non-null"), None)),
Never => Some((format!("The never type (`!`) has no valid value"), None)),
- // Recurse for some compound types.
+ // Primitive types with other constraints.
+ Bool if init == InitKind::Uninit =>
+ Some((format!("Booleans must be `true` or `false`"), None)),
+ Char if init == InitKind::Uninit =>
+ Some((format!("Characters must be a valid unicode codepoint"), None)),
+ // Recurse and checks for some compound types.
Adt(adt_def, substs) if !adt_def.is_union() => {
+ // First check f this ADT has a layout attribute (like `NonNull` and friends).
+ use std::ops::Bound;
+ match tcx.layout_scalar_valid_range(adt_def.did) {
+ // We exploit here that `layout_scalar_valid_range` will never
+ // return `Bound::Excluded`. (And we have tests checking that we
+ // handle the attribute correctly.)
+ (Bound::Included(lo), _) if lo > 0 =>
+ return Some((format!("{} must be non-null", ty), None)),
+ (Bound::Included(_), _) | (_, Bound::Included(_))
+ if init == InitKind::Uninit =>
+ return Some((
+ format!("{} must be initialized inside its custom valid range", ty),
+ None,
+ )),
+ _ => {}
+ }
+ // Now, recurse.
match adt_def.variants.len() {
0 => Some((format!("0-variant enums have no valid value"), None)),
1 => {
@@ -1905,6 +1981,7 @@
ty_find_init_error(
tcx,
field.ty(tcx, substs),
+ init,
).map(|(mut msg, span)| if span.is_none() {
// Point to this field, should be helpful for figuring
// out where the source of the error is.
@@ -1918,57 +1995,48 @@
})
})
}
+ // Multi-variant enums are tricky: if all but one variant are
+ // uninhabited, we might actually do layout like for a single-variant
+ // enum, and then even leaving them uninitialized could be okay.
_ => None, // Conservative fallback for multi-variant enum.
}
}
Tuple(..) => {
// Proceed recursively, check all fields.
- ty.tuple_fields().find_map(|field| ty_find_init_error(tcx, field))
+ ty.tuple_fields().find_map(|field| ty_find_init_error(tcx, field, init))
}
- // FIXME: Would be nice to also warn for `NonNull`/`NonZero*`.
- // FIXME: *Only for `mem::uninitialized`*, we could also warn for `bool`,
- // `char`, and any multivariant enum.
// Conservative fallback.
_ => None,
}
}
- if let hir::ExprKind::Call(ref path_expr, ref _args) = expr.node {
- if let hir::ExprKind::Path(ref qpath) = path_expr.node {
- if let Some(def_id) = cx.tables.qpath_res(qpath, path_expr.hir_id).opt_def_id() {
- if cx.match_def_path(def_id, &ZEROED_PATH) ||
- cx.match_def_path(def_id, &UININIT_PATH)
- {
- // This conjures an instance of a type out of nothing,
- // using zeroed or uninitialized memory.
- // We are extremely conservative with what we warn about.
- let conjured_ty = cx.tables.expr_ty(expr);
- if let Some((msg, span)) = ty_find_init_error(cx.tcx, conjured_ty) {
- let mut err = cx.struct_span_lint(
- INVALID_VALUE,
- expr.span,
- &format!(
- "the type `{}` does not permit {}",
- conjured_ty,
- if cx.match_def_path(def_id, &ZEROED_PATH) {
- "zero-initialization"
- } else {
- "being left uninitialized"
- }
- ),
- );
- err.span_label(expr.span,
- "this code causes undefined behavior when executed");
- err.span_label(expr.span, "help: use `MaybeUninit<T>` instead");
- if let Some(span) = span {
- err.span_note(span, &msg);
- } else {
- err.note(&msg);
- }
- err.emit();
- }
- }
+ if let Some(init) = is_dangerous_init(cx, expr) {
+ // This conjures an instance of a type out of nothing,
+ // using zeroed or uninitialized memory.
+ // We are extremely conservative with what we warn about.
+ let conjured_ty = cx.tables.expr_ty(expr);
+ if let Some((msg, span)) = ty_find_init_error(cx.tcx, conjured_ty, init) {
+ let mut err = cx.struct_span_lint(
+ INVALID_VALUE,
+ expr.span,
+ &format!(
+ "the type `{}` does not permit {}",
+ conjured_ty,
+ match init {
+ InitKind::Zeroed => "zero-initialization",
+ InitKind::Uninit => "being left uninitialized",
+ },
+ ),
+ );
+ err.span_label(expr.span,
+ "this code causes undefined behavior when executed");
+ err.span_label(expr.span, "help: use `MaybeUninit<T>` instead");
+ if let Some(span) = span {
+ err.span_note(span, &msg);
+ } else {
+ err.note(&msg);
}
+ err.emit();
}
}
}
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/const_eval.rs b/src/librustc_mir/const_eval.rs
index 52225ea..76ee76a 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -11,9 +11,8 @@
use rustc::hir::def_id::DefId;
use rustc::mir::interpret::{ConstEvalErr, ErrorHandled, ScalarMaybeUndef};
use rustc::mir;
-use rustc::ty::{self, TyCtxt};
+use rustc::ty::{self, Ty, TyCtxt, subst::Subst};
use rustc::ty::layout::{self, LayoutOf, VariantIdx};
-use rustc::ty::subst::Subst;
use rustc::traits::Reveal;
use rustc_data_structures::fx::FxHashMap;
@@ -415,7 +414,7 @@
_bin_op: mir::BinOp,
_left: ImmTy<'tcx>,
_right: ImmTy<'tcx>,
- ) -> InterpResult<'tcx, (Scalar, bool)> {
+ ) -> InterpResult<'tcx, (Scalar, bool, Ty<'tcx>)> {
Err(
ConstEvalError::NeedsRfc("pointer arithmetic or comparison".to_string()).into(),
)
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index ee105fe..4c86c53 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -137,7 +137,7 @@
let l = self.read_immediate(args[0])?;
let r = self.read_immediate(args[1])?;
let is_add = intrinsic_name == "saturating_add";
- let (val, overflowed) = self.binary_op(if is_add {
+ let (val, overflowed, _ty) = self.overflowing_binary_op(if is_add {
BinOp::Add
} else {
BinOp::Sub
@@ -184,7 +184,7 @@
"unchecked_shr" => BinOp::Shr,
_ => bug!("Already checked for int ops")
};
- let (val, overflowed) = self.binary_op(bin_op, l, r)?;
+ let (val, overflowed, _ty) = self.overflowing_binary_op(bin_op, l, r)?;
if overflowed {
let layout = self.layout_of(substs.type_at(0))?;
let r_val = r.to_scalar()?.to_bits(layout.size)?;
diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs
index 33ffb1d..bb74a50 100644
--- a/src/librustc_mir/interpret/machine.rs
+++ b/src/librustc_mir/interpret/machine.rs
@@ -7,7 +7,7 @@
use rustc::hir::def_id::DefId;
use rustc::mir;
-use rustc::ty::{self, TyCtxt};
+use rustc::ty::{self, Ty, TyCtxt};
use super::{
Allocation, AllocId, InterpResult, Scalar, AllocationExtra,
@@ -176,7 +176,7 @@
bin_op: mir::BinOp,
left: ImmTy<'tcx, Self::PointerTag>,
right: ImmTy<'tcx, Self::PointerTag>,
- ) -> InterpResult<'tcx, (Scalar<Self::PointerTag>, bool)>;
+ ) -> InterpResult<'tcx, (Scalar<Self::PointerTag>, bool, Ty<'tcx>)>;
/// Heap allocations via the `box` keyword.
fn box_alloc(
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 6771d76..87d36da 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -297,7 +297,7 @@
/// and `align`. On success, returns `None` for zero-sized accesses (where
/// nothing else is left to do) and a `Pointer` to use for the actual access otherwise.
/// Crucially, if the input is a `Pointer`, we will test it for liveness
- /// *even of* the size is 0.
+ /// *even if* the size is 0.
///
/// Everyone accessing memory based on a `Scalar` should use this method to get the
/// `Pointer` they need. And even if you already have a `Pointer`, call this method
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 139a92c..726ae6f 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -108,7 +108,7 @@
// as input for binary and cast operations.
#[derive(Copy, Clone, Debug)]
pub struct ImmTy<'tcx, Tag=()> {
- pub imm: Immediate<Tag>,
+ pub(crate) imm: Immediate<Tag>,
pub layout: TyLayout<'tcx>,
}
@@ -155,7 +155,7 @@
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct OpTy<'tcx, Tag=()> {
- op: Operand<Tag>,
+ op: Operand<Tag>, // Keep this private, it helps enforce invariants
pub layout: TyLayout<'tcx>,
}
@@ -187,14 +187,23 @@
}
}
-impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag>
-{
+impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> {
#[inline]
pub fn from_scalar(val: Scalar<Tag>, layout: TyLayout<'tcx>) -> Self {
ImmTy { imm: val.into(), layout }
}
#[inline]
+ pub fn from_uint(i: impl Into<u128>, layout: TyLayout<'tcx>) -> Self {
+ Self::from_scalar(Scalar::from_uint(i, layout.size), layout)
+ }
+
+ #[inline]
+ pub fn from_int(i: impl Into<i128>, layout: TyLayout<'tcx>) -> Self {
+ Self::from_scalar(Scalar::from_int(i, layout.size), layout)
+ }
+
+ #[inline]
pub fn to_bits(self) -> InterpResult<'tcx, u128> {
self.to_scalar()?.to_bits(self.layout.size)
}
diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs
index e638ebc..470cc93 100644
--- a/src/librustc_mir/interpret/operator.rs
+++ b/src/librustc_mir/interpret/operator.rs
@@ -1,5 +1,5 @@
use rustc::mir;
-use rustc::ty::{self, layout::TyLayout};
+use rustc::ty::{self, Ty, layout::{TyLayout, LayoutOf}};
use syntax::ast::FloatTy;
use rustc_apfloat::Float;
use rustc::mir::interpret::{InterpResult, Scalar};
@@ -17,7 +17,12 @@
right: ImmTy<'tcx, M::PointerTag>,
dest: PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> {
- let (val, overflowed) = self.binary_op(op, left, right)?;
+ let (val, overflowed, ty) = self.overflowing_binary_op(op, left, right)?;
+ debug_assert_eq!(
+ self.tcx.intern_tup(&[ty, self.tcx.types.bool]),
+ dest.layout.ty,
+ "type mismatch for result of {:?}", op,
+ );
let val = Immediate::ScalarPair(val.into(), Scalar::from_bool(overflowed).into());
self.write_immediate(val, dest)
}
@@ -31,7 +36,8 @@
right: ImmTy<'tcx, M::PointerTag>,
dest: PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> {
- let (val, _overflowed) = self.binary_op(op, left, right)?;
+ let (val, _overflowed, ty) = self.overflowing_binary_op(op, left, right)?;
+ assert_eq!(ty, dest.layout.ty, "type mismatch for result of {:?}", op);
self.write_scalar(val, dest)
}
}
@@ -42,7 +48,7 @@
bin_op: mir::BinOp,
l: char,
r: char,
- ) -> (Scalar<M::PointerTag>, bool) {
+ ) -> (Scalar<M::PointerTag>, bool, Ty<'tcx>) {
use rustc::mir::BinOp::*;
let res = match bin_op {
@@ -54,7 +60,7 @@
Ge => l >= r,
_ => bug!("Invalid operation on char: {:?}", bin_op),
};
- return (Scalar::from_bool(res), false);
+ return (Scalar::from_bool(res), false, self.tcx.types.bool);
}
fn binary_bool_op(
@@ -62,7 +68,7 @@
bin_op: mir::BinOp,
l: bool,
r: bool,
- ) -> (Scalar<M::PointerTag>, bool) {
+ ) -> (Scalar<M::PointerTag>, bool, Ty<'tcx>) {
use rustc::mir::BinOp::*;
let res = match bin_op {
@@ -77,32 +83,33 @@
BitXor => l ^ r,
_ => bug!("Invalid operation on bool: {:?}", bin_op),
};
- return (Scalar::from_bool(res), false);
+ return (Scalar::from_bool(res), false, self.tcx.types.bool);
}
fn binary_float_op<F: Float + Into<Scalar<M::PointerTag>>>(
&self,
bin_op: mir::BinOp,
+ ty: Ty<'tcx>,
l: F,
r: F,
- ) -> (Scalar<M::PointerTag>, bool) {
+ ) -> (Scalar<M::PointerTag>, bool, Ty<'tcx>) {
use rustc::mir::BinOp::*;
- let val = match bin_op {
- Eq => Scalar::from_bool(l == r),
- Ne => Scalar::from_bool(l != r),
- Lt => Scalar::from_bool(l < r),
- Le => Scalar::from_bool(l <= r),
- Gt => Scalar::from_bool(l > r),
- Ge => Scalar::from_bool(l >= r),
- Add => (l + r).value.into(),
- Sub => (l - r).value.into(),
- Mul => (l * r).value.into(),
- Div => (l / r).value.into(),
- Rem => (l % r).value.into(),
+ let (val, ty) = match bin_op {
+ Eq => (Scalar::from_bool(l == r), self.tcx.types.bool),
+ Ne => (Scalar::from_bool(l != r), self.tcx.types.bool),
+ Lt => (Scalar::from_bool(l < r), self.tcx.types.bool),
+ Le => (Scalar::from_bool(l <= r), self.tcx.types.bool),
+ Gt => (Scalar::from_bool(l > r), self.tcx.types.bool),
+ Ge => (Scalar::from_bool(l >= r), self.tcx.types.bool),
+ Add => ((l + r).value.into(), ty),
+ Sub => ((l - r).value.into(), ty),
+ Mul => ((l * r).value.into(), ty),
+ Div => ((l / r).value.into(), ty),
+ Rem => ((l % r).value.into(), ty),
_ => bug!("invalid float op: `{:?}`", bin_op),
};
- return (val, false);
+ return (val, false, ty);
}
fn binary_int_op(
@@ -113,7 +120,7 @@
left_layout: TyLayout<'tcx>,
r: u128,
right_layout: TyLayout<'tcx>,
- ) -> InterpResult<'tcx, (Scalar<M::PointerTag>, bool)> {
+ ) -> InterpResult<'tcx, (Scalar<M::PointerTag>, bool, Ty<'tcx>)> {
use rustc::mir::BinOp::*;
// Shift ops can have an RHS with a different numeric type.
@@ -142,7 +149,7 @@
}
};
let truncated = self.truncate(result, left_layout);
- return Ok((Scalar::from_uint(truncated, size), oflo));
+ return Ok((Scalar::from_uint(truncated, size), oflo, left_layout.ty));
}
// For the remaining ops, the types must be the same on both sides
@@ -167,7 +174,7 @@
if let Some(op) = op {
let l = self.sign_extend(l, left_layout) as i128;
let r = self.sign_extend(r, right_layout) as i128;
- return Ok((Scalar::from_bool(op(&l, &r)), false));
+ return Ok((Scalar::from_bool(op(&l, &r)), false, self.tcx.types.bool));
}
let op: Option<fn(i128, i128) -> (i128, bool)> = match bin_op {
Div if r == 0 => throw_panic!(DivisionByZero),
@@ -187,7 +194,7 @@
Rem | Div => {
// int_min / -1
if r == -1 && l == (1 << (size.bits() - 1)) {
- return Ok((Scalar::from_uint(l, size), true));
+ return Ok((Scalar::from_uint(l, size), true, left_layout.ty));
}
},
_ => {},
@@ -202,25 +209,24 @@
// this may be out-of-bounds for the result type, so we have to truncate ourselves
let result = result as u128;
let truncated = self.truncate(result, left_layout);
- return Ok((Scalar::from_uint(truncated, size), oflo));
+ return Ok((Scalar::from_uint(truncated, size), oflo, left_layout.ty));
}
}
let size = left_layout.size;
- // only ints left
- let val = match bin_op {
- Eq => Scalar::from_bool(l == r),
- Ne => Scalar::from_bool(l != r),
+ let (val, ty) = match bin_op {
+ Eq => (Scalar::from_bool(l == r), self.tcx.types.bool),
+ Ne => (Scalar::from_bool(l != r), self.tcx.types.bool),
- Lt => Scalar::from_bool(l < r),
- Le => Scalar::from_bool(l <= r),
- Gt => Scalar::from_bool(l > r),
- Ge => Scalar::from_bool(l >= r),
+ Lt => (Scalar::from_bool(l < r), self.tcx.types.bool),
+ Le => (Scalar::from_bool(l <= r), self.tcx.types.bool),
+ Gt => (Scalar::from_bool(l > r), self.tcx.types.bool),
+ Ge => (Scalar::from_bool(l >= r), self.tcx.types.bool),
- BitOr => Scalar::from_uint(l | r, size),
- BitAnd => Scalar::from_uint(l & r, size),
- BitXor => Scalar::from_uint(l ^ r, size),
+ BitOr => (Scalar::from_uint(l | r, size), left_layout.ty),
+ BitAnd => (Scalar::from_uint(l & r, size), left_layout.ty),
+ BitXor => (Scalar::from_uint(l ^ r, size), left_layout.ty),
Add | Sub | Mul | Rem | Div => {
debug_assert!(!left_layout.abi.is_signed());
@@ -236,7 +242,11 @@
};
let (result, oflo) = op(l, r);
let truncated = self.truncate(result, left_layout);
- return Ok((Scalar::from_uint(truncated, size), oflo || truncated != result));
+ return Ok((
+ Scalar::from_uint(truncated, size),
+ oflo || truncated != result,
+ left_layout.ty,
+ ));
}
_ => {
@@ -250,17 +260,17 @@
}
};
- Ok((val, false))
+ Ok((val, false, ty))
}
- /// Returns the result of the specified operation and whether it overflowed.
- #[inline]
- pub fn binary_op(
+ /// Returns the result of the specified operation, whether it overflowed, and
+ /// the result type.
+ pub fn overflowing_binary_op(
&self,
bin_op: mir::BinOp,
left: ImmTy<'tcx, M::PointerTag>,
right: ImmTy<'tcx, M::PointerTag>,
- ) -> InterpResult<'tcx, (Scalar<M::PointerTag>, bool)> {
+ ) -> InterpResult<'tcx, (Scalar<M::PointerTag>, bool, Ty<'tcx>)> {
trace!("Running binary op {:?}: {:?} ({:?}), {:?} ({:?})",
bin_op, *left, left.layout.ty, *right, right.layout.ty);
@@ -279,11 +289,14 @@
}
ty::Float(fty) => {
assert_eq!(left.layout.ty, right.layout.ty);
+ let ty = left.layout.ty;
let left = left.to_scalar()?;
let right = right.to_scalar()?;
Ok(match fty {
- FloatTy::F32 => self.binary_float_op(bin_op, left.to_f32()?, right.to_f32()?),
- FloatTy::F64 => self.binary_float_op(bin_op, left.to_f64()?, right.to_f64()?),
+ FloatTy::F32 =>
+ self.binary_float_op(bin_op, ty, left.to_f32()?, right.to_f32()?),
+ FloatTy::F64 =>
+ self.binary_float_op(bin_op, ty, left.to_f64()?, right.to_f64()?),
})
}
_ if left.layout.ty.is_integral() => {
@@ -312,11 +325,23 @@
}
}
+ /// Typed version of `checked_binary_op`, returning an `ImmTy`. Also ignores overflows.
+ #[inline]
+ pub fn binary_op(
+ &self,
+ bin_op: mir::BinOp,
+ left: ImmTy<'tcx, M::PointerTag>,
+ right: ImmTy<'tcx, M::PointerTag>,
+ ) -> InterpResult<'tcx, ImmTy<'tcx, M::PointerTag>> {
+ let (val, _overflow, ty) = self.overflowing_binary_op(bin_op, left, right)?;
+ Ok(ImmTy::from_scalar(val, self.layout_of(ty)?))
+ }
+
pub fn unary_op(
&self,
un_op: mir::UnOp,
val: ImmTy<'tcx, M::PointerTag>,
- ) -> InterpResult<'tcx, Scalar<M::PointerTag>> {
+ ) -> InterpResult<'tcx, ImmTy<'tcx, M::PointerTag>> {
use rustc::mir::UnOp::*;
let layout = val.layout;
@@ -330,7 +355,7 @@
Not => !val,
_ => bug!("Invalid bool op {:?}", un_op)
};
- Ok(Scalar::from_bool(res))
+ Ok(ImmTy::from_scalar(Scalar::from_bool(res), self.layout_of(self.tcx.types.bool)?))
}
ty::Float(fty) => {
let res = match (un_op, fty) {
@@ -338,7 +363,7 @@
(Neg, FloatTy::F64) => Scalar::from_f64(-val.to_f64()?),
_ => bug!("Invalid float op {:?}", un_op)
};
- Ok(res)
+ Ok(ImmTy::from_scalar(res, layout))
}
_ => {
assert!(layout.ty.is_integral());
@@ -351,7 +376,7 @@
}
};
// res needs tuncating
- Ok(Scalar::from_uint(self.truncate(res, layout), layout.size))
+ Ok(ImmTy::from_uint(self.truncate(res, layout), layout))
}
}
}
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 16686c3..ef9f20d 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -45,7 +45,7 @@
#[derive(Copy, Clone, Debug)]
pub struct PlaceTy<'tcx, Tag=()> {
- place: Place<Tag>,
+ place: Place<Tag>, // Keep this private, it helps enforce invariants
pub layout: TyLayout<'tcx>,
}
diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs
index e558278..b010bf0 100644
--- a/src/librustc_mir/interpret/step.rs
+++ b/src/librustc_mir/interpret/step.rs
@@ -177,7 +177,8 @@
// The operand always has the same type as the result.
let val = self.read_immediate(self.eval_operand(operand, Some(dest.layout))?)?;
let val = self.unary_op(un_op, val)?;
- self.write_scalar(val, dest)?;
+ assert_eq!(val.layout, dest.layout, "layout mismatch for result of {:?}", un_op);
+ self.write_immediate(*val, dest)?;
}
Aggregate(ref kind, ref operands) => {
diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs
index 1d6b48e..5de2979 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/src/librustc_mir/interpret/terminator.rs
@@ -7,7 +7,7 @@
use rustc_target::spec::abi::Abi;
use super::{
- InterpResult, PointerArithmetic, Scalar,
+ InterpResult, PointerArithmetic,
InterpCx, Machine, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup, FnVal,
};
@@ -50,11 +50,10 @@
for (index, &const_int) in values.iter().enumerate() {
// Compare using binary_op, to also support pointer values
- let const_int = Scalar::from_uint(const_int, discr.layout.size);
- let (res, _) = self.binary_op(mir::BinOp::Eq,
+ let res = self.overflowing_binary_op(mir::BinOp::Eq,
discr,
- ImmTy::from_scalar(const_int, discr.layout),
- )?;
+ ImmTy::from_uint(const_int, discr.layout),
+ )?.0;
if res.to_bool()? {
target_block = targets[index];
break;
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index c3c432d..98d8ca5 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -19,7 +19,7 @@
use rustc::ty::subst::InternalSubsts;
use rustc_data_structures::indexed_vec::IndexVec;
use rustc::ty::layout::{
- LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout, Size,
+ LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout,
};
use crate::interpret::{
@@ -396,17 +396,10 @@
if let ty::Slice(_) = mplace.layout.ty.sty {
let len = mplace.meta.unwrap().to_usize(&self.ecx).unwrap();
- Some(ImmTy {
- imm: Immediate::Scalar(
- Scalar::from_uint(
- len,
- Size::from_bits(
- self.tcx.sess.target.usize_ty.bit_width().unwrap() as u64
- )
- ).into(),
- ),
- layout: self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).ok()?,
- }.into())
+ Some(ImmTy::from_uint(
+ len,
+ self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).ok()?,
+ ).into())
} else {
trace!("not slice: {:?}", mplace.layout.ty.sty);
None
@@ -414,12 +407,10 @@
},
Rvalue::NullaryOp(NullOp::SizeOf, ty) => {
type_size_of(self.tcx, self.param_env, ty).and_then(|n| Some(
- ImmTy {
- imm: Immediate::Scalar(
- Scalar::from_uint(n, self.tcx.data_layout.pointer_size).into()
- ),
- layout: self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).ok()?,
- }.into()
+ ImmTy::from_uint(
+ n,
+ self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).ok()?,
+ ).into()
))
}
Rvalue::UnaryOp(op, ref arg) => {
@@ -452,11 +443,7 @@
// Now run the actual operation.
this.ecx.unary_op(op, prim)
})?;
- let res = ImmTy {
- imm: Immediate::Scalar(val.into()),
- layout: place_layout,
- };
- Some(res.into())
+ Some(val.into())
}
Rvalue::CheckedBinaryOp(op, ref left, ref right) |
Rvalue::BinaryOp(op, ref left, ref right) => {
@@ -510,8 +497,8 @@
this.ecx.read_immediate(left)
})?;
trace!("const evaluating {:?} for {:?} and {:?}", op, left, right);
- let (val, overflow) = self.use_ecx(source_info, |this| {
- this.ecx.binary_op(op, l, r)
+ let (val, overflow, _ty) = self.use_ecx(source_info, |this| {
+ this.ecx.overflowing_binary_op(op, l, r)
})?;
let val = if let Rvalue::CheckedBinaryOp(..) = *rvalue {
Immediate::ScalarPair(
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 1510d74..4242845 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -160,12 +160,25 @@
Some(ext)
}
+ // FIXME: `extra_placeholders` should be included into the `fragment` as regular placeholders.
crate fn build_reduced_graph(
- &mut self, fragment: &AstFragment, parent_scope: ParentScope<'a>
+ &mut self,
+ fragment: &AstFragment,
+ extra_placeholders: &[NodeId],
+ parent_scope: ParentScope<'a>,
) -> LegacyScope<'a> {
- fragment.visit_with(&mut DefCollector::new(&mut self.definitions, parent_scope.expansion));
+ let mut def_collector = DefCollector::new(&mut self.definitions, parent_scope.expansion);
+ fragment.visit_with(&mut def_collector);
+ for placeholder in extra_placeholders {
+ def_collector.visit_macro_invoc(*placeholder);
+ }
+
let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope };
fragment.visit_with(&mut visitor);
+ for placeholder in extra_placeholders {
+ visitor.parent_scope.legacy = visitor.visit_invoc(*placeholder);
+ }
+
visitor.parent_scope.legacy
}
@@ -871,7 +884,7 @@
}
/// Builds the reduced graph for a single item in an external crate.
- fn build_reduced_graph_for_external_crate_res(&mut self, child: Export<ast::NodeId>) {
+ fn build_reduced_graph_for_external_crate_res(&mut self, child: Export<NodeId>) {
let parent = self.parent_scope.module;
let Export { ident, res, vis, span } = child;
// FIXME: We shouldn't create the gensym here, it should come from metadata,
@@ -1060,10 +1073,10 @@
false
}
- fn visit_invoc(&mut self, id: ast::NodeId) -> LegacyScope<'a> {
+ fn visit_invoc(&mut self, id: NodeId) -> LegacyScope<'a> {
let invoc_id = id.placeholder_to_expn_id();
- self.parent_scope.module.unresolved_invocations.borrow_mut().insert(invoc_id);
+ self.parent_scope.module.unexpanded_invocations.borrow_mut().insert(invoc_id);
let old_parent_scope = self.r.invocation_parent_scopes.insert(invoc_id, self.parent_scope);
assert!(old_parent_scope.is_none(), "invocation data is reset for an invocation");
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index afdcec1..b79e0c2 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -169,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
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 d8bd866..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 { .. } => {}
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 12c4f5b..2dd0ad1 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -448,7 +448,7 @@
populate_on_access: Cell<bool>,
// Macro invocations that can expand into items in this module.
- unresolved_invocations: RefCell<FxHashSet<ExpnId>>,
+ unexpanded_invocations: RefCell<FxHashSet<ExpnId>>,
no_implicit_prelude: bool,
@@ -478,7 +478,7 @@
normal_ancestor_id,
lazy_resolutions: Default::default(),
populate_on_access: Cell::new(!normal_ancestor_id.is_local()),
- unresolved_invocations: Default::default(),
+ unexpanded_invocations: Default::default(),
no_implicit_prelude: false,
glob_importers: RefCell::new(Vec::new()),
globs: RefCell::new(Vec::new()),
@@ -1499,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
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 6f49377..01ad672 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -10,7 +10,7 @@
use rustc::hir::def::{self, DefKind, NonMacroAttrKind};
use rustc::middle::stability;
use rustc::{ty, lint, span_bug};
-use syntax::ast::{self, Ident};
+use syntax::ast::{self, NodeId, Ident};
use syntax::attr::StabilityLevel;
use syntax::edition::Edition;
use syntax::ext::base::{self, Indeterminate, SpecialDerives};
@@ -26,7 +26,7 @@
use std::{mem, ptr};
use rustc_data_structures::sync::Lrc;
-type Res = def::Res<ast::NodeId>;
+type Res = def::Res<NodeId>;
/// Binding produced by a `macro_rules` item.
/// Not modularized, can shadow previous legacy bindings, etc.
@@ -91,11 +91,11 @@
}
impl<'a> base::Resolver for Resolver<'a> {
- fn next_node_id(&mut self) -> ast::NodeId {
+ fn next_node_id(&mut self) -> NodeId {
self.session.next_node_id()
}
- fn get_module_scope(&mut self, id: ast::NodeId) -> ExpnId {
+ fn get_module_scope(&mut self, id: NodeId) -> ExpnId {
let expn_id = ExpnId::fresh(Some(ExpnData::default(
ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, self.session.edition()
)));
@@ -115,23 +115,18 @@
});
}
+ // FIXME: `extra_placeholders` should be included into the `fragment` as regular placeholders.
fn visit_ast_fragment_with_placeholders(
- &mut self, expansion: ExpnId, fragment: &AstFragment, derives: &[ExpnId]
+ &mut self, expansion: ExpnId, fragment: &AstFragment, extra_placeholders: &[NodeId]
) {
- // Fill in some data for derives if the fragment is from a derive container.
+ // Integrate the new AST fragment into all the definition and module structures.
// We are inside the `expansion` now, but other parent scope components are still the same.
let parent_scope = ParentScope { expansion, ..self.invocation_parent_scopes[&expansion] };
- let parent_def = self.definitions.invocation_parent(expansion);
- self.invocation_parent_scopes.extend(derives.iter().map(|&derive| (derive, parent_scope)));
- for &derive_invoc_id in derives {
- self.definitions.set_invocation_parent(derive_invoc_id, parent_def);
- }
- parent_scope.module.unresolved_invocations.borrow_mut().remove(&expansion);
- parent_scope.module.unresolved_invocations.borrow_mut().extend(derives);
-
- // Integrate the new AST fragment into all the definition and module structures.
- let output_legacy_scope = self.build_reduced_graph(fragment, parent_scope);
+ let output_legacy_scope =
+ self.build_reduced_graph(fragment, extra_placeholders, parent_scope);
self.output_legacy_scopes.insert(expansion, output_legacy_scope);
+
+ parent_scope.module.unexpanded_invocations.borrow_mut().remove(&expansion);
}
fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension) {
@@ -485,7 +480,7 @@
Scope::MacroUsePrelude => match this.macro_use_prelude.get(&ident.name).cloned() {
Some(binding) => Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE)),
None => Err(Determinacy::determined(
- this.graph_root.unresolved_invocations.borrow().is_empty()
+ this.graph_root.unexpanded_invocations.borrow().is_empty()
))
}
Scope::BuiltinAttrs => if is_builtin_attr_name(ident.name) {
@@ -508,7 +503,7 @@
Scope::ExternPrelude => match this.extern_prelude_get(ident, !record_used) {
Some(binding) => Ok((binding, Flags::PRELUDE)),
None => Err(Determinacy::determined(
- this.graph_root.unresolved_invocations.borrow().is_empty()
+ this.graph_root.unexpanded_invocations.borrow().is_empty()
)),
}
Scope::ToolPrelude => if KNOWN_TOOLS.contains(&ident.name) {
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index b49f186..fd222a1 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -202,7 +202,7 @@
Err((Determined, Weak::No))
} else if let Some(binding) = self.extern_prelude_get(ident, !record_used) {
Ok(binding)
- } else if !self.graph_root.unresolved_invocations.borrow().is_empty() {
+ } else if !self.graph_root.unexpanded_invocations.borrow().is_empty() {
// Macro-expanded `extern crate` items can add names to extern prelude.
Err((Undetermined, Weak::No))
} else {
@@ -348,7 +348,7 @@
// progress, we have to ignore those potential unresolved invocations from other modules
// and prohibit access to macro-expanded `macro_export` macros instead (unless restricted
// shadowing is enabled, see `macro_expanded_macro_export_errors`).
- let unexpanded_macros = !module.unresolved_invocations.borrow().is_empty();
+ let unexpanded_macros = !module.unexpanded_invocations.borrow().is_empty();
if let Some(binding) = resolution.binding {
if !unexpanded_macros || ns == MacroNS || restricted_shadowing {
return check_usable(self, binding);
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 3d15782..50e428e 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;
@@ -1787,7 +1787,6 @@
pub volatile: bool,
pub alignstack: bool,
pub dialect: AsmDialect,
- pub ctxt: SyntaxContext,
}
/// An argument in a function header.
@@ -2035,7 +2034,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/ext/base.rs b/src/libsyntax/ext/base.rs
index fb1bf4d..b0a4a6a 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -1,4 +1,4 @@
-use crate::ast::{self, Attribute, Name, PatKind};
+use crate::ast::{self, NodeId, Attribute, Name, PatKind};
use crate::attr::{HasAttrs, Stability, Deprecation};
use crate::source_map::SourceMap;
use crate::edition::Edition;
@@ -671,13 +671,13 @@
}
pub trait Resolver {
- fn next_node_id(&mut self) -> ast::NodeId;
+ fn next_node_id(&mut self) -> NodeId;
- fn get_module_scope(&mut self, id: ast::NodeId) -> ExpnId;
+ fn get_module_scope(&mut self, id: NodeId) -> ExpnId;
fn resolve_dollar_crates(&mut self);
fn visit_ast_fragment_with_placeholders(&mut self, expn_id: ExpnId, fragment: &AstFragment,
- derives: &[ExpnId]);
+ extra_placeholders: &[NodeId]);
fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension);
fn resolve_imports(&mut self);
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index dac4029..c1d52c9 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -291,7 +291,7 @@
// Unresolved macros produce dummy outputs as a recovery measure.
invocations.reverse();
let mut expanded_fragments = Vec::new();
- let mut derives: FxHashMap<ExpnId, Vec<_>> = FxHashMap::default();
+ let mut all_derive_placeholders: FxHashMap<ExpnId, Vec<_>> = FxHashMap::default();
let mut undetermined_invocations = Vec::new();
let (mut progress, mut force) = (false, !self.monotonic);
loop {
@@ -347,13 +347,14 @@
let mut item = self.fully_configure(item);
item.visit_attrs(|attrs| attrs.retain(|a| a.path != sym::derive));
- let derives = derives.entry(invoc.expansion_data.id).or_default();
+ let derive_placeholders =
+ all_derive_placeholders.entry(invoc.expansion_data.id).or_default();
- derives.reserve(traits.len());
+ derive_placeholders.reserve(traits.len());
invocations.reserve(traits.len());
for path in traits {
let expn_id = ExpnId::fresh(None);
- derives.push(expn_id);
+ derive_placeholders.push(NodeId::placeholder_from_expn_id(expn_id));
invocations.push(Invocation {
kind: InvocationKind::Derive { path, item: item.clone() },
fragment_kind: invoc.fragment_kind,
@@ -365,7 +366,7 @@
}
let fragment = invoc.fragment_kind
.expect_from_annotatables(::std::iter::once(item));
- self.collect_invocations(fragment, derives)
+ self.collect_invocations(fragment, derive_placeholders)
} else {
unreachable!()
};
@@ -384,10 +385,11 @@
// Finally incorporate all the expanded macros into the input AST fragment.
let mut placeholder_expander = PlaceholderExpander::new(self.cx, self.monotonic);
while let Some(expanded_fragments) = expanded_fragments.pop() {
- for (mark, expanded_fragment) in expanded_fragments.into_iter().rev() {
- let derives = derives.remove(&mark).unwrap_or_else(Vec::new);
- placeholder_expander.add(NodeId::placeholder_from_expn_id(mark),
- expanded_fragment, derives);
+ for (expn_id, expanded_fragment) in expanded_fragments.into_iter().rev() {
+ let derive_placeholders =
+ all_derive_placeholders.remove(&expn_id).unwrap_or_else(Vec::new);
+ placeholder_expander.add(NodeId::placeholder_from_expn_id(expn_id),
+ expanded_fragment, derive_placeholders);
}
}
fragment_with_placeholders.mut_visit_with(&mut placeholder_expander);
@@ -404,7 +406,7 @@
/// them with "placeholders" - dummy macro invocations with specially crafted `NodeId`s.
/// Then call into resolver that builds a skeleton ("reduced graph") of the fragment and
/// prepares data for resolving paths of macro invocations.
- fn collect_invocations(&mut self, mut fragment: AstFragment, derives: &[ExpnId])
+ fn collect_invocations(&mut self, mut fragment: AstFragment, extra_placeholders: &[NodeId])
-> (AstFragment, Vec<Invocation>) {
// Resolve `$crate`s in the fragment for pretty-printing.
self.cx.resolver.resolve_dollar_crates();
@@ -423,9 +425,10 @@
collector.invocations
};
+ // FIXME: Merge `extra_placeholders` into the `fragment` as regular placeholders.
if self.monotonic {
self.cx.resolver.visit_ast_fragment_with_placeholders(
- self.cx.current_expansion.id, &fragment, derives);
+ self.cx.current_expansion.id, &fragment, extra_placeholders);
}
(fragment, invocations)
diff --git a/src/libsyntax/ext/placeholders.rs b/src/libsyntax/ext/placeholders.rs
index 2d05f8f..d800cfe 100644
--- a/src/libsyntax/ext/placeholders.rs
+++ b/src/libsyntax/ext/placeholders.rs
@@ -2,7 +2,6 @@
use crate::source_map::{DUMMY_SP, dummy_spanned};
use crate::ext::base::ExtCtxt;
use crate::ext::expand::{AstFragment, AstFragmentKind};
-use crate::ext::hygiene::ExpnId;
use crate::tokenstream::TokenStream;
use crate::mut_visit::*;
use crate::ptr::P;
@@ -86,11 +85,11 @@
}
}
- pub fn add(&mut self, id: ast::NodeId, mut fragment: AstFragment, derives: Vec<ExpnId>) {
+ pub fn add(&mut self, id: ast::NodeId, mut fragment: AstFragment, placeholders: Vec<NodeId>) {
fragment.mut_visit_with(self);
if let AstFragment::Items(mut items) = fragment {
- for derive in derives {
- match self.remove(NodeId::placeholder_from_expn_id(derive)) {
+ for placeholder in placeholders {
+ match self.remove(placeholder) {
AstFragment::Items(derived_items) => items.extend(derived_items),
_ => unreachable!(),
}
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index b67b461..9785f8e 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -1183,7 +1183,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_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 361e017..0b8f16b 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;
@@ -848,28 +849,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/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/consts/const-eval/ub-nonnull.rs b/src/test/ui/consts/const-eval/ub-nonnull.rs
index 431ff35..9edae19 100644
--- a/src/test/ui/consts/const-eval/ub-nonnull.rs
+++ b/src/test/ui/consts/const-eval/ub-nonnull.rs
@@ -1,5 +1,5 @@
#![feature(rustc_attrs, const_transmute)]
-#![allow(const_err)] // make sure we cannot allow away the errors tested here
+#![allow(const_err, invalid_value)] // make sure we cannot allow away the errors tested here
use std::mem;
use std::ptr::NonNull;
diff --git a/src/test/ui/consts/const-eval/ub-ref.rs b/src/test/ui/consts/const-eval/ub-ref.rs
index 0d8f301..bbab85c 100644
--- a/src/test/ui/consts/const-eval/ub-ref.rs
+++ b/src/test/ui/consts/const-eval/ub-ref.rs
@@ -1,6 +1,6 @@
// ignore-tidy-linelength
#![feature(const_transmute)]
-#![allow(const_err)] // make sure we cannot allow away the errors tested here
+#![allow(const_err, invalid_value)] // make sure we cannot allow away the errors tested here
use std::mem;
diff --git a/src/test/ui/consts/const-eval/ub-upvars.rs b/src/test/ui/consts/const-eval/ub-upvars.rs
index 0a427cd..baab14d 100644
--- a/src/test/ui/consts/const-eval/ub-upvars.rs
+++ b/src/test/ui/consts/const-eval/ub-upvars.rs
@@ -1,5 +1,5 @@
#![feature(const_transmute)]
-#![allow(const_err)] // make sure we cannot allow away the errors tested here
+#![allow(const_err, invalid_value)] // make sure we cannot allow away the errors tested here
use std::mem;
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/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/lint/uninitialized-zeroed.rs b/src/test/ui/lint/uninitialized-zeroed.rs
index d816479..5cf62b8 100644
--- a/src/test/ui/lint/uninitialized-zeroed.rs
+++ b/src/test/ui/lint/uninitialized-zeroed.rs
@@ -2,11 +2,13 @@
// This test checks that calling `mem::{uninitialized,zeroed}` with certain types results
// in a lint.
-#![feature(never_type)]
+#![feature(never_type, rustc_attrs)]
#![allow(deprecated)]
#![deny(invalid_value)]
use std::mem::{self, MaybeUninit};
+use std::ptr::NonNull;
+use std::num::NonZeroU32;
enum Void {}
@@ -16,6 +18,11 @@
struct Wrap<T> { wrapped: T }
enum WrapEnum<T> { Wrapped(T) }
+#[rustc_layout_scalar_valid_range_start(0)]
+#[rustc_layout_scalar_valid_range_end(128)]
+#[repr(transparent)]
+pub(crate) struct NonBig(u64);
+
#[allow(unused)]
fn generic<T: 'static>() {
unsafe {
@@ -29,6 +36,7 @@
fn main() {
unsafe {
+ // Things that cannot even be zero.
let _val: ! = mem::zeroed(); //~ ERROR: does not permit zero-initialization
let _val: ! = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
@@ -56,11 +64,28 @@
let _val: Wrap<(RefPair, i32)> = mem::zeroed(); //~ ERROR: does not permit zero-initialization
let _val: Wrap<(RefPair, i32)> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
- // Some types that should work just fine.
+ let _val: NonNull<i32> = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+ let _val: NonNull<i32> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ // Things that can be zero, but not uninit.
+ let _val: bool = mem::zeroed();
+ let _val: bool = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: Wrap<char> = mem::zeroed();
+ let _val: Wrap<char> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ let _val: NonBig = mem::zeroed();
+ let _val: NonBig = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+ // Transmute-from-0
+ let _val: &'static i32 = mem::transmute(0usize); //~ ERROR: does not permit zero-initialization
+ let _val: &'static [i32] = mem::transmute((0usize, 0usize)); //~ ERROR: does not permit zero-initialization
+ let _val: NonZeroU32 = mem::transmute(0); //~ ERROR: does not permit zero-initialization
+
+ // Some more types that should work just fine.
let _val: Option<&'static i32> = mem::zeroed();
let _val: Option<fn()> = mem::zeroed();
let _val: MaybeUninit<&'static i32> = mem::zeroed();
- let _val: bool = mem::zeroed();
let _val: i32 = mem::zeroed();
}
}
diff --git a/src/test/ui/lint/uninitialized-zeroed.stderr b/src/test/ui/lint/uninitialized-zeroed.stderr
index 1b15fc2..a36a32a 100644
--- a/src/test/ui/lint/uninitialized-zeroed.stderr
+++ b/src/test/ui/lint/uninitialized-zeroed.stderr
@@ -1,5 +1,5 @@
error: the type `&'static T` does not permit zero-initialization
- --> $DIR/uninitialized-zeroed.rs:22:32
+ --> $DIR/uninitialized-zeroed.rs:29:32
|
LL | let _val: &'static T = mem::zeroed();
| ^^^^^^^^^^^^^
@@ -15,7 +15,7 @@
= note: References must be non-null
error: the type `&'static T` does not permit being left uninitialized
- --> $DIR/uninitialized-zeroed.rs:23:32
+ --> $DIR/uninitialized-zeroed.rs:30:32
|
LL | let _val: &'static T = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@
= note: References must be non-null
error: the type `Wrap<&'static T>` does not permit zero-initialization
- --> $DIR/uninitialized-zeroed.rs:25:38
+ --> $DIR/uninitialized-zeroed.rs:32:38
|
LL | let _val: Wrap<&'static T> = mem::zeroed();
| ^^^^^^^^^^^^^
@@ -35,13 +35,13 @@
| help: use `MaybeUninit<T>` instead
|
note: References must be non-null (in this struct field)
- --> $DIR/uninitialized-zeroed.rs:16:18
+ --> $DIR/uninitialized-zeroed.rs:18:18
|
LL | struct Wrap<T> { wrapped: T }
| ^^^^^^^^^^
error: the type `Wrap<&'static T>` does not permit being left uninitialized
- --> $DIR/uninitialized-zeroed.rs:26:38
+ --> $DIR/uninitialized-zeroed.rs:33:38
|
LL | let _val: Wrap<&'static T> = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^
@@ -50,13 +50,13 @@
| help: use `MaybeUninit<T>` instead
|
note: References must be non-null (in this struct field)
- --> $DIR/uninitialized-zeroed.rs:16:18
+ --> $DIR/uninitialized-zeroed.rs:18:18
|
LL | struct Wrap<T> { wrapped: T }
| ^^^^^^^^^^
error: the type `!` does not permit zero-initialization
- --> $DIR/uninitialized-zeroed.rs:32:23
+ --> $DIR/uninitialized-zeroed.rs:40:23
|
LL | let _val: ! = mem::zeroed();
| ^^^^^^^^^^^^^
@@ -67,7 +67,7 @@
= note: The never type (`!`) has no valid value
error: the type `!` does not permit being left uninitialized
- --> $DIR/uninitialized-zeroed.rs:33:23
+ --> $DIR/uninitialized-zeroed.rs:41:23
|
LL | let _val: ! = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^
@@ -78,7 +78,7 @@
= note: The never type (`!`) has no valid value
error: the type `(i32, !)` does not permit zero-initialization
- --> $DIR/uninitialized-zeroed.rs:35:30
+ --> $DIR/uninitialized-zeroed.rs:43:30
|
LL | let _val: (i32, !) = mem::zeroed();
| ^^^^^^^^^^^^^
@@ -89,7 +89,7 @@
= note: The never type (`!`) has no valid value
error: the type `(i32, !)` does not permit being left uninitialized
- --> $DIR/uninitialized-zeroed.rs:36:30
+ --> $DIR/uninitialized-zeroed.rs:44:30
|
LL | let _val: (i32, !) = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^
@@ -100,7 +100,7 @@
= note: The never type (`!`) has no valid value
error: the type `Void` does not permit zero-initialization
- --> $DIR/uninitialized-zeroed.rs:38:26
+ --> $DIR/uninitialized-zeroed.rs:46:26
|
LL | let _val: Void = mem::zeroed();
| ^^^^^^^^^^^^^
@@ -111,7 +111,7 @@
= note: 0-variant enums have no valid value
error: the type `Void` does not permit being left uninitialized
- --> $DIR/uninitialized-zeroed.rs:39:26
+ --> $DIR/uninitialized-zeroed.rs:47:26
|
LL | let _val: Void = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^
@@ -122,7 +122,7 @@
= note: 0-variant enums have no valid value
error: the type `&'static i32` does not permit zero-initialization
- --> $DIR/uninitialized-zeroed.rs:41:34
+ --> $DIR/uninitialized-zeroed.rs:49:34
|
LL | let _val: &'static i32 = mem::zeroed();
| ^^^^^^^^^^^^^
@@ -133,7 +133,7 @@
= note: References must be non-null
error: the type `&'static i32` does not permit being left uninitialized
- --> $DIR/uninitialized-zeroed.rs:42:34
+ --> $DIR/uninitialized-zeroed.rs:50:34
|
LL | let _val: &'static i32 = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^
@@ -144,7 +144,7 @@
= note: References must be non-null
error: the type `Ref` does not permit zero-initialization
- --> $DIR/uninitialized-zeroed.rs:44:25
+ --> $DIR/uninitialized-zeroed.rs:52:25
|
LL | let _val: Ref = mem::zeroed();
| ^^^^^^^^^^^^^
@@ -153,13 +153,13 @@
| help: use `MaybeUninit<T>` instead
|
note: References must be non-null (in this struct field)
- --> $DIR/uninitialized-zeroed.rs:13:12
+ --> $DIR/uninitialized-zeroed.rs:15:12
|
LL | struct Ref(&'static i32);
| ^^^^^^^^^^^^
error: the type `Ref` does not permit being left uninitialized
- --> $DIR/uninitialized-zeroed.rs:45:25
+ --> $DIR/uninitialized-zeroed.rs:53:25
|
LL | let _val: Ref = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^
@@ -168,13 +168,13 @@
| help: use `MaybeUninit<T>` instead
|
note: References must be non-null (in this struct field)
- --> $DIR/uninitialized-zeroed.rs:13:12
+ --> $DIR/uninitialized-zeroed.rs:15:12
|
LL | struct Ref(&'static i32);
| ^^^^^^^^^^^^
error: the type `fn()` does not permit zero-initialization
- --> $DIR/uninitialized-zeroed.rs:47:26
+ --> $DIR/uninitialized-zeroed.rs:55:26
|
LL | let _val: fn() = mem::zeroed();
| ^^^^^^^^^^^^^
@@ -185,7 +185,7 @@
= note: Function pointers must be non-null
error: the type `fn()` does not permit being left uninitialized
- --> $DIR/uninitialized-zeroed.rs:48:26
+ --> $DIR/uninitialized-zeroed.rs:56:26
|
LL | let _val: fn() = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^
@@ -196,7 +196,7 @@
= note: Function pointers must be non-null
error: the type `Wrap<fn()>` does not permit zero-initialization
- --> $DIR/uninitialized-zeroed.rs:50:32
+ --> $DIR/uninitialized-zeroed.rs:58:32
|
LL | let _val: Wrap<fn()> = mem::zeroed();
| ^^^^^^^^^^^^^
@@ -205,13 +205,13 @@
| help: use `MaybeUninit<T>` instead
|
note: Function pointers must be non-null (in this struct field)
- --> $DIR/uninitialized-zeroed.rs:16:18
+ --> $DIR/uninitialized-zeroed.rs:18:18
|
LL | struct Wrap<T> { wrapped: T }
| ^^^^^^^^^^
error: the type `Wrap<fn()>` does not permit being left uninitialized
- --> $DIR/uninitialized-zeroed.rs:51:32
+ --> $DIR/uninitialized-zeroed.rs:59:32
|
LL | let _val: Wrap<fn()> = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^
@@ -220,13 +220,13 @@
| help: use `MaybeUninit<T>` instead
|
note: Function pointers must be non-null (in this struct field)
- --> $DIR/uninitialized-zeroed.rs:16:18
+ --> $DIR/uninitialized-zeroed.rs:18:18
|
LL | struct Wrap<T> { wrapped: T }
| ^^^^^^^^^^
error: the type `WrapEnum<fn()>` does not permit zero-initialization
- --> $DIR/uninitialized-zeroed.rs:53:36
+ --> $DIR/uninitialized-zeroed.rs:61:36
|
LL | let _val: WrapEnum<fn()> = mem::zeroed();
| ^^^^^^^^^^^^^
@@ -235,13 +235,13 @@
| help: use `MaybeUninit<T>` instead
|
note: Function pointers must be non-null (in this enum field)
- --> $DIR/uninitialized-zeroed.rs:17:28
+ --> $DIR/uninitialized-zeroed.rs:19:28
|
LL | enum WrapEnum<T> { Wrapped(T) }
| ^
error: the type `WrapEnum<fn()>` does not permit being left uninitialized
- --> $DIR/uninitialized-zeroed.rs:54:36
+ --> $DIR/uninitialized-zeroed.rs:62:36
|
LL | let _val: WrapEnum<fn()> = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^
@@ -250,13 +250,13 @@
| help: use `MaybeUninit<T>` instead
|
note: Function pointers must be non-null (in this enum field)
- --> $DIR/uninitialized-zeroed.rs:17:28
+ --> $DIR/uninitialized-zeroed.rs:19:28
|
LL | enum WrapEnum<T> { Wrapped(T) }
| ^
error: the type `Wrap<(RefPair, i32)>` does not permit zero-initialization
- --> $DIR/uninitialized-zeroed.rs:56:42
+ --> $DIR/uninitialized-zeroed.rs:64:42
|
LL | let _val: Wrap<(RefPair, i32)> = mem::zeroed();
| ^^^^^^^^^^^^^
@@ -265,13 +265,13 @@
| help: use `MaybeUninit<T>` instead
|
note: References must be non-null (in this struct field)
- --> $DIR/uninitialized-zeroed.rs:14:16
+ --> $DIR/uninitialized-zeroed.rs:16:16
|
LL | struct RefPair((&'static i32, i32));
| ^^^^^^^^^^^^^^^^^^^
error: the type `Wrap<(RefPair, i32)>` does not permit being left uninitialized
- --> $DIR/uninitialized-zeroed.rs:57:42
+ --> $DIR/uninitialized-zeroed.rs:65:42
|
LL | let _val: Wrap<(RefPair, i32)> = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^
@@ -280,10 +280,102 @@
| help: use `MaybeUninit<T>` instead
|
note: References must be non-null (in this struct field)
- --> $DIR/uninitialized-zeroed.rs:14:16
+ --> $DIR/uninitialized-zeroed.rs:16:16
|
LL | struct RefPair((&'static i32, i32));
| ^^^^^^^^^^^^^^^^^^^
-error: aborting due to 22 previous errors
+error: the type `std::ptr::NonNull<i32>` does not permit zero-initialization
+ --> $DIR/uninitialized-zeroed.rs:67:34
+ |
+LL | let _val: NonNull<i32> = mem::zeroed();
+ | ^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead
+ |
+ = note: std::ptr::NonNull<i32> must be non-null
+
+error: the type `std::ptr::NonNull<i32>` does not permit being left uninitialized
+ --> $DIR/uninitialized-zeroed.rs:68:34
+ |
+LL | let _val: NonNull<i32> = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead
+ |
+ = note: std::ptr::NonNull<i32> must be non-null
+
+error: the type `bool` does not permit being left uninitialized
+ --> $DIR/uninitialized-zeroed.rs:72:26
+ |
+LL | let _val: bool = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead
+ |
+ = note: Booleans must be `true` or `false`
+
+error: the type `Wrap<char>` does not permit being left uninitialized
+ --> $DIR/uninitialized-zeroed.rs:75:32
+ |
+LL | let _val: Wrap<char> = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead
+ |
+note: Characters must be a valid unicode codepoint (in this struct field)
+ --> $DIR/uninitialized-zeroed.rs:18:18
+ |
+LL | struct Wrap<T> { wrapped: T }
+ | ^^^^^^^^^^
+
+error: the type `NonBig` does not permit being left uninitialized
+ --> $DIR/uninitialized-zeroed.rs:78:28
+ |
+LL | let _val: NonBig = mem::uninitialized();
+ | ^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead
+ |
+ = note: NonBig must be initialized inside its custom valid range
+
+error: the type `&'static i32` does not permit zero-initialization
+ --> $DIR/uninitialized-zeroed.rs:81:34
+ |
+LL | let _val: &'static i32 = mem::transmute(0usize);
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead
+ |
+ = note: References must be non-null
+
+error: the type `&'static [i32]` does not permit zero-initialization
+ --> $DIR/uninitialized-zeroed.rs:82:36
+ |
+LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead
+ |
+ = note: References must be non-null
+
+error: the type `std::num::NonZeroU32` does not permit zero-initialization
+ --> $DIR/uninitialized-zeroed.rs:83:32
+ |
+LL | let _val: NonZeroU32 = mem::transmute(0);
+ | ^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead
+ |
+ = note: std::num::NonZeroU32 must be non-null
+
+error: aborting due to 30 previous errors
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/proc-macro/auxiliary/gen-macro-rules.rs b/src/test/ui/proc-macro/auxiliary/gen-macro-rules.rs
new file mode 100644
index 0000000..d4b67d6
--- /dev/null
+++ b/src/test/ui/proc-macro/auxiliary/gen-macro-rules.rs
@@ -0,0 +1,12 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+#[proc_macro_derive(repro)]
+pub fn proc_macro_hack_expr(_input: TokenStream) -> TokenStream {
+ "macro_rules! m {()=>{}}".parse().unwrap()
+}
diff --git a/src/test/ui/proc-macro/gen-macro-rules.rs b/src/test/ui/proc-macro/gen-macro-rules.rs
new file mode 100644
index 0000000..13ad27f
--- /dev/null
+++ b/src/test/ui/proc-macro/gen-macro-rules.rs
@@ -0,0 +1,13 @@
+// Derive macros can generate `macro_rules` items, regression test for issue #63651.
+
+// check-pass
+// aux-build:gen-macro-rules.rs
+
+extern crate gen_macro_rules as repro;
+
+#[derive(repro::repro)]
+pub struct S;
+
+m!(); // OK
+
+fn main() {}
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/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() };