// flesh out rpath support more fully in the future.
cmd.arg("-Z").arg("osx-rpath-install-name");
Some("-Wl,-rpath,@loader_path/../lib")
- } else if !target.contains("windows") && !target.contains("wasm32") {
+ } else if !target.contains("windows") &&
+ !target.contains("wasm32") &&
+ !target.contains("fuchsia") {
Some("-Wl,-rpath,$ORIGIN/../lib")
} else {
None
o("profiler", "build.profiler", "build the profiler runtime")
o("emscripten", None, "compile the emscripten backend as well as LLVM")
o("full-tools", None, "enable all tools")
+o("lld", "rust.lld", "build lld")
o("lldb", "rust.lldb", "build lldb")
o("missing-tools", "dist.missing-tools", "allow failures when building tools")
} else if target != self.config.build &&
!target.contains("msvc") &&
!target.contains("emscripten") &&
- !target.contains("wasm32") {
+ !target.contains("wasm32") &&
+ !target.contains("fuchsia") {
Some(self.cc(target))
} else {
None
--- /dev/null
+FROM ubuntu:16.04
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ g++ \
+ make \
+ file \
+ curl \
+ ca-certificates \
+ python2.7 \
+ git \
+ cmake \
+ sudo \
+ gdb \
+ xz-utils \
+ g++-powerpc-linux-gnuspe \
+ libssl-dev \
+ pkg-config
+
+
+COPY scripts/sccache.sh /scripts/
+RUN sh /scripts/sccache.sh
+
+ENV HOSTS=powerpc-unknown-linux-gnuspe
+
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
+ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
CC_x86_64_sun_solaris=x86_64-sun-solaris2.10-gcc \
CXX_x86_64_sun_solaris=x86_64-sun-solaris2.10-g++
+ENV CARGO_TARGET_X86_64_FUCHSIA_AR /usr/local/bin/llvm-ar
+ENV CARGO_TARGET_X86_64_FUCHSIA_RUSTFLAGS \
+-C link-arg=--sysroot=/usr/local/x86_64-fuchsia \
+-C link-arg=-L/usr/local/x86_64-fuchsia/lib \
+-C link-arg=-L/usr/local/lib/x86_64-fuchsia/lib
+ENV CARGO_TARGET_AARCH64_FUCHSIA_AR /usr/local/bin/llvm-ar
+ENV CARGO_TARGET_AARCH64_FUCHSIA_RUSTFLAGS \
+-C link-arg=--sysroot=/usr/local/aarch64-fuchsia \
+-C link-arg=-L/usr/local/aarch64-fuchsia/lib \
+-C link-arg=-L/usr/local/lib/aarch64-fuchsia/lib
+
ENV TARGETS=x86_64-fuchsia
ENV TARGETS=$TARGETS,aarch64-fuchsia
ENV TARGETS=$TARGETS,sparcv9-sun-solaris
ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32
ENV TARGETS=$TARGETS,x86_64-unknown-cloudabi
-ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
+ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --disable-docs
ENV SCRIPT python2.7 ../x.py dist --target $TARGETS
impl<T: ?Sized> Rc<T> {
// Allocates an `RcBox<T>` with sufficient space for an unsized value
unsafe fn allocate_for_ptr(ptr: *const T) -> *mut RcBox<T> {
- // Create a fake RcBox to find allocation size and alignment
- let fake_ptr = ptr as *mut RcBox<T>;
-
- let layout = Layout::for_value(&*fake_ptr);
+ // Calculate layout using the given value.
+ // Previously, layout was calculated on the expression
+ // `&*(ptr as *const RcBox<T>)`, but this created a misaligned
+ // reference (see #54908).
+ let (layout, _) = Layout::new::<RcBox<()>>()
+ .extend(Layout::for_value(&*ptr)).unwrap();
let mem = Global.alloc(layout)
.unwrap_or_else(|_| handle_alloc_error(layout));
- // Initialize the real RcBox
+ // Initialize the RcBox
let inner = set_data_ptr(ptr as *mut T, mem.as_ptr() as *mut u8) as *mut RcBox<T>;
ptr::write(&mut (*inner).strong, Cell::new(1));
impl<T: ?Sized> Arc<T> {
// Allocates an `ArcInner<T>` with sufficient space for an unsized value
unsafe fn allocate_for_ptr(ptr: *const T) -> *mut ArcInner<T> {
- // Create a fake ArcInner to find allocation size and alignment
- let fake_ptr = ptr as *mut ArcInner<T>;
-
- let layout = Layout::for_value(&*fake_ptr);
+ // Calculate layout using the given value.
+ // Previously, layout was calculated on the expression
+ // `&*(ptr as *const ArcInner<T>)`, but this created a misaligned
+ // reference (see #54908).
+ let (layout, _) = Layout::new::<ArcInner<()>>()
+ .extend(Layout::for_value(&*ptr)).unwrap();
let mem = Global.alloc(layout)
.unwrap_or_else(|_| handle_alloc_error(layout));
- // Initialize the real ArcInner
+ // Initialize the ArcInner
let inner = set_data_ptr(ptr as *mut T, mem.as_ptr() as *mut u8) as *mut ArcInner<T>;
ptr::write(&mut (*inner).strong, atomic::AtomicUsize::new(1));
#[cfg(not(target_feature = "atomics"))]
mod lock {
+ #[inline]
pub fn lock() {} // no atomics, no threads, that's easy!
}
}
/// [`bool`]: ../../../std/primitive.bool.html
#[cfg(target_has_atomic = "8")]
#[stable(feature = "rust1", since = "1.0.0")]
+#[repr(C, align(1))]
pub struct AtomicBool {
v: UnsafeCell<u8>,
}
/// This type has the same in-memory representation as a `*mut T`.
#[cfg(target_has_atomic = "ptr")]
#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(target_pointer_width = "16", repr(C, align(2)))]
+#[cfg_attr(target_pointer_width = "32", repr(C, align(4)))]
+#[cfg_attr(target_pointer_width = "64", repr(C, align(8)))]
pub struct AtomicPtr<T> {
p: UnsafeCell<*mut T>,
}
$s_int_type:expr, $int_ref:expr,
$extra_feature:expr,
$min_fn:ident, $max_fn:ident,
+ $align:expr,
$int_type:ident $atomic_type:ident $atomic_init:ident) => {
/// An integer type which can be safely shared between threads.
///
///
/// [module-level documentation]: index.html
#[$stable]
+ #[repr(C, align($align))]
pub struct $atomic_type {
v: UnsafeCell<$int_type>,
}
"i8", "../../../std/primitive.i8.html",
"#![feature(integer_atomics)]\n\n",
atomic_min, atomic_max,
+ 1,
i8 AtomicI8 ATOMIC_I8_INIT
}
#[cfg(target_has_atomic = "8")]
"u8", "../../../std/primitive.u8.html",
"#![feature(integer_atomics)]\n\n",
atomic_umin, atomic_umax,
+ 1,
u8 AtomicU8 ATOMIC_U8_INIT
}
#[cfg(target_has_atomic = "16")]
"i16", "../../../std/primitive.i16.html",
"#![feature(integer_atomics)]\n\n",
atomic_min, atomic_max,
+ 2,
i16 AtomicI16 ATOMIC_I16_INIT
}
#[cfg(target_has_atomic = "16")]
"u16", "../../../std/primitive.u16.html",
"#![feature(integer_atomics)]\n\n",
atomic_umin, atomic_umax,
+ 2,
u16 AtomicU16 ATOMIC_U16_INIT
}
#[cfg(target_has_atomic = "32")]
"i32", "../../../std/primitive.i32.html",
"#![feature(integer_atomics)]\n\n",
atomic_min, atomic_max,
+ 4,
i32 AtomicI32 ATOMIC_I32_INIT
}
#[cfg(target_has_atomic = "32")]
"u32", "../../../std/primitive.u32.html",
"#![feature(integer_atomics)]\n\n",
atomic_umin, atomic_umax,
+ 4,
u32 AtomicU32 ATOMIC_U32_INIT
}
#[cfg(target_has_atomic = "64")]
"i64", "../../../std/primitive.i64.html",
"#![feature(integer_atomics)]\n\n",
atomic_min, atomic_max,
+ 8,
i64 AtomicI64 ATOMIC_I64_INIT
}
#[cfg(target_has_atomic = "64")]
"u64", "../../../std/primitive.u64.html",
"#![feature(integer_atomics)]\n\n",
atomic_umin, atomic_umax,
+ 8,
u64 AtomicU64 ATOMIC_U64_INIT
}
+#[cfg(all(not(stage0), target_has_atomic = "128"))]
+atomic_int! {
+ unstable(feature = "integer_atomics", issue = "32976"),
+ unstable(feature = "integer_atomics", issue = "32976"),
+ unstable(feature = "integer_atomics", issue = "32976"),
+ unstable(feature = "integer_atomics", issue = "32976"),
+ unstable(feature = "integer_atomics", issue = "32976"),
+ unstable(feature = "integer_atomics", issue = "32976"),
+ "i128", "../../../std/primitive.i128.html",
+ "#![feature(integer_atomics)]\n\n",
+ atomic_min, atomic_max,
+ 16,
+ i128 AtomicI128 ATOMIC_I128_INIT
+}
+#[cfg(all(not(stage0), target_has_atomic = "128"))]
+atomic_int! {
+ unstable(feature = "integer_atomics", issue = "32976"),
+ unstable(feature = "integer_atomics", issue = "32976"),
+ unstable(feature = "integer_atomics", issue = "32976"),
+ unstable(feature = "integer_atomics", issue = "32976"),
+ unstable(feature = "integer_atomics", issue = "32976"),
+ unstable(feature = "integer_atomics", issue = "32976"),
+ "u128", "../../../std/primitive.u128.html",
+ "#![feature(integer_atomics)]\n\n",
+ atomic_umin, atomic_umax,
+ 16,
+ u128 AtomicU128 ATOMIC_U128_INIT
+}
+#[cfg(target_pointer_width = "16")]
+macro_rules! ptr_width {
+ () => { 2 }
+}
+#[cfg(target_pointer_width = "32")]
+macro_rules! ptr_width {
+ () => { 4 }
+}
+#[cfg(target_pointer_width = "64")]
+macro_rules! ptr_width {
+ () => { 8 }
+}
#[cfg(target_has_atomic = "ptr")]
atomic_int!{
stable(feature = "rust1", since = "1.0.0"),
"isize", "../../../std/primitive.isize.html",
"",
atomic_min, atomic_max,
+ ptr_width!(),
isize AtomicIsize ATOMIC_ISIZE_INIT
}
#[cfg(target_has_atomic = "ptr")]
"usize", "../../../std/primitive.usize.html",
"",
atomic_umin, atomic_umax,
+ ptr_width!(),
usize AtomicUsize ATOMIC_USIZE_INIT
}
return true;
}
- // (To be) stable attribute for #[lang = "panic_impl"]
- if attr::contains_name(attrs, "panic_implementation") ||
- attr::contains_name(attrs, "panic_handler")
- {
+ // Stable attribute for #[lang = "panic_impl"]
+ if attr::contains_name(attrs, "panic_handler") {
return true;
}
if let Some(value) = attribute.value_str() {
return Some((value, attribute.span));
}
- } else if attribute.check_name("panic_implementation") ||
- attribute.check_name("panic_handler")
- {
+ } else if attribute.check_name("panic_handler") {
return Some((Symbol::intern("panic_impl"), attribute.span))
} else if attribute.check_name("alloc_error_handler") {
return Some((Symbol::intern("oom"), attribute.span))
/// implicit closure bindings. It is needed when the closure is
/// borrowing or mutating a mutable referent, e.g.:
///
- /// let x: &mut isize = ...;
- /// let y = || *x += 5;
+ /// let x: &mut isize = ...;
+ /// let y = || *x += 5;
///
/// If we were to try to translate this closure into a more explicit
/// form, we'd encounter an error with the code as written:
///
- /// struct Env { x: & &mut isize }
- /// let x: &mut isize = ...;
- /// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn
- /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
+ /// struct Env { x: & &mut isize }
+ /// let x: &mut isize = ...;
+ /// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn
+ /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
///
/// This is then illegal because you cannot mutate an `&mut` found
/// in an aliasable location. To solve, you'd have to translate with
/// an `&mut` borrow:
///
- /// struct Env { x: & &mut isize }
- /// let x: &mut isize = ...;
- /// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
- /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
+ /// struct Env { x: & &mut isize }
+ /// let x: &mut isize = ...;
+ /// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
+ /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
///
/// Now the assignment to `**env.x` is legal, but creating a
/// mutable pointer to `x` is not because `x` is not mutable. We
}
}
- pub fn atomic_load(&self, ptr: &'ll Value, order: AtomicOrdering, align: Align) -> &'ll Value {
+ pub fn atomic_load(&self, ptr: &'ll Value, order: AtomicOrdering, size: Size) -> &'ll Value {
self.count_insn("load.atomic");
unsafe {
let load = llvm::LLVMRustBuildAtomicLoad(self.llbuilder, ptr, noname(), order);
- // FIXME(eddyb) Isn't it UB to use `pref` instead of `abi` here?
- // However, 64-bit atomic loads on `i686-apple-darwin` appear to
- // require `___atomic_load` with ABI-alignment, so it's staying.
- llvm::LLVMSetAlignment(load, align.pref() as c_uint);
+ // LLVM requires the alignment of atomic loads to be at least the size of the type.
+ llvm::LLVMSetAlignment(load, size.bytes() as c_uint);
load
}
}
}
pub fn atomic_store(&self, val: &'ll Value, ptr: &'ll Value,
- order: AtomicOrdering, align: Align) {
+ order: AtomicOrdering, size: Size) {
debug!("Store {:?} -> {:?}", val, ptr);
self.count_insn("store.atomic");
let ptr = self.check_store(val, ptr);
unsafe {
let store = llvm::LLVMRustBuildAtomicStore(self.llbuilder, val, ptr, order);
- // FIXME(eddyb) Isn't it UB to use `pref` instead of `abi` here?
- // Also see `atomic_load` for more context.
- llvm::LLVMSetAlignment(store, align.pref() as c_uint);
+ // LLVM requires the alignment of atomic stores to be at least the size of the type.
+ llvm::LLVMSetAlignment(store, size.bytes() as c_uint);
}
}
"load" => {
let ty = substs.type_at(0);
if int_type_width_signed(ty, cx).is_some() {
- let align = cx.align_of(ty);
- bx.atomic_load(args[0].immediate(), order, align)
+ let size = cx.size_of(ty);
+ bx.atomic_load(args[0].immediate(), order, size)
} else {
return invalid_monomorphization(ty);
}
"store" => {
let ty = substs.type_at(0);
if int_type_width_signed(ty, cx).is_some() {
- let align = cx.align_of(ty);
- bx.atomic_store(args[1].immediate(), args[0].immediate(), order, align);
+ let size = cx.size_of(ty);
+ bx.atomic_store(args[1].immediate(), args[0].immediate(), order, size);
return;
} else {
return invalid_monomorphization(ty);
is non-empty",
pat_ty));
span_help!(&mut err, scrut.span,
- "Please ensure that all possible cases are being handled; \
- possibly adding wildcards or more match arms.");
+ "ensure that all possible cases are being handled, \
+ possibly by adding wildcards or more match arms");
err.emit();
}
// If the type *is* uninhabited, it's vacuously exhaustive
"unchecked_shr" => BinOp::Shr,
_ => bug!("Already checked for int ops")
};
- let (val, overflowed) = self.binary_op_val(bin_op, l, r)?;
+ let (val, overflowed) = self.binary_op_imm(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)?;
right: ImmTy<'tcx, M::PointerTag>,
dest: PlaceTy<'tcx, M::PointerTag>,
) -> EvalResult<'tcx> {
- let (val, overflowed) = self.binary_op_val(op, left, right)?;
+ let (val, overflowed) = self.binary_op_imm(op, left, right)?;
let val = Immediate::ScalarPair(val.into(), Scalar::from_bool(overflowed).into());
self.write_immediate(val, dest)
}
right: ImmTy<'tcx, M::PointerTag>,
dest: PlaceTy<'tcx, M::PointerTag>,
) -> EvalResult<'tcx> {
- let (val, _overflowed) = self.binary_op_val(op, left, right)?;
+ let (val, _overflowed) = self.binary_op_imm(op, left, right)?;
self.write_scalar(val, dest)
}
}
}
/// Convenience wrapper that's useful when keeping the layout together with the
- /// value.
+ /// immediate value.
#[inline]
- pub fn binary_op_val(
+ pub fn binary_op_imm(
&self,
bin_op: mir::BinOp,
left: ImmTy<'tcx, M::PointerTag>,
//
// * First is weak lang items. These are basically mechanisms for
// libcore to forward-reference symbols defined later in crates like
- // the standard library or `#[panic_implementation]` definitions. The
+ // the standard library or `#[panic_handler]` definitions. The
// definition of these weak lang items needs to be referenceable by
// libcore, so we're no longer a candidate for internalization.
// Removal of these functions can't be done by LLVM but rather must be
})?;
trace!("const evaluating {:?} for {:?} and {:?}", op, left, right);
let (val, overflow) = self.use_ecx(source_info, |this| {
- this.ecx.binary_op_val(op, l, r)
+ this.ecx.binary_op_imm(op, l, r)
})?;
let val = if let Rvalue::CheckedBinaryOp(..) = *rvalue {
Immediate::ScalarPair(
return Err(Determinacy::Determined);
}
}
+ Def::Err => {
+ return Err(Determinacy::Determined);
+ }
_ => panic!("expected `Def::Macro` or `Def::NonMacroAttr`"),
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use spec::{LldFlavor, LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::fuchsia_base::opts();
target_os: "fuchsia".to_string(),
target_env: String::new(),
target_vendor: String::new(),
- linker_flavor: LinkerFlavor::Gcc,
+ linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
options: TargetOptions {
abi_blacklist: super::arm_base::abi_blacklist(),
.. base
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use spec::{LinkArgs, LinkerFlavor, TargetOptions};
+use spec::{LldFlavor, LinkArgs, LinkerFlavor, TargetOptions};
use std::default::Default;
pub fn opts() -> TargetOptions {
let mut args = LinkArgs::new();
- args.insert(LinkerFlavor::Gcc, vec![
- // We want to be able to strip as much executable code as possible
- // from the linker command line, and this flag indicates to the
- // linker that it can avoid linking in dynamic libraries that don't
- // actually satisfy any symbols up to that point (as with many other
- // resolutions the linker does). This option only applies to all
- // following libraries so we're sure to pass it as one of the first
- // arguments.
- // FIXME: figure out whether these linker args are desirable
- //"-Wl,--as-needed".to_string(),
-
- // Always enable NX protection when it is available
- //"-Wl,-z,noexecstack".to_string(),
+ args.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec![
+ "--build-id".to_string(), "--hash-style=gnu".to_string(),
+ "-z".to_string(), "rodynamic".to_string(),
]);
TargetOptions {
+ linker: Some("rust-lld".to_owned()),
+ lld_flavor: LldFlavor::Ld,
dynamic_linking: true,
executables: true,
target_family: Some("unix".to_string()),
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use spec::{LinkerFlavor, Target, TargetResult};
+use spec::{LldFlavor, LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::fuchsia_base::opts();
base.cpu = "x86-64".to_string();
base.max_atomic_width = Some(64);
- base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
base.stack_probes = true;
Ok(Target {
target_os: "fuchsia".to_string(),
target_env: String::new(),
target_vendor: String::new(),
- linker_flavor: LinkerFlavor::Gcc,
+ linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
options: base,
})
}
// Trait must have a method named `m_name` and it should not have
// type parameters or early-bound regions.
let tcx = self.tcx;
- let method_item =
- self.associated_item(trait_def_id, m_name, Namespace::Value).unwrap();
+ let method_item = match self.associated_item(trait_def_id, m_name, Namespace::Value) {
+ Some(method_item) => method_item,
+ None => {
+ tcx.sess.delay_span_bug(span,
+ "operator trait does not have corresponding operator method");
+ return None;
+ }
+ };
let def_id = method_item.def_id;
let generics = tcx.generics_of(def_id);
assert_eq!(generics.params.len(), 0);
}
}
- // Check that a function marked as `#[panic_implementation]` has signature `fn(&PanicInfo) -> !`
+ // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() {
if panic_impl_did == fcx.tcx.hir.local_def_id(fn_id) {
if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() {
///
/// [changes]: ../io/index.html#platform-specific-behavior
///
+/// **NOTE**: If a parent of the given path doesn't exist, this function will
+/// return an error. To create a directory and all its missing parents at the
+/// same time, use the [`create_dir_all`] function.
+///
/// # Errors
///
/// This function will return an error in the following situations, but is not
/// limited to just these cases:
///
/// * User lacks permissions to create directory at `path`.
+/// * A parent of the given path doesn't exist. (To create a directory and all
+/// its missing parents at the same time, use the [`create_dir_all`]
+/// function.)
/// * `path` already exists.
///
/// # Examples
#[cfg(target_has_atomic = "64")]
#[unstable(feature = "integer_atomics", issue = "32976")]
impl RefUnwindSafe for atomic::AtomicI64 {}
+#[cfg(all(not(stage0), target_has_atomic = "128"))]
+#[unstable(feature = "integer_atomics", issue = "32976")]
+impl RefUnwindSafe for atomic::AtomicI128 {}
#[cfg(target_has_atomic = "ptr")]
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
#[cfg(target_has_atomic = "64")]
#[unstable(feature = "integer_atomics", issue = "32976")]
impl RefUnwindSafe for atomic::AtomicU64 {}
+#[cfg(all(not(stage0), target_has_atomic = "128"))]
+#[unstable(feature = "integer_atomics", issue = "32976")]
+impl RefUnwindSafe for atomic::AtomicU128 {}
#[cfg(target_has_atomic = "8")]
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
use cell::UnsafeCell;
use fmt;
+use hint;
use mem;
/// A thread local storage key which owns its contents.
// process multiple declarations
($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = $init:expr; $($rest:tt)*) => (
- __thread_local_inner!($(#[$attr])* $vis $name, $t, $init);
- thread_local!($($rest)*);
+ $crate::__thread_local_inner!($(#[$attr])* $vis $name, $t, $init);
+ $crate::thread_local!($($rest)*);
);
// handle a single declaration
($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = $init:expr) => (
- __thread_local_inner!($(#[$attr])* $vis $name, $t, $init);
+ $crate::__thread_local_inner!($(#[$attr])* $vis $name, $t, $init);
);
}
};
($(#[$attr:meta])* $vis:vis $name:ident, $t:ty, $init:expr) => {
$(#[$attr])* $vis const $name: $crate::thread::LocalKey<$t> =
- __thread_local_inner!(@key $(#[$attr])* $vis $name, $t, $init);
+ $crate::__thread_local_inner!(@key $(#[$attr])* $vis $name, $t, $init);
}
}
// operations a little differently and make this safe to call.
mem::replace(&mut *ptr, Some(value));
- (*ptr).as_ref().unwrap()
+ // After storing `Some` we want to get a reference to the contents of
+ // what we just stored. While we could use `unwrap` here and it should
+ // always work it empirically doesn't seem to always get optimized away,
+ // which means that using something like `try_with` can pull in
+ // panicking code and cause a large size bloat.
+ match *ptr {
+ Some(ref x) => x,
+ None => hint::unreachable_unchecked(),
+ }
}
/// Acquires a reference to the value in this TLS key.
}
},
AstFragmentKind::Ty => AstFragment::Ty(self.parse_ty()?),
- AstFragmentKind::Pat => AstFragment::Pat(self.parse_pat()?),
+ AstFragmentKind::Pat => AstFragment::Pat(self.parse_pat(None)?),
})
}
}
pub fn parse_pat_panic(parser: &mut Parser) -> P<Pat> {
- panictry!(parser.parse_pat())
+ panictry!(parser.parse_pat(None))
}
pub fn parse_arm_panic(parser: &mut Parser) -> Arm {
FatalError.raise();
}
},
- "pat" => token::NtPat(panictry!(p.parse_pat())),
+ "pat" => token::NtPat(panictry!(p.parse_pat(None))),
"expr" => token::NtExpr(panictry!(p.parse_expr())),
"literal" => token::NtLiteral(panictry!(p.parse_literal_maybe_minus())),
"ty" => token::NtTy(panictry!(p.parse_ty())),
(active, abi_thiscall, "1.19.0", None, None),
// Allows a test to fail without failing the whole suite
- (active, allow_fail, "1.19.0", Some(42219), None),
+ (active, allow_fail, "1.19.0", Some(46488), None),
// Allows unsized tuple coercion.
(active, unsized_tuple_coercion, "1.20.0", Some(42877), None),
(active, non_exhaustive, "1.22.0", Some(44109), None),
// `crate` as visibility modifier, synonymous to `pub(crate)`
- (active, crate_visibility_modifier, "1.23.0", Some(45388), None),
+ (active, crate_visibility_modifier, "1.23.0", Some(53120), None),
// extern types
(active, extern_types, "1.23.0", Some(43467), None),
(active, generic_associated_types, "1.23.0", Some(44265), None),
// `extern` in paths
- (active, extern_in_paths, "1.23.0", Some(44660), None),
+ (active, extern_in_paths, "1.23.0", Some(55600), None),
// Use `?` as the Kleene "at most one" operator
(active, macro_at_most_once_rep, "1.25.0", Some(48075), None),
// Infer static outlives requirements; RFC 2093
- (active, infer_static_outlives_requirements, "1.26.0", Some(44493), None),
+ (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None),
// Multiple patterns with `|` in `if let` and `while let`
(active, if_while_or_patterns, "1.26.0", Some(48215), None),
// Integer match exhaustiveness checking
(active, exhaustive_integer_patterns, "1.30.0", Some(50907), None),
- // RFC 2070: #[panic_implementation] / #[panic_handler]
- (active, panic_implementation, "1.28.0", Some(44489), None),
-
// #[doc(keyword = "...")]
(active, doc_keyword, "1.28.0", Some(51315), None),
(active, test_2018_feature, "1.31.0", Some(0), Some(Edition::Edition2018)),
// Support for arbitrary delimited token streams in non-macro attributes
- (active, unrestricted_attribute_tokens, "1.30.0", Some(44690), None),
+ (active, unrestricted_attribute_tokens, "1.30.0", Some(55208), None),
// Allows `use x::y;` to resolve through `self::x`, not just `::x`
(active, uniform_paths, "1.30.0", Some(53130), None),
(active, underscore_const_names, "1.31.0", Some(54912), None),
// `extern crate foo as bar;` puts `bar` into extern prelude.
- (active, extern_crate_item_prelude, "1.31.0", Some(54658), None),
+ (active, extern_crate_item_prelude, "1.31.0", Some(55599), None),
// `reason = ` in lint attributes and `expect` lint attribute
(active, lint_reasons, "1.31.0", Some(54503), None),
Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
(removed, proc_macro_gen, "1.27.0", Some(54727), None,
Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
+ (removed, panic_implementation, "1.28.0", Some(44489), None,
+ Some("subsumed by `#[panic_handler]`")),
);
declare_features! (
"infer 'static lifetime requirements",
cfg_fn!(infer_static_outlives_requirements))),
- // RFC 2070 (deprecated attribute name)
- ("panic_implementation",
- Normal,
- Gated(Stability::Deprecated("https://github.com/rust-lang/rust/issues/44489\
- #issuecomment-415140224",
- Some("replace this attribute with `#[panic_handler]`")),
- "panic_implementation",
- "this attribute was renamed to `panic_handler`",
- cfg_fn!(panic_implementation))),
-
// RFC 2070
("panic_handler", Normal, Ungated),
self.look_ahead(offset + 1, |t| t == &token::Colon)
}
+ /// Skip unexpected attributes and doc comments in this position and emit an appropriate error.
+ fn eat_incorrect_doc_comment(&mut self, applied_to: &str) {
+ if let token::DocComment(_) = self.token {
+ let mut err = self.diagnostic().struct_span_err(
+ self.span,
+ &format!("documentation comments cannot be applied to {}", applied_to),
+ );
+ err.span_label(self.span, "doc comments are not allowed here");
+ err.emit();
+ self.bump();
+ } else if self.token == token::Pound && self.look_ahead(1, |t| {
+ *t == token::OpenDelim(token::Bracket)
+ }) {
+ let lo = self.span;
+ // Skip every token until next possible arg.
+ while self.token != token::CloseDelim(token::Bracket) {
+ self.bump();
+ }
+ let sp = lo.to(self.span);
+ self.bump();
+ let mut err = self.diagnostic().struct_span_err(
+ sp,
+ &format!("attributes cannot be applied to {}", applied_to),
+ );
+ err.span_label(sp, "attributes are not allowed here");
+ err.emit();
+ }
+ }
+
/// This version of parse arg doesn't necessarily require
/// identifier names.
fn parse_arg_general(&mut self, require_name: bool) -> PResult<'a, Arg> {
let (pat, ty) = if require_name || self.is_named_argument() {
debug!("parse_arg_general parse_pat (require_name:{})",
require_name);
- let pat = self.parse_pat()?;
+ self.eat_incorrect_doc_comment("method arguments");
+ let pat = self.parse_pat(Some("argument name"))?;
if let Err(mut err) = self.expect(&token::Colon) {
// If we find a pattern followed by an identifier, it could be an (incorrect)
return Err(err);
}
+ self.eat_incorrect_doc_comment("a method argument's type");
(pat, self.parse_ty()?)
} else {
debug!("parse_arg_general ident_to_pat");
let parser_snapshot_before_ty = self.clone();
+ self.eat_incorrect_doc_comment("a method argument's type");
let mut ty = self.parse_ty();
if ty.is_ok() && self.token == token::Colon {
// This wasn't actually a type, but a pattern looking like a type,
// Recover from attempting to parse the argument as a type without pattern.
err.cancel();
mem::replace(self, parser_snapshot_before_ty);
- let pat = self.parse_pat()?;
+ let pat = self.parse_pat(Some("argument name"))?;
self.expect(&token::Colon)?;
let ty = self.parse_ty()?;
/// Parse an argument in a lambda header e.g. |arg, arg|
fn parse_fn_block_arg(&mut self) -> PResult<'a, Arg> {
- let pat = self.parse_pat()?;
+ let pat = self.parse_pat(Some("argument name"))?;
let t = if self.eat(&token::Colon) {
self.parse_ty()?
} else {
return Ok(self.mk_expr(lo.to(hi), ex, attrs));
}
if self.eat_keyword(keywords::Match) {
- return self.parse_match_expr(attrs);
+ let match_sp = self.prev_span;
+ return self.parse_match_expr(attrs).map_err(|mut err| {
+ err.span_label(match_sp, "while parsing this match expression");
+ err
+ });
}
if self.eat_keyword(keywords::Unsafe) {
return self.parse_block_expr(
"`..` can only be used once per tuple or tuple struct pattern");
}
} else if !self.check(&token::CloseDelim(token::Paren)) {
- fields.push(self.parse_pat()?);
+ fields.push(self.parse_pat(None)?);
} else {
break
}
}
}
- let subpat = self.parse_pat()?;
+ let subpat = self.parse_pat(None)?;
if before_slice && self.eat(&token::DotDot) {
slice = Some(subpat);
before_slice = false;
// Parsing a pattern of the form "fieldname: pat"
let fieldname = self.parse_field_name()?;
self.bump();
- let pat = self.parse_pat()?;
+ let pat = self.parse_pat(None)?;
hi = pat.span;
(pat, fieldname, false)
} else {
/// "top-level" patterns in a match arm, `for` loop, `let`, &c. (in contrast
/// to subpatterns within such).
fn parse_top_level_pat(&mut self) -> PResult<'a, P<Pat>> {
- let pat = self.parse_pat()?;
+ let pat = self.parse_pat(None)?;
if self.token == token::Comma {
// An unexpected comma after a top-level pattern is a clue that the
// user (perhaps more accustomed to some other language) forgot the
}
/// Parse a pattern.
- pub fn parse_pat(&mut self) -> PResult<'a, P<Pat>> {
- self.parse_pat_with_range_pat(true)
+ pub fn parse_pat(&mut self, expected: Option<&'static str>) -> PResult<'a, P<Pat>> {
+ self.parse_pat_with_range_pat(true, expected)
}
/// Parse a pattern, with a setting whether modern range patterns e.g. `a..=b`, `a..b` are
/// allowed.
- fn parse_pat_with_range_pat(&mut self, allow_range_pat: bool) -> PResult<'a, P<Pat>> {
+ fn parse_pat_with_range_pat(
+ &mut self,
+ allow_range_pat: bool,
+ expected: Option<&'static str>,
+ ) -> PResult<'a, P<Pat>> {
maybe_whole!(self, NtPat, |x| x);
let lo = self.span;
err.span_label(self.span, "unexpected lifetime");
return Err(err);
}
- let subpat = self.parse_pat_with_range_pat(false)?;
+ let subpat = self.parse_pat_with_range_pat(false, expected)?;
pat = PatKind::Ref(subpat, mutbl);
}
token::OpenDelim(token::Paren) => {
pat = self.parse_pat_ident(BindingMode::ByRef(mutbl))?;
} else if self.eat_keyword(keywords::Box) {
// Parse box pat
- let subpat = self.parse_pat_with_range_pat(false)?;
+ let subpat = self.parse_pat_with_range_pat(false, None)?;
pat = PatKind::Box(subpat);
} else if self.token.is_ident() && !self.token.is_reserved_ident() &&
self.parse_as_ident() {
}
Err(mut err) => {
self.cancel(&mut err);
- let msg = format!("expected pattern, found {}", self.this_token_descr());
+ let expected = expected.unwrap_or("pattern");
+ let msg = format!(
+ "expected {}, found {}",
+ expected,
+ self.this_token_descr(),
+ );
let mut err = self.fatal(&msg);
- err.span_label(self.span, "expected pattern");
+ err.span_label(self.span, format!("expected {}", expected));
return Err(err);
}
}
-> PResult<'a, PatKind> {
let ident = self.parse_ident()?;
let sub = if self.eat(&token::At) {
- Some(self.parse_pat()?)
+ Some(self.parse_pat(Some("binding pattern"))?)
} else {
None
};
pub fn string_to_pat(source_str: String) -> P<ast::Pat> {
let ps = ParseSess::new(FilePathMapping::empty());
with_error_checking_parse(source_str, &ps, |p| {
- p.parse_pat()
+ p.parse_pat(None)
})
}
pub unsafe fn atomic_i64(x: *mut i64) {
atomic_xadd(x, 1);
}
+#[cfg(target_has_atomic = "128")]
+pub unsafe fn atomic_u128(x: *mut u128) {
+ atomic_xadd(x, 1);
+}
+#[cfg(target_has_atomic = "128")]
+pub unsafe fn atomic_i128(x: *mut i128) {
+ atomic_xadd(x, 1);
+}
#[cfg(target_has_atomic = "ptr")]
pub unsafe fn atomic_usize(x: *mut usize) {
atomic_xadd(x, 1);
$(RUSTC) foo.rs -C lto -O --target wasm32-unknown-unknown --cfg c
wc -c < $(TMPDIR)/foo.wasm
[ "`wc -c < $(TMPDIR)/foo.wasm`" -lt "5120" ]
+ $(RUSTC) foo.rs -C lto -O --target wasm32-unknown-unknown --cfg d
+ wc -c < $(TMPDIR)/foo.wasm
+ [ "`wc -c < $(TMPDIR)/foo.wasm`" -lt "5120" ]
else
all:
endif
pub fn foo() {
panic!("{}", "a");
}
+
+#[no_mangle]
+#[cfg(d)]
+pub fn foo() -> usize {
+ use std::cell::Cell;
+ thread_local!(static A: Cell<Vec<u32>> = Cell::new(Vec::new()));
+ A.try_with(|x| x.replace(Vec::new()).len()).unwrap_or(0)
+}
// except according to those terms.
#![crate_type = "cdylib"]
-
-#![feature(panic_implementation)]
#![no_std]
use core::panic::PanicInfo;
panic!()
}
-#[panic_implementation]
+#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {}
}
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(cfg_target_has_atomic)]
+#![feature(integer_atomics)]
+
+use std::mem::{align_of, size_of};
+use std::sync::atomic::*;
+
+fn main() {
+ #[cfg(target_has_atomic = "8")]
+ assert_eq!(align_of::<AtomicBool>(), size_of::<AtomicBool>());
+ #[cfg(target_has_atomic = "ptr")]
+ assert_eq!(align_of::<AtomicPtr<u8>>(), size_of::<AtomicPtr<u8>>());
+ #[cfg(target_has_atomic = "8")]
+ assert_eq!(align_of::<AtomicU8>(), size_of::<AtomicU8>());
+ #[cfg(target_has_atomic = "8")]
+ assert_eq!(align_of::<AtomicI8>(), size_of::<AtomicI8>());
+ #[cfg(target_has_atomic = "16")]
+ assert_eq!(align_of::<AtomicU16>(), size_of::<AtomicU16>());
+ #[cfg(target_has_atomic = "16")]
+ assert_eq!(align_of::<AtomicI16>(), size_of::<AtomicI16>());
+ #[cfg(target_has_atomic = "32")]
+ assert_eq!(align_of::<AtomicU32>(), size_of::<AtomicU32>());
+ #[cfg(target_has_atomic = "32")]
+ assert_eq!(align_of::<AtomicI32>(), size_of::<AtomicI32>());
+ #[cfg(target_has_atomic = "64")]
+ assert_eq!(align_of::<AtomicU64>(), size_of::<AtomicU64>());
+ #[cfg(target_has_atomic = "64")]
+ assert_eq!(align_of::<AtomicI64>(), size_of::<AtomicI64>());
+ #[cfg(target_has_atomic = "128")]
+ assert_eq!(align_of::<AtomicU128>(), size_of::<AtomicU128>());
+ #[cfg(target_has_atomic = "128")]
+ assert_eq!(align_of::<AtomicI128>(), size_of::<AtomicI128>());
+ #[cfg(target_has_atomic = "ptr")]
+ assert_eq!(align_of::<AtomicUsize>(), size_of::<AtomicUsize>());
+ #[cfg(target_has_atomic = "ptr")]
+ assert_eq!(align_of::<AtomicIsize>(), size_of::<AtomicIsize>());
+}
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![no_std]
+
+extern crate std;
+
+std::thread_local!(static A: usize = 30);
+
+fn main() {
+}
LL | match x { } //~ ERROR E0004
| ^
|
-help: Please ensure that all possible cases are being handled; possibly adding wildcards or more match arms.
+help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
--> $DIR/E0004-2.rs:14:11
|
LL | match x { } //~ ERROR E0004
-error[E0658]: allow_fail attribute is currently unstable (see issue #42219)
+error[E0658]: allow_fail attribute is currently unstable (see issue #46488)
--> $DIR/feature-gate-allow_fail.rs:13:1
|
LL | #[allow_fail] //~ ERROR allow_fail attribute is currently unstable
pub unsafe fn atomic_i64(x: *mut i64) {
atomic_xadd(x, 1);
}
+#[cfg(target_has_atomic = "128")]
+//~^ ERROR `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976)
+pub unsafe fn atomic_u128(x: *mut u128) {
+ atomic_xadd(x, 1);
+}
+#[cfg(target_has_atomic = "128")]
+//~^ ERROR `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976)
+pub unsafe fn atomic_i128(x: *mut i128) {
+ atomic_xadd(x, 1);
+}
#[cfg(target_has_atomic = "ptr")]
//~^ ERROR `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976)
pub unsafe fn atomic_usize(x: *mut usize) {
//~^ ERROR `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976)
cfg!(target_has_atomic = "64");
//~^ ERROR `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976)
+ cfg!(target_has_atomic = "128");
+ //~^ ERROR `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976)
cfg!(target_has_atomic = "ptr");
//~^ ERROR `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976)
}
error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976)
--> $DIR/feature-gate-cfg-target-has-atomic.rs:64:7
|
-LL | #[cfg(target_has_atomic = "ptr")]
+LL | #[cfg(target_has_atomic = "128")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable
error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976)
--> $DIR/feature-gate-cfg-target-has-atomic.rs:69:7
|
+LL | #[cfg(target_has_atomic = "128")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable
+
+error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976)
+ --> $DIR/feature-gate-cfg-target-has-atomic.rs:74:7
+ |
+LL | #[cfg(target_has_atomic = "ptr")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable
+
+error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976)
+ --> $DIR/feature-gate-cfg-target-has-atomic.rs:79:7
+ |
LL | #[cfg(target_has_atomic = "ptr")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable
error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976)
- --> $DIR/feature-gate-cfg-target-has-atomic.rs:76:10
+ --> $DIR/feature-gate-cfg-target-has-atomic.rs:86:10
|
LL | cfg!(target_has_atomic = "8");
| ^^^^^^^^^^^^^^^^^^^^^^^
= help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable
error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976)
- --> $DIR/feature-gate-cfg-target-has-atomic.rs:78:10
+ --> $DIR/feature-gate-cfg-target-has-atomic.rs:88:10
|
LL | cfg!(target_has_atomic = "16");
| ^^^^^^^^^^^^^^^^^^^^^^^^
= help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable
error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976)
- --> $DIR/feature-gate-cfg-target-has-atomic.rs:80:10
+ --> $DIR/feature-gate-cfg-target-has-atomic.rs:90:10
|
LL | cfg!(target_has_atomic = "32");
| ^^^^^^^^^^^^^^^^^^^^^^^^
= help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable
error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976)
- --> $DIR/feature-gate-cfg-target-has-atomic.rs:82:10
+ --> $DIR/feature-gate-cfg-target-has-atomic.rs:92:10
|
LL | cfg!(target_has_atomic = "64");
| ^^^^^^^^^^^^^^^^^^^^^^^^
= help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable
error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976)
- --> $DIR/feature-gate-cfg-target-has-atomic.rs:84:10
+ --> $DIR/feature-gate-cfg-target-has-atomic.rs:94:10
+ |
+LL | cfg!(target_has_atomic = "128");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable
+
+error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976)
+ --> $DIR/feature-gate-cfg-target-has-atomic.rs:96:10
|
LL | cfg!(target_has_atomic = "ptr");
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable
-error: aborting due to 15 previous errors
+error: aborting due to 18 previous errors
For more information about this error, try `rustc --explain E0658`.
-error[E0658]: `crate` visibility modifier is experimental (see issue #45388)
+error[E0658]: `crate` visibility modifier is experimental (see issue #53120)
--> $DIR/feature-gate-crate_visibility_modifier.rs:11:1
|
LL | crate struct Bender { //~ ERROR `crate` visibility modifier is experimental
-error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #54658)
+error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599)
--> $DIR/feature-gate-extern_crate_item_prelude.rs:26:9
|
LL | use alloc;
|
= help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable
-error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #54658)
+error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599)
--> $DIR/feature-gate-extern_crate_item_prelude.rs:28:9
|
LL | use alloc::boxed;
|
= help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable
-error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #54658)
+error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599)
--> $DIR/feature-gate-extern_crate_item_prelude.rs:33:11
|
LL | use ::alloc;
|
= help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable
-error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #54658)
+error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599)
--> $DIR/feature-gate-extern_crate_item_prelude.rs:35:11
|
LL | use ::alloc::boxed;
|
= help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable
-error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #54658)
+error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599)
--> $DIR/feature-gate-extern_crate_item_prelude.rs:9:17
|
LL | let v = alloc::vec![0];
|
= help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable
-error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #54658)
+error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599)
--> $DIR/feature-gate-extern_crate_item_prelude.rs:11:18
|
LL | type A = alloc::boxed::Box<u8>;
|
= help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable
-error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #54658)
+error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599)
--> $DIR/feature-gate-extern_crate_item_prelude.rs:18:19
|
LL | let v = ::alloc::vec![0];
|
= help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable
-error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #54658)
+error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599)
--> $DIR/feature-gate-extern_crate_item_prelude.rs:20:20
|
LL | type A = ::alloc::boxed::Box<u8>;
|
= help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable
-error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #54658)
+error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599)
--> $DIR/feature-gate-extern_crate_item_prelude.rs:42:14
|
LL | type A = core::boxed::Box<u8>;
-error[E0658]: `extern` in paths is experimental (see issue #44660)
+error[E0658]: `extern` in paths is experimental (see issue #55600)
--> $DIR/feature-gate-extern_in_paths.rs:14:13
|
LL | let _ = extern::std::vec::Vec::new(); //~ ERROR `extern` in paths is experimental
+++ /dev/null
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// compile-flags:-C panic=abort
-
-#![no_std]
-#![no_main]
-
-use core::panic::PanicInfo;
-
-#[panic_implementation] //~ ERROR this attribute was renamed to `panic_handler` (see issue #44489)
-fn panic(info: &PanicInfo) -> ! {
- loop {}
-}
+++ /dev/null
-error[E0658]: this attribute was renamed to `panic_handler` (see issue #44489)
- --> $DIR/feature-gate-panic-implementation.rs:18:1
- |
-LL | #[panic_implementation] //~ ERROR this attribute was renamed to `panic_handler` (see issue #44489)
- | ^^^^^^^^^^^^^^^^^^^^^^^
- |
- = help: add #![feature(panic_implementation)] to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
--- /dev/null
+use NonExistent; //~ ERROR unresolved import `NonExistent`
+use non_existent::non_existent; //~ ERROR unresolved import `non_existent`
+
+#[non_existent] //~ ERROR cannot determine resolution for the attribute macro `non_existent`
+#[derive(NonExistent)] //~ ERROR cannot determine resolution for the derive macro `NonExistent`
+struct S;
+
+fn main() {}
--- /dev/null
+error[E0432]: unresolved import `NonExistent`
+ --> $DIR/issue-55457.rs:1:5
+ |
+LL | use NonExistent; //~ ERROR unresolved import `NonExistent`
+ | ^^^^^^^^^^^ no `NonExistent` in the root. Did you mean to use `non_existent`?
+
+error[E0432]: unresolved import `non_existent`
+ --> $DIR/issue-55457.rs:2:5
+ |
+LL | use non_existent::non_existent; //~ ERROR unresolved import `non_existent`
+ | ^^^^^^^^^^^^ Maybe a missing `extern crate non_existent;`?
+
+error: cannot determine resolution for the derive macro `NonExistent`
+ --> $DIR/issue-55457.rs:5:10
+ |
+LL | #[derive(NonExistent)] //~ ERROR cannot determine resolution for the derive macro `NonExistent`
+ | ^^^^^^^^^^^
+ |
+ = note: import resolution is stuck, try simplifying macro imports
+
+error: cannot determine resolution for the attribute macro `non_existent`
+ --> $DIR/issue-55457.rs:4:3
+ |
+LL | #[non_existent] //~ ERROR cannot determine resolution for the attribute macro `non_existent`
+ | ^^^^^^^^^^^^
+ |
+ = note: import resolution is stuck, try simplifying macro imports
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0432`.
LL | match () { } //~ ERROR non-exhaustive
| ^^
|
-help: Please ensure that all possible cases are being handled; possibly adding wildcards or more match arms.
+help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
--> $DIR/issue-3096-1.rs:12:11
|
LL | match () { } //~ ERROR non-exhaustive
LL | match x { } //~ ERROR non-exhaustive patterns
| ^
|
-help: Please ensure that all possible cases are being handled; possibly adding wildcards or more match arms.
+help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
--> $DIR/issue-3096-2.rs:15:11
|
LL | match x { } //~ ERROR non-exhaustive patterns
--- /dev/null
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang="sized"]
+trait Sized {}
+
+#[lang="add"]
+trait Add<T> {}
+
+impl Add<i32> for i32 {}
+
+fn main() {
+ let x = 5 + 6;
+ //~^ ERROR binary operation `+` cannot be applied to type `{integer}`
+ let y = 5i32 + 6i32;
+ //~^ ERROR binary operation `+` cannot be applied to type `i32`
+}
--- /dev/null
+error[E0369]: binary operation `+` cannot be applied to type `{integer}`
+ --> $DIR/issue-31076.rs:13:13
+ |
+LL | let x = 5 + 6;
+ | ^^^^^
+ |
+ = note: an implementation of `std::ops::Add` might be missing for `{integer}`
+
+error[E0369]: binary operation `+` cannot be applied to type `i32`
+ --> $DIR/issue-31076.rs:15:13
+ |
+LL | let y = 5i32 + 6i32;
+ | ^^^^^^^^^^^
+ |
+ = note: an implementation of `std::ops::Add` might be missing for `i32`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0369`.
--> $DIR/label_break_value_illegal_uses.rs:28:17
|
LL | match false 'b: {} //~ ERROR expected one of `.`, `?`, `{`, or an operator
- | ^^ expected one of `.`, `?`, `{`, or an operator here
+ | ----- ^^ expected one of `.`, `?`, `{`, or an operator here
+ | |
+ | while parsing this match expression
error: aborting due to 4 previous errors
+++ /dev/null
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// compile-flags:-C panic=abort
-
-#![deny(deprecated)]
-#![feature(panic_implementation)]
-#![no_std]
-
-use core::panic::PanicInfo;
-
-#[panic_implementation]
-fn panic(info: &PanicInfo) -> ! {
- loop {}
-}
-
-fn main() {}
+++ /dev/null
-error: use of deprecated attribute `panic_implementation`: this attribute was renamed to `panic_handler`. See https://github.com/rust-lang/rust/issues/44489#issuecomment-415140224
- --> $DIR/panic-implementation-deprecated.rs:19:1
- |
-LL | #[panic_implementation]
- | ^^^^^^^^^^^^^^^^^^^^^^^ help: replace this attribute with `#[panic_handler]`
- |
-note: lint level defined here
- --> $DIR/panic-implementation-deprecated.rs:13:9
- |
-LL | #![deny(deprecated)]
- | ^^^^^^^^^^
-
-error: aborting due to previous error
-
--- /dev/null
+pub fn f(
+ /// Comment
+ //~^ ERROR documentation comments cannot be applied to method arguments
+ //~| NOTE doc comments are not allowed here
+ id: u8,
+ /// Other
+ //~^ ERROR documentation comments cannot be applied to method arguments
+ //~| NOTE doc comments are not allowed here
+ a: u8,
+) {}
+
+fn foo(#[allow(dead_code)] id: i32) {}
+//~^ ERROR attributes cannot be applied to method arguments
+//~| NOTE attributes are not allowed here
+
+fn bar(id: #[allow(dead_code)] i32) {}
+//~^ ERROR attributes cannot be applied to a method argument's type
+//~| NOTE attributes are not allowed here
+
+fn main() {
+ // verify that the parser recovered and properly typechecked the args
+ f("", "");
+ //~^ ERROR mismatched types
+ //~| NOTE expected u8, found reference
+ //~| NOTE expected
+ //~| ERROR mismatched types
+ //~| NOTE expected u8, found reference
+ //~| NOTE expected
+ foo("");
+ //~^ ERROR mismatched types
+ //~| NOTE expected i32, found reference
+ //~| NOTE expected
+ bar("");
+ //~^ ERROR mismatched types
+ //~| NOTE expected i32, found reference
+ //~| NOTE expected
+}
--- /dev/null
+error: documentation comments cannot be applied to method arguments
+ --> $DIR/fn-arg-doc-comment.rs:2:5
+ |
+LL | /// Comment
+ | ^^^^^^^^^^^ doc comments are not allowed here
+
+error: documentation comments cannot be applied to method arguments
+ --> $DIR/fn-arg-doc-comment.rs:6:5
+ |
+LL | /// Other
+ | ^^^^^^^^^ doc comments are not allowed here
+
+error: attributes cannot be applied to method arguments
+ --> $DIR/fn-arg-doc-comment.rs:12:8
+ |
+LL | fn foo(#[allow(dead_code)] id: i32) {}
+ | ^^^^^^^^^^^^^^^^^^^ attributes are not allowed here
+
+error: attributes cannot be applied to a method argument's type
+ --> $DIR/fn-arg-doc-comment.rs:16:12
+ |
+LL | fn bar(id: #[allow(dead_code)] i32) {}
+ | ^^^^^^^^^^^^^^^^^^^ attributes are not allowed here
+
+error[E0308]: mismatched types
+ --> $DIR/fn-arg-doc-comment.rs:22:7
+ |
+LL | f("", "");
+ | ^^ expected u8, found reference
+ |
+ = note: expected type `u8`
+ found type `&'static str`
+
+error[E0308]: mismatched types
+ --> $DIR/fn-arg-doc-comment.rs:22:11
+ |
+LL | f("", "");
+ | ^^ expected u8, found reference
+ |
+ = note: expected type `u8`
+ found type `&'static str`
+
+error[E0308]: mismatched types
+ --> $DIR/fn-arg-doc-comment.rs:29:9
+ |
+LL | foo("");
+ | ^^ expected i32, found reference
+ |
+ = note: expected type `i32`
+ found type `&'static str`
+
+error[E0308]: mismatched types
+ --> $DIR/fn-arg-doc-comment.rs:33:9
+ |
+LL | bar("");
+ | ^^ expected i32, found reference
+ |
+ = note: expected type `i32`
+ found type `&'static str`
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
// compile-flags: -Z parse-only
impl S {
- fn f(*, a: u8) -> u8 {} //~ ERROR expected pattern, found `*`
+ fn f(*, a: u8) -> u8 {}
+ //~^ ERROR expected argument name, found `*`
}
-error: expected pattern, found `*`
+error: expected argument name, found `*`
--> $DIR/issue-33413.rs:14:10
|
-LL | fn f(*, a: u8) -> u8 {} //~ ERROR expected pattern, found `*`
- | ^ expected pattern
+LL | fn f(*, a: u8) -> u8 {}
+ | ^ expected argument name
error: aborting due to previous error
fn main() {
let foo =
- match
+ match //~ NOTE while parsing this match expression
Some(4).unwrap_or_else(5)
//~^ NOTE expected one of `.`, `?`, `{`, or an operator here
; //~ NOTE unexpected token
error: expected one of `.`, `?`, `{`, or an operator, found `;`
--> $DIR/match-refactor-to-expr.rs:18:9
|
-LL | match
- | ----- help: try removing this `match`
+LL | match //~ NOTE while parsing this match expression
+ | -----
+ | |
+ | while parsing this match expression
+ | help: try removing this `match`
LL | Some(4).unwrap_or_else(5)
| - expected one of `.`, `?`, `{`, or an operator here
LL | //~^ NOTE expected one of `.`, `?`, `{`, or an operator here
// compile-flags: -Z parse-only
-fn f(+x: isize) {} //~ ERROR expected pattern, found `+`
+fn f(+x: isize) {}
+//~^ ERROR expected argument name, found `+`
-error: expected pattern, found `+`
+error: expected argument name, found `+`
--> $DIR/removed-syntax-mode.rs:13:6
|
-LL | fn f(+x: isize) {} //~ ERROR expected pattern, found `+`
- | ^ expected pattern
+LL | fn f(+x: isize) {}
+ | ^ expected argument name
error: aborting due to previous error
--> $DIR/try-block-in-match.rs:16:11
|
LL | match try { false } { _ => {} } //~ ERROR expected expression, found reserved keyword `try`
- | ^^^ expected expression
+ | ----- ^^^ expected expression
+ | |
+ | while parsing this match expression
error: aborting due to previous error
LL | let _ = match x {}; //~ ERROR non-exhaustive
| ^
|
-help: Please ensure that all possible cases are being handled; possibly adding wildcards or more match arms.
+help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
--> $DIR/uninhabited-matches-feature-gated.rs:20:19
|
LL | let _ = match x {}; //~ ERROR non-exhaustive
LL | let _ = match x {}; //~ ERROR non-exhaustive
| ^
|
-help: Please ensure that all possible cases are being handled; possibly adding wildcards or more match arms.
+help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
--> $DIR/uninhabited-matches-feature-gated.rs:23:19
|
LL | let _ = match x {}; //~ ERROR non-exhaustive
LL | let _ = match x {}; //~ ERROR non-exhaustive
| ^
|
-help: Please ensure that all possible cases are being handled; possibly adding wildcards or more match arms.
+help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
--> $DIR/uninhabited-matches-feature-gated.rs:26:19
|
LL | let _ = match x {}; //~ ERROR non-exhaustive
+error[E0502]: cannot borrow `u.y` as immutable because it is also borrowed as mutable
+ --> $DIR/union-borrow-move-parent-sibling.rs:25:13
+ |
+LL | let a = &mut u.x.0;
+ | ---------- mutable borrow occurs here
+LL | let b = &u.y; //~ ERROR cannot borrow `u.y`
+ | ^^^^ immutable borrow occurs here
+LL | use_borrow(a);
+ | - mutable borrow later used here
+
error[E0382]: use of moved value: `u`
- --> $DIR/union-borrow-move-parent-sibling.rs:29:13
+ --> $DIR/union-borrow-move-parent-sibling.rs:32:13
|
LL | let a = u.x.0;
| ----- value moved here
-LL | let a = u.y; //~ ERROR use of moved value: `u.y`
+LL | let b = u.y; //~ ERROR use of moved value: `u.y`
| ^^^ value used here after move
|
= note: move occurs because `u` has type `U`, which does not implement the `Copy` trait
+error[E0502]: cannot borrow `u.y` as immutable because it is also borrowed as mutable
+ --> $DIR/union-borrow-move-parent-sibling.rs:38:13
+ |
+LL | let a = &mut (u.x.0).0;
+ | -------------- mutable borrow occurs here
+LL | let b = &u.y; //~ ERROR cannot borrow `u.y`
+ | ^^^^ immutable borrow occurs here
+LL | use_borrow(a);
+ | - mutable borrow later used here
+
error[E0382]: use of moved value: `u`
- --> $DIR/union-borrow-move-parent-sibling.rs:41:13
+ --> $DIR/union-borrow-move-parent-sibling.rs:45:13
|
LL | let a = (u.x.0).0;
| --------- value moved here
-LL | let a = u.y; //~ ERROR use of moved value: `u.y`
+LL | let b = u.y; //~ ERROR use of moved value: `u.y`
| ^^^ value used here after move
|
= note: move occurs because `u` has type `U`, which does not implement the `Copy` trait
+error[E0502]: cannot borrow `u.x` as immutable because it is also borrowed as mutable
+ --> $DIR/union-borrow-move-parent-sibling.rs:51:13
+ |
+LL | let a = &mut *u.y;
+ | --------- mutable borrow occurs here
+LL | let b = &u.x; //~ ERROR cannot borrow `u` (via `u.x`)
+ | ^^^^ immutable borrow occurs here
+LL | use_borrow(a);
+ | - mutable borrow later used here
+
error[E0382]: use of moved value: `u`
- --> $DIR/union-borrow-move-parent-sibling.rs:53:13
+ --> $DIR/union-borrow-move-parent-sibling.rs:58:13
|
LL | let a = *u.y;
| ---- value moved here
-LL | let a = u.x; //~ ERROR use of moved value: `u.x`
+LL | let b = u.x; //~ ERROR use of moved value: `u.x`
| ^^^ value used here after move
|
= note: move occurs because `u` has type `U`, which does not implement the `Copy` trait
-error: aborting due to 3 previous errors
+error: aborting due to 6 previous errors
-For more information about this error, try `rustc --explain E0382`.
+Some errors occurred: E0382, E0502.
+For more information about an error, try `rustc --explain E0382`.
y: Box<Vec<u8>>,
}
+fn use_borrow<T>(_: &T) {}
+
unsafe fn parent_sibling_borrow() {
let mut u = U { x: ((Vec::new(), Vec::new()), Vec::new()) };
let a = &mut u.x.0;
- let a = &u.y; //~ ERROR cannot borrow `u.y`
+ let b = &u.y; //~ ERROR cannot borrow `u.y`
+ use_borrow(a);
}
unsafe fn parent_sibling_move() {
let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) };
let a = u.x.0;
- let a = u.y; //~ ERROR use of moved value: `u.y`
+ let b = u.y; //~ ERROR use of moved value: `u.y`
}
unsafe fn grandparent_sibling_borrow() {
let mut u = U { x: ((Vec::new(), Vec::new()), Vec::new()) };
let a = &mut (u.x.0).0;
- let a = &u.y; //~ ERROR cannot borrow `u.y`
+ let b = &u.y; //~ ERROR cannot borrow `u.y`
+ use_borrow(a);
}
unsafe fn grandparent_sibling_move() {
let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) };
let a = (u.x.0).0;
- let a = u.y; //~ ERROR use of moved value: `u.y`
+ let b = u.y; //~ ERROR use of moved value: `u.y`
}
unsafe fn deref_sibling_borrow() {
let mut u = U { y: Box::default() };
let a = &mut *u.y;
- let a = &u.x; //~ ERROR cannot borrow `u` (via `u.x`)
+ let b = &u.x; //~ ERROR cannot borrow `u` (via `u.x`)
+ use_borrow(a);
}
unsafe fn deref_sibling_move() {
let u = U { x: ((Vec::new(), Vec::new()), Vec::new()) };
let a = *u.y;
- let a = u.x; //~ ERROR use of moved value: `u.x`
+ let b = u.x; //~ ERROR use of moved value: `u.x`
}
error[E0502]: cannot borrow `u.y` as immutable because `u.x.0` is also borrowed as mutable
- --> $DIR/union-borrow-move-parent-sibling.rs:23:14
+ --> $DIR/union-borrow-move-parent-sibling.rs:25:14
|
LL | let a = &mut u.x.0;
| ----- mutable borrow occurs here
-LL | let a = &u.y; //~ ERROR cannot borrow `u.y`
+LL | let b = &u.y; //~ ERROR cannot borrow `u.y`
| ^^^ immutable borrow occurs here
+LL | use_borrow(a);
LL | }
| - mutable borrow ends here
error[E0382]: use of moved value: `u.y`
- --> $DIR/union-borrow-move-parent-sibling.rs:29:9
+ --> $DIR/union-borrow-move-parent-sibling.rs:32:9
|
LL | let a = u.x.0;
| - value moved here
-LL | let a = u.y; //~ ERROR use of moved value: `u.y`
+LL | let b = u.y; //~ ERROR use of moved value: `u.y`
| ^ value used here after move
|
= note: move occurs because `u.y` has type `[type error]`, which does not implement the `Copy` trait
error[E0502]: cannot borrow `u.y` as immutable because `u.x.0.0` is also borrowed as mutable
- --> $DIR/union-borrow-move-parent-sibling.rs:35:14
+ --> $DIR/union-borrow-move-parent-sibling.rs:38:14
|
LL | let a = &mut (u.x.0).0;
| --------- mutable borrow occurs here
-LL | let a = &u.y; //~ ERROR cannot borrow `u.y`
+LL | let b = &u.y; //~ ERROR cannot borrow `u.y`
| ^^^ immutable borrow occurs here
+LL | use_borrow(a);
LL | }
| - mutable borrow ends here
error[E0382]: use of moved value: `u.y`
- --> $DIR/union-borrow-move-parent-sibling.rs:41:9
+ --> $DIR/union-borrow-move-parent-sibling.rs:45:9
|
LL | let a = (u.x.0).0;
| - value moved here
-LL | let a = u.y; //~ ERROR use of moved value: `u.y`
+LL | let b = u.y; //~ ERROR use of moved value: `u.y`
| ^ value used here after move
|
= note: move occurs because `u.y` has type `[type error]`, which does not implement the `Copy` trait
error[E0502]: cannot borrow `u` (via `u.x`) as immutable because `u` is also borrowed as mutable (via `*u.y`)
- --> $DIR/union-borrow-move-parent-sibling.rs:47:14
+ --> $DIR/union-borrow-move-parent-sibling.rs:51:14
|
LL | let a = &mut *u.y;
| ---- mutable borrow occurs here (via `*u.y`)
-LL | let a = &u.x; //~ ERROR cannot borrow `u` (via `u.x`)
+LL | let b = &u.x; //~ ERROR cannot borrow `u` (via `u.x`)
| ^^^ immutable borrow occurs here (via `u.x`)
+LL | use_borrow(a);
LL | }
| - mutable borrow ends here
error[E0382]: use of moved value: `u.x`
- --> $DIR/union-borrow-move-parent-sibling.rs:53:9
+ --> $DIR/union-borrow-move-parent-sibling.rs:58:9
|
LL | let a = *u.y;
| - value moved here
-LL | let a = u.x; //~ ERROR use of moved value: `u.x`
+LL | let b = u.x; //~ ERROR use of moved value: `u.x`
| ^ value used here after move
|
= note: move occurs because `u.x` has type `[type error]`, which does not implement the `Copy` trait