// 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
options.append(Option(*args, value=True))
-o("debug", "rust.debug", "debug mode; disables optimization unless `--enable-optimize` given")
+o("debug", "rust.debug", "enables debugging environment; does not affect optimization of bootstrapped code (use `--disable-optimize` for that)")
o("docs", "build.docs", "build standard library documentation")
o("compiler-docs", "build.compiler-docs", "build compiler documentation")
o("optimize-tests", "rust.optimize-tests", "build tests with optimizations")
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
libssl-dev \
pkg-config \
gcc-arm-none-eabi \
- libnewlib-arm-none-eabi
+ libnewlib-arm-none-eabi \
+ qemu-system-arm
WORKDIR /build
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
# except according to those terms.
import gdb
-import re
import sys
import debugger_pretty_printers_common as rustpp
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!
}
}
///
/// # Examples
///
-/// Here you can see how using `Cell<T>` allows to use mutable field inside
-/// immutable struct (which is also called 'interior mutability').
+/// In this example, you can see that `Cell<T>` enables mutation inside an
+/// immutable struct. In other words, it enables "interior mutability".
///
/// ```
/// use std::cell::Cell;
///
/// let new_value = 100;
///
-/// // ERROR, because my_struct is immutable
+/// // ERROR: `my_struct` is immutable
/// // my_struct.regular_field = new_value;
///
-/// // WORKS, although `my_struct` is immutable, field `special_field` is mutable because it is Cell
+/// // WORKS: although `my_struct` is immutable, `special_field` is a `Cell`,
+/// // which can always be mutated
/// my_struct.special_field.set(new_value);
/// assert_eq!(my_struct.special_field.get(), new_value);
/// ```
/// [`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
}
}
}
-impl<'a, 'tcx> LayoutOf for &'a LateContext<'a, 'tcx> {
+impl<'a, 'tcx> LayoutOf for LateContext<'a, 'tcx> {
type Ty = Ty<'tcx>;
type TyLayout = Result<TyLayout<'tcx>, LayoutError<'tcx>>;
- fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
+ fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
self.tcx.layout_of(self.param_env.and(ty))
}
}
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;
}
// `Option<typeof(function)>` to present a clearer error.
let from = unpack_option_like(self.tcx.global_tcx(), from);
if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (&from.sty, sk_to) {
- if size_to == Pointer.size(self.tcx) {
+ if size_to == Pointer.size(&self.tcx) {
struct_span_err!(self.tcx.sess, span, E0591,
"can't transmute zero-sized type")
.note(&format!("source type: {}", from))
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))
// These are not supposed to be overridden.
#[inline(always)]
- fn pointer_size(self) -> Size {
+ fn pointer_size(&self) -> Size {
self.data_layout().pointer_size
}
//// Trunace the given value to the pointer size; also return whether there was an overflow
- fn truncate_to_ptr(self, val: u128) -> (u64, bool) {
+ fn truncate_to_ptr(&self, val: u128) -> (u64, bool) {
let max_ptr_plus_1 = 1u128 << self.pointer_size().bits();
((val % max_ptr_plus_1) as u64, val >= max_ptr_plus_1)
}
// Overflow checking only works properly on the range from -u64 to +u64.
- fn overflowing_signed_offset(self, val: u64, i: i128) -> (u64, bool) {
+ fn overflowing_signed_offset(&self, val: u64, i: i128) -> (u64, bool) {
// FIXME: is it possible to over/underflow here?
if i < 0 {
// trickery to ensure that i64::min_value() works fine
}
}
- fn overflowing_offset(self, val: u64, i: u64) -> (u64, bool) {
+ fn overflowing_offset(&self, val: u64, i: u64) -> (u64, bool) {
let (res, over1) = val.overflowing_add(i);
let (res, over2) = self.truncate_to_ptr(res as u128);
(res, over1 || over2)
}
- fn signed_offset<'tcx>(self, val: u64, i: i64) -> EvalResult<'tcx, u64> {
+ fn signed_offset<'tcx>(&self, val: u64, i: i64) -> EvalResult<'tcx, u64> {
let (res, over) = self.overflowing_signed_offset(val, i as i128);
if over { err!(Overflow(mir::BinOp::Add)) } else { Ok(res) }
}
- fn offset<'tcx>(self, val: u64, i: u64) -> EvalResult<'tcx, u64> {
+ fn offset<'tcx>(&self, val: u64, i: u64) -> EvalResult<'tcx, u64> {
let (res, over) = self.overflowing_offset(val, i);
if over { err!(Overflow(mir::BinOp::Add)) } else { Ok(res) }
}
- fn wrapping_signed_offset(self, val: u64, i: i64) -> u64 {
+ fn wrapping_signed_offset(&self, val: u64, i: i64) -> u64 {
self.overflowing_signed_offset(val, i as i128).0
}
}
Pointer { alloc_id, offset, tag }
}
- pub fn wrapping_signed_offset(self, i: i64, cx: impl HasDataLayout) -> Self {
+ pub fn wrapping_signed_offset(self, i: i64, cx: &impl HasDataLayout) -> Self {
Pointer::new_with_tag(
self.alloc_id,
Size::from_bytes(cx.data_layout().wrapping_signed_offset(self.offset.bytes(), i)),
)
}
- pub fn overflowing_signed_offset(self, i: i128, cx: impl HasDataLayout) -> (Self, bool) {
+ pub fn overflowing_signed_offset(self, i: i128, cx: &impl HasDataLayout) -> (Self, bool) {
let (res, over) = cx.data_layout().overflowing_signed_offset(self.offset.bytes(), i);
(Pointer::new_with_tag(self.alloc_id, Size::from_bytes(res), self.tag), over)
}
- pub fn signed_offset(self, i: i64, cx: impl HasDataLayout) -> EvalResult<'tcx, Self> {
+ pub fn signed_offset(self, i: i64, cx: &impl HasDataLayout) -> EvalResult<'tcx, Self> {
Ok(Pointer::new_with_tag(
self.alloc_id,
Size::from_bytes(cx.data_layout().signed_offset(self.offset.bytes(), i)?),
))
}
- pub fn overflowing_offset(self, i: Size, cx: impl HasDataLayout) -> (Self, bool) {
+ pub fn overflowing_offset(self, i: Size, cx: &impl HasDataLayout) -> (Self, bool) {
let (res, over) = cx.data_layout().overflowing_offset(self.offset.bytes(), i.bytes());
(Pointer::new_with_tag(self.alloc_id, Size::from_bytes(res), self.tag), over)
}
- pub fn offset(self, i: Size, cx: impl HasDataLayout) -> EvalResult<'tcx, Self> {
+ pub fn offset(self, i: Size, cx: &impl HasDataLayout) -> EvalResult<'tcx, Self> {
Ok(Pointer::new_with_tag(
self.alloc_id,
Size::from_bytes(cx.data_layout().offset(self.offset.bytes(), i.bytes())?),
pub fn new_slice(
val: Scalar,
len: u64,
- cx: impl HasDataLayout
+ cx: &impl HasDataLayout
) -> Self {
ConstValue::ScalarPair(val, Scalar::Bits {
bits: len as u128,
}
#[inline]
- pub fn ptr_null(cx: impl HasDataLayout) -> Self {
+ pub fn ptr_null(cx: &impl HasDataLayout) -> Self {
Scalar::Bits {
bits: 0,
size: cx.data_layout().pointer_size.bytes() as u8,
}
#[inline]
- pub fn ptr_signed_offset(self, i: i64, cx: impl HasDataLayout) -> EvalResult<'tcx, Self> {
- let layout = cx.data_layout();
+ pub fn ptr_signed_offset(self, i: i64, cx: &impl HasDataLayout) -> EvalResult<'tcx, Self> {
+ let dl = cx.data_layout();
match self {
Scalar::Bits { bits, size } => {
- assert_eq!(size as u64, layout.pointer_size.bytes());
+ assert_eq!(size as u64, dl.pointer_size.bytes());
Ok(Scalar::Bits {
- bits: layout.signed_offset(bits as u64, i)? as u128,
+ bits: dl.signed_offset(bits as u64, i)? as u128,
size,
})
}
- Scalar::Ptr(ptr) => ptr.signed_offset(i, layout).map(Scalar::Ptr),
+ Scalar::Ptr(ptr) => ptr.signed_offset(i, dl).map(Scalar::Ptr),
}
}
#[inline]
- pub fn ptr_offset(self, i: Size, cx: impl HasDataLayout) -> EvalResult<'tcx, Self> {
- let layout = cx.data_layout();
+ pub fn ptr_offset(self, i: Size, cx: &impl HasDataLayout) -> EvalResult<'tcx, Self> {
+ let dl = cx.data_layout();
match self {
Scalar::Bits { bits, size } => {
- assert_eq!(size as u64, layout.pointer_size.bytes());
+ assert_eq!(size as u64, dl.pointer_size.bytes());
Ok(Scalar::Bits {
- bits: layout.offset(bits as u64, i.bytes())? as u128,
+ bits: dl.offset(bits as u64, i.bytes())? as u128,
size,
})
}
- Scalar::Ptr(ptr) => ptr.offset(i, layout).map(Scalar::Ptr),
+ Scalar::Ptr(ptr) => ptr.offset(i, dl).map(Scalar::Ptr),
}
}
#[inline]
- pub fn ptr_wrapping_signed_offset(self, i: i64, cx: impl HasDataLayout) -> Self {
- let layout = cx.data_layout();
+ pub fn ptr_wrapping_signed_offset(self, i: i64, cx: &impl HasDataLayout) -> Self {
+ let dl = cx.data_layout();
match self {
Scalar::Bits { bits, size } => {
- assert_eq!(size as u64, layout.pointer_size.bytes());
+ assert_eq!(size as u64, dl.pointer_size.bytes());
Scalar::Bits {
- bits: layout.wrapping_signed_offset(bits as u64, i) as u128,
+ bits: dl.wrapping_signed_offset(bits as u64, i) as u128,
size,
}
}
- Scalar::Ptr(ptr) => Scalar::Ptr(ptr.wrapping_signed_offset(i, layout)),
+ Scalar::Ptr(ptr) => Scalar::Ptr(ptr.wrapping_signed_offset(i, dl)),
}
}
#[inline]
- pub fn is_null_ptr(self, cx: impl HasDataLayout) -> bool {
+ pub fn is_null_ptr(self, cx: &impl HasDataLayout) -> bool {
match self {
Scalar::Bits { bits, size } => {
assert_eq!(size as u64, cx.data_layout().pointer_size.bytes());
Ok(b as u64)
}
- pub fn to_usize(self, cx: impl HasDataLayout) -> EvalResult<'static, u64> {
+ pub fn to_usize(self, cx: &impl HasDataLayout) -> EvalResult<'static, u64> {
let b = self.to_bits(cx.data_layout().pointer_size)?;
assert_eq!(b as u64 as u128, b);
Ok(b as u64)
Ok(b as i64)
}
- pub fn to_isize(self, cx: impl HasDataLayout) -> EvalResult<'static, i64> {
+ pub fn to_isize(self, cx: &impl HasDataLayout) -> EvalResult<'static, i64> {
let b = self.to_bits(cx.data_layout().pointer_size)?;
let b = sign_extend(b, cx.data_layout().pointer_size) as i128;
assert_eq!(b as i64 as i128, b);
/// 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
if !cg.remark.is_empty() && debuginfo == DebugInfo::None {
early_warn(
error_format,
- "-C remark will not show source locations without \
- --debuginfo",
+ "-C remark requires \"-C debuginfo=n\" to show source locations",
);
}
let fuel = self.optimization_fuel_limit.get();
ret = fuel != 0;
if fuel == 0 && !self.out_of_fuel.get() {
- println!("optimization-fuel-exhausted: {}", msg());
+ eprintln!("optimization-fuel-exhausted: {}", msg());
self.out_of_fuel.set(true);
} else if fuel > 0 {
self.optimization_fuel_limit.set(fuel - 1);
ty::RegionKind::ReLateBound(_, _),
) => {}
- (ty::RegionKind::ReLateBound(_, _), _) => {
+ (ty::RegionKind::ReLateBound(_, _), _) |
+ (_, ty::RegionKind::ReVar(_)) => {
+ // One of these is true:
// The new predicate has a HRTB in a spot where the old
// predicate does not (if they both had a HRTB, the previous
- // match arm would have executed).
+ // match arm would have executed). A HRBT is a 'stricter'
+ // bound than anything else, so we want to keep the newer
+ // predicate (with the HRBT) in place of the old predicate.
//
- // The means we want to remove the older predicate from
- // user_computed_preds, since having both it and the new
+ // OR
+ //
+ // The old predicate has a region variable where the new
+ // predicate has some other kind of region. An region
+ // variable isn't something we can actually display to a user,
+ // so we choose ther new predicate (which doesn't have a region
+ // varaible).
+ //
+ // In both cases, we want to remove the old predicate,
+ // from user_computed_preds, and replace it with the new
+ // one. Having both the old and the new
// predicate in a ParamEnv would confuse SelectionContext
+ //
// We're currently in the predicate passed to 'retain',
// so we return 'false' to remove the old predicate from
// user_computed_preds
return false;
}
- (_, ty::RegionKind::ReLateBound(_, _)) => {
- // This is the opposite situation as the previous arm - the
- // old predicate has a HRTB lifetime in a place where the
- // new predicate does not. We want to leave the old
+ (_, ty::RegionKind::ReLateBound(_, _)) |
+ (ty::RegionKind::ReVar(_), _) => {
+ // This is the opposite situation as the previous arm.
+ // One of these is true:
+ //
+ // The old predicate has a HRTB lifetime in a place where the
+ // new predicate does not.
+ //
+ // OR
+ //
+ // The new predicate has a region variable where the old
+ // predicate has some other type of region.
+ //
+ // We want to leave the old
// predicate in user_computed_preds, and skip adding
// new_pred to user_computed_params.
should_add_new = false
- }
+ },
_ => {}
}
}
));
let tcx = self.tcx;
if let Some(len) = len.val.try_to_scalar().and_then(|scalar| {
- scalar.to_usize(tcx).ok()
+ scalar.to_usize(&tcx).ok()
}) {
flags.push((
"_Self".to_owned(),
use mir::interpret::{GlobalId, ErrorHandled};
use ty::{self, Ty, TypeFoldable, ToPolyTraitRef, ToPredicate};
use ty::error::ExpectedFound;
-use rustc_data_structures::obligation_forest::{Error, ForestObligation, ObligationForest};
-use rustc_data_structures::obligation_forest::{ObligationProcessor, ProcessResult};
+use rustc_data_structures::obligation_forest::{DoCompleted, Error, ForestObligation};
+use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor};
+use rustc_data_structures::obligation_forest::{ProcessResult};
use std::marker::PhantomData;
use hir::def_id::DefId;
let outcome = self.predicates.process_obligations(&mut FulfillProcessor {
selcx,
register_region_obligations: self.register_region_obligations
- });
+ }, DoCompleted::No);
debug!("select: outcome={:#?}", outcome);
// FIXME: if we kept the original cache key, we could mark projection
pub trait IntegerExt {
fn to_ty<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, signed: bool) -> Ty<'tcx>;
- fn from_attr<C: HasDataLayout>(cx: C, ity: attr::IntType) -> Integer;
+ fn from_attr<C: HasDataLayout>(cx: &C, ity: attr::IntType) -> Integer;
fn repr_discr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
ty: Ty<'tcx>,
repr: &ReprOptions,
}
/// Get the Integer type from an attr::IntType.
- fn from_attr<C: HasDataLayout>(cx: C, ity: attr::IntType) -> Integer {
+ fn from_attr<C: HasDataLayout>(cx: &C, ity: attr::IntType) -> Integer {
let dl = cx.data_layout();
match ity {
let min_default = I8;
if let Some(ity) = repr.int {
- let discr = Integer::from_attr(tcx, ity);
+ let discr = Integer::from_attr(&tcx, ity);
let fit = if ity.is_signed() { signed_fit } else { unsigned_fit };
if discr < fit {
bug!("Integer::repr_discr: `#[repr]` hint too small for \
};
}
-#[derive(Copy, Clone)]
pub struct LayoutCx<'tcx, C> {
pub tcx: C,
pub param_env: ty::ParamEnv<'tcx>
}
impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
- fn layout_raw_uncached(self, ty: Ty<'tcx>)
+ fn layout_raw_uncached(&self, ty: Ty<'tcx>)
-> Result<&'tcx LayoutDetails, LayoutError<'tcx>> {
let tcx = self.tcx;
let param_env = self.param_env;
let (mut min, mut max) = (i128::max_value(), i128::min_value());
let discr_type = def.repr.discr_type();
- let bits = Integer::from_attr(tcx, discr_type).size().bits();
+ let bits = Integer::from_attr(self, discr_type).size().bits();
for (i, discr) in def.discriminants(tcx).enumerate() {
if variants[i].iter().any(|f| f.abi.is_uninhabited()) {
continue;
/// This is invoked by the `layout_raw` query to record the final
/// layout of each type.
#[inline]
- fn record_layout_for_printing(self, layout: TyLayout<'tcx>) {
+ fn record_layout_for_printing(&self, layout: TyLayout<'tcx>) {
// If we are running with `-Zprint-type-sizes`, record layouts for
// dumping later. Ignore layouts that are done with non-empty
// environments or non-monomorphic layouts, as the user only wants
self.record_layout_for_printing_outlined(layout)
}
- fn record_layout_for_printing_outlined(self, layout: TyLayout<'tcx>) {
+ fn record_layout_for_printing_outlined(&self, layout: TyLayout<'tcx>) {
// (delay format until we actually need it)
let record = |kind, packed, opt_discr_size, variants| {
let type_desc = format!("{:?}", layout.ty);
/// Computes the layout of a type. Note that this implicitly
/// executes in "reveal all" mode.
- fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
+ fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
let param_env = self.param_env.with_reveal_all();
let ty = self.tcx.normalize_erasing_regions(param_env, ty);
let details = self.tcx.layout_raw(param_env.and(ty))?;
/// Computes the layout of a type. Note that this implicitly
/// executes in "reveal all" mode.
- fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
+ fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
let param_env = self.param_env.with_reveal_all();
let ty = self.tcx.normalize_erasing_regions(param_env, ty);
let details = self.tcx.layout_raw(param_env.and(ty))?;
where C: LayoutOf<Ty = Ty<'tcx>> + HasTyCtxt<'tcx>,
C::TyLayout: MaybeResult<TyLayout<'tcx>>
{
- fn for_variant(this: TyLayout<'tcx>, cx: C, variant_index: usize) -> TyLayout<'tcx> {
+ fn for_variant(this: TyLayout<'tcx>, cx: &C, variant_index: usize) -> TyLayout<'tcx> {
let details = match this.variants {
Variants::Single { index } if index == variant_index => this.details,
}
}
- fn field(this: TyLayout<'tcx>, cx: C, i: usize) -> C::TyLayout {
+ fn field(this: TyLayout<'tcx>, cx: &C, i: usize) -> C::TyLayout {
let tcx = cx.tcx();
cx.layout_of(match this.ty.sty {
ty::Bool |
Variants::Tagged { tag: ref discr, .. } |
Variants::NicheFilling { niche: ref discr, .. } => {
assert_eq!(i, 0);
- let layout = LayoutDetails::scalar(tcx, discr.clone());
+ let layout = LayoutDetails::scalar(cx, discr.clone());
return MaybeResult::from_ok(TyLayout {
details: tcx.intern_layout(layout),
ty: discr.value.to_ty(tcx)
impl Niche {
fn reserve<'a, 'tcx>(
&self,
- cx: LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>>,
+ cx: &LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>>,
count: u128,
) -> Option<(u128, Scalar)> {
if count > self.available {
/// Find the offset of a niche leaf field, starting from
/// the given type and recursing through aggregates.
// FIXME(eddyb) traverse already optimized enums.
- fn find_niche(self, layout: TyLayout<'tcx>) -> Result<Option<Niche>, LayoutError<'tcx>> {
+ fn find_niche(&self, layout: TyLayout<'tcx>) -> Result<Option<Niche>, LayoutError<'tcx>> {
let scalar_niche = |scalar: &Scalar, offset| {
let Scalar { value, valid_range: ref v } = *scalar;
match self.ty.sty {
ty::Int(ity) => {
let bits = ty::tls::with(|tcx| {
- Integer::from_attr(tcx, SignedInt(ity)).size().bits()
+ Integer::from_attr(&tcx, SignedInt(ity)).size().bits()
});
let x = self.val as i128;
// sign extend the raw representation to be an i128
}
pub fn checked_add<'a, 'gcx>(self, tcx: TyCtxt<'a, 'gcx, 'tcx>, n: u128) -> (Self, bool) {
let (int, signed) = match self.ty.sty {
- Int(ity) => (Integer::from_attr(tcx, SignedInt(ity)), true),
- Uint(uty) => (Integer::from_attr(tcx, UnsignedInt(uty)), false),
+ Int(ity) => (Integer::from_attr(&tcx, SignedInt(ity)), true),
+ Uint(uty) => (Integer::from_attr(&tcx, UnsignedInt(uty)), false),
_ => bug!("non integer discriminant"),
};
}
});
+ // We always generate bitcode through ThinLTOBuffers,
+ // which do not support anonymous globals
+ if config.bitcode_needed() {
+ let pass = llvm::LLVMRustFindAndCreatePass("name-anon-globals\0".as_ptr() as *const _);
+ llvm::LLVMRustAddPass(pm, pass.unwrap());
+ }
+
if config.verify_llvm_ir {
let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _);
llvm::LLVMRustAddPass(pm, pass.unwrap());
use attributes;
use back::bytecode::{self, RLIB_BYTECODE_EXTENSION};
-use back::lto::{self, ModuleBuffer, ThinBuffer, SerializedModule};
+use back::lto::{self, ThinBuffer, SerializedModule};
use back::link::{self, get_linker, remove};
use base;
use consts;
self.merge_functions = sess.opts.optimize == config::OptLevel::Default ||
sess.opts.optimize == config::OptLevel::Aggressive;
}
+
+ pub fn bitcode_needed(&self) -> bool {
+ self.emit_bc || self.obj_is_bitcode
+ || self.emit_bc_compressed || self.embed_bitcode
+ }
}
/// Assembler name and command used by codegen when no_integrated_as is enabled
// Some options cause LLVM bitcode to be emitted, which uses ThinLTOBuffers, so we need
// to make sure we run LLVM's NameAnonGlobals pass when emitting bitcode; otherwise
// we'll get errors in LLVM.
- let using_thin_buffers = llvm::LLVMRustThinLTOAvailable() && (config.emit_bc
- || config.obj_is_bitcode || config.emit_bc_compressed || config.embed_bitcode);
+ let using_thin_buffers = config.bitcode_needed();
let mut have_name_anon_globals_pass = false;
if !config.no_prepopulate_passes {
llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod);
if write_bc || config.emit_bc_compressed || config.embed_bitcode {
- let thin;
- let old;
- let data = if llvm::LLVMRustThinLTOAvailable() {
- thin = ThinBuffer::new(llmod);
- thin.data()
- } else {
- old = ModuleBuffer::new(llmod);
- old.data()
- };
+ let thin = ThinBuffer::new(llmod);
+ let data = thin.data();
timeline.record("make-bc");
if write_bc {
// builds we don't actually want to LTO the allocator modules if
// it shows up. This is due to various linker shenanigans that
// we'll encounter later.
- //
- // Additionally here's where we also factor in the current LLVM
- // version. If it doesn't support ThinLTO we skip this.
Lto::ThinLocal => {
- module.kind != ModuleKind::Allocator &&
- unsafe { llvm::LLVMRustThinLTOAvailable() }
+ module.kind != ModuleKind::Allocator
}
};
{
check_for_rustc_errors_attr(tcx);
- if let Some(true) = tcx.sess.opts.debugging_opts.thinlto {
- if unsafe { !llvm::LLVMRustThinLTOAvailable() } {
- tcx.sess.fatal("this compiler's LLVM does not support ThinLTO");
- }
- }
-
- if (tcx.sess.opts.debugging_opts.pgo_gen.is_some() ||
- !tcx.sess.opts.debugging_opts.pgo_use.is_empty()) &&
- unsafe { !llvm::LLVMRustPGOAvailable() }
- {
- tcx.sess.fatal("this compiler's LLVM does not support PGO");
- }
-
let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx);
// Codegen the metadata.
}
}
- 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);
}
}
}
}
-impl ty::layout::HasDataLayout for &'a CodegenCx<'ll, 'tcx> {
+impl ty::layout::HasDataLayout for CodegenCx<'ll, 'tcx> {
fn data_layout(&self) -> &ty::layout::TargetDataLayout {
&self.tcx.data_layout
}
}
-impl HasTargetSpec for &'a CodegenCx<'ll, 'tcx> {
+impl HasTargetSpec for CodegenCx<'ll, 'tcx> {
fn target_spec(&self) -> &Target {
&self.tcx.sess.target.target
}
}
-impl ty::layout::HasTyCtxt<'tcx> for &'a CodegenCx<'ll, 'tcx> {
- fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> {
+impl ty::layout::HasTyCtxt<'tcx> for CodegenCx<'ll, 'tcx> {
+ fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
self.tcx
}
}
-impl LayoutOf for &'a CodegenCx<'ll, 'tcx> {
+impl LayoutOf for CodegenCx<'ll, 'tcx> {
type Ty = Ty<'tcx>;
type TyLayout = TyLayout<'tcx>;
- fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
+ fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
self.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty))
.unwrap_or_else(|e| if let LayoutError::SizeOverflow(_) = e {
self.sess().fatal(&e.to_string())
"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);
pub fn LLVMRustModuleBufferFree(p: &'static mut ModuleBuffer);
pub fn LLVMRustModuleCost(M: &Module) -> u64;
- pub fn LLVMRustThinLTOAvailable() -> bool;
- pub fn LLVMRustPGOAvailable() -> bool;
pub fn LLVMRustThinLTOBufferCreate(M: &Module) -> &'static mut ThinLTOBuffer;
pub fn LLVMRustThinLTOBufferFree(M: &'static mut ThinLTOBuffer);
pub fn LLVMRustThinLTOBufferPtr(M: &ThinLTOBuffer) -> *const c_char;
pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll Value {
let mut llvals = Vec::with_capacity(alloc.relocations.len() + 1);
- let layout = cx.data_layout();
- let pointer_size = layout.pointer_size.bytes() as usize;
+ let dl = cx.data_layout();
+ let pointer_size = dl.pointer_size.bytes() as usize;
let mut next_offset = 0;
for &(offset, ((), alloc_id)) in alloc.relocations.iter() {
llvals.push(C_bytes(cx, &alloc.bytes[next_offset..offset]));
}
let ptr_offset = read_target_uint(
- layout.endian,
+ dl.endian,
&alloc.bytes[offset..(offset + pointer_size)],
).expect("const_alloc_to_llvm: could not read relocation pointer") as u64;
llvals.push(scalar_to_llvm(
#[derive(Debug)]
pub struct Outcome<O, E> {
/// Obligations that were completely evaluated, including all
- /// (transitive) subobligations.
- pub completed: Vec<O>,
+ /// (transitive) subobligations. Only computed if requested.
+ pub completed: Option<Vec<O>>,
/// Backtrace of obligations that were found to be in error.
pub errors: Vec<Error<O, E>>,
pub stalled: bool,
}
+/// Should `process_obligations` compute the `Outcome::completed` field of its
+/// result?
+#[derive(PartialEq)]
+pub enum DoCompleted {
+ No,
+ Yes,
+}
+
#[derive(Debug, PartialEq, Eq)]
pub struct Error<O, E> {
pub error: E,
});
}
}
- let successful_obligations = self.compress();
- assert!(successful_obligations.is_empty());
+ let successful_obligations = self.compress(DoCompleted::Yes);
+ assert!(successful_obligations.unwrap().is_empty());
errors
}
/// be called in a loop until `outcome.stalled` is false.
///
/// This CANNOT be unrolled (presently, at least).
- pub fn process_obligations<P>(&mut self, processor: &mut P) -> Outcome<O, P::Error>
+ pub fn process_obligations<P>(&mut self, processor: &mut P, do_completed: DoCompleted)
+ -> Outcome<O, P::Error>
where P: ObligationProcessor<Obligation=O>
{
debug!("process_obligations(len={})", self.nodes.len());
// There's no need to perform marking, cycle processing and compression when nothing
// changed.
return Outcome {
- completed: vec![],
+ completed: if do_completed == DoCompleted::Yes { Some(vec![]) } else { None },
errors,
stalled,
};
self.process_cycles(processor);
// Now we have to compress the result
- let completed_obligations = self.compress();
+ let completed = self.compress(do_completed);
debug!("process_obligations: complete");
Outcome {
- completed: completed_obligations,
+ completed,
errors,
stalled,
}
/// Beforehand, all nodes must be marked as `Done` and no cycles
/// on these nodes may be present. This is done by e.g. `process_cycles`.
#[inline(never)]
- fn compress(&mut self) -> Vec<O> {
+ fn compress(&mut self, do_completed: DoCompleted) -> Option<Vec<O>> {
let nodes_len = self.nodes.len();
let mut node_rewrites: Vec<_> = self.scratch.take().unwrap();
node_rewrites.extend(0..nodes_len);
if dead_nodes == 0 {
node_rewrites.truncate(0);
self.scratch = Some(node_rewrites);
- return vec![];
+ return if do_completed == DoCompleted::Yes { Some(vec![]) } else { None };
}
// Pop off all the nodes we killed and extract the success
// stories.
- let successful = (0..dead_nodes)
- .map(|_| self.nodes.pop().unwrap())
- .flat_map(|node| {
- match node.state.get() {
- NodeState::Error => None,
- NodeState::Done => Some(node.obligation),
- _ => unreachable!()
- }
- })
- .collect();
+ let successful = if do_completed == DoCompleted::Yes {
+ Some((0..dead_nodes)
+ .map(|_| self.nodes.pop().unwrap())
+ .flat_map(|node| {
+ match node.state.get() {
+ NodeState::Error => None,
+ NodeState::Done => Some(node.obligation),
+ _ => unreachable!()
+ }
+ })
+ .collect())
+ } else {
+ self.nodes.truncate(self.nodes.len() - dead_nodes);
+ None
+ };
self.apply_rewrites(&node_rewrites);
node_rewrites.truncate(0);
#![cfg(test)]
-use super::{Error, ObligationForest, ObligationProcessor, Outcome, ProcessResult};
+use super::{Error, DoCompleted, ObligationForest, ObligationProcessor, Outcome, ProcessResult};
use std::fmt;
use std::marker::PhantomData;
"C" => ProcessResult::Changed(vec![]),
_ => unreachable!(),
}
- }, |_| {}));
- assert_eq!(ok, vec!["C"]);
+ }, |_| {}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap(), vec!["C"]);
assert_eq!(err,
vec![Error {
error: "B is for broken",
"D" => ProcessResult::Changed(vec!["D.1", "D.2"]),
_ => unreachable!(),
}
- }, |_| {}));
- assert_eq!(ok, Vec::<&'static str>::new());
+ }, |_| {}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap(), Vec::<&'static str>::new());
assert_eq!(err, Vec::new());
"D.2" => ProcessResult::Changed(vec!["D.2.i"]),
_ => unreachable!(),
}
- }, |_| {}));
- assert_eq!(ok, vec!["A.3", "A.1", "A.3.i"]);
+ }, |_| {}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap(), vec!["A.3", "A.1", "A.3.i"]);
assert_eq!(err,
vec![Error {
error: "A is for apple",
"D.2.i" => ProcessResult::Changed(vec![]),
_ => panic!("unexpected obligation {:?}", obligation),
}
- }, |_| {}));
- assert_eq!(ok, vec!["D.2.i", "D.2"]);
+ }, |_| {}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap(), vec!["D.2.i", "D.2"]);
assert_eq!(err,
vec![Error {
error: "D is for dumb",
"A" => ProcessResult::Changed(vec!["A.1", "A.2", "A.3"]),
_ => unreachable!(),
}
- }, |_| {}));
- assert!(ok.is_empty());
+ }, |_| {}), DoCompleted::Yes);
+ assert!(ok.unwrap().is_empty());
assert!(err.is_empty());
let Outcome { completed: ok, errors: err, .. } =
"A.3" => ProcessResult::Changed(vec![]),
_ => unreachable!(),
}
- }, |_| {}));
- assert_eq!(ok, vec!["A.3", "A.1"]);
+ }, |_| {}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap(), vec!["A.3", "A.1"]);
assert!(err.is_empty());
let Outcome { completed: ok, errors: err, .. } =
"A.2.ii" => ProcessResult::Changed(vec![]),
_ => unreachable!(),
}
- }, |_| {}));
- assert_eq!(ok, vec!["A.2.ii"]);
+ }, |_| {}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap(), vec!["A.2.ii"]);
assert!(err.is_empty());
let Outcome { completed: ok, errors: err, .. } =
"A.2.i.a" => ProcessResult::Changed(vec![]),
_ => unreachable!(),
}
- }, |_| {}));
- assert_eq!(ok, vec!["A.2.i.a", "A.2.i", "A.2", "A"]);
+ }, |_| {}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap(), vec!["A.2.i.a", "A.2.i", "A.2", "A"]);
assert!(err.is_empty());
let Outcome { completed: ok, errors: err, .. } =
- forest.process_obligations(&mut C(|_| unreachable!(), |_| {}));
+ forest.process_obligations(&mut C(|_| unreachable!(), |_| {}),
+ DoCompleted::Yes);
- assert!(ok.is_empty());
+ assert!(ok.unwrap().is_empty());
assert!(err.is_empty());
}
"A" => ProcessResult::Changed(vec!["A.1", "A.2", "A.3"]),
_ => unreachable!(),
}
- }, |_|{}));
- assert_eq!(ok.len(), 0);
+ }, |_|{}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap().len(), 0);
assert_eq!(err.len(), 0);
let errors = forest.to_errors(());
assert_eq!(errors[0].backtrace, vec!["A.1", "A"]);
"A" => ProcessResult::Changed(vec!["A.1", "A.2"]),
_ => unreachable!(),
}
- }, |_|{}));
- assert_eq!(ok.len(), 0);
+ }, |_|{}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap().len(), 0);
assert_eq!(err.len(), 0);
let Outcome { completed: ok, errors: err, .. } =
"A.2" => ProcessResult::Changed(vec!["D"]),
_ => unreachable!(),
}
- }, |_|{}));
- assert_eq!(ok.len(), 0);
+ }, |_|{}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap().len(), 0);
assert_eq!(err.len(), 0);
let mut d_count = 0;
"D" => { d_count += 1; ProcessResult::Changed(vec![]) },
_ => unreachable!(),
}
- }, |_|{}));
+ }, |_|{}), DoCompleted::Yes);
assert_eq!(d_count, 1);
- assert_eq!(ok, vec!["D", "A.2", "A.1", "A"]);
+ assert_eq!(ok.unwrap(), vec!["D", "A.2", "A.1", "A"]);
assert_eq!(err.len(), 0);
let errors = forest.to_errors(());
"A'" => ProcessResult::Changed(vec!["A'.1", "A'.2"]),
_ => unreachable!(),
}
- }, |_|{}));
- assert_eq!(ok.len(), 0);
+ }, |_|{}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap().len(), 0);
assert_eq!(err.len(), 0);
let Outcome { completed: ok, errors: err, .. } =
"A'.2" => ProcessResult::Changed(vec!["D'"]),
_ => unreachable!(),
}
- }, |_|{}));
- assert_eq!(ok.len(), 0);
+ }, |_|{}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap().len(), 0);
assert_eq!(err.len(), 0);
let mut d_count = 0;
"D'" => { d_count += 1; ProcessResult::Error("operation failed") },
_ => unreachable!(),
}
- }, |_|{}));
+ }, |_|{}), DoCompleted::Yes);
assert_eq!(d_count, 1);
- assert_eq!(ok.len(), 0);
+ assert_eq!(ok.unwrap().len(), 0);
assert_eq!(err, vec![super::Error {
error: "operation failed",
backtrace: vec!["D'", "A'.1", "A'"]
"A: Sized" | "B: Sized" | "C: Sized" => ProcessResult::Changed(vec![]),
_ => unreachable!(),
}
- }, |_|{}));
- assert_eq!(ok, vec!["C: Sized", "B: Sized", "A: Sized"]);
+ }, |_|{}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap(), vec!["C: Sized", "B: Sized", "A: Sized"]);
assert_eq!(err.len(), 0);
forest.register_obligation("(A,B,C): Sized");
]),
_ => unreachable!(),
}
- }, |_|{}));
- assert_eq!(ok, vec!["(A,B,C): Sized"]);
+ }, |_|{}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap(), vec!["(A,B,C): Sized"]);
assert_eq!(err.len(), 0);
}
"C2" => ProcessResult::Changed(vec![]),
_ => unreachable!(),
}
- }, |_|{}));
- assert_eq!(ok, vec!["C2", "C1"]);
+ }, |_|{}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap(), vec!["C2", "C1"]);
assert_eq!(err.len(), 0);
let Outcome { completed: ok, errors: err, .. } =
"B" => ProcessResult::Changed(vec!["D"]),
_ => unreachable!(),
}
- }, |_|{}));
- assert_eq!(ok.len(), 0);
+ }, |_|{}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap().len(), 0);
assert_eq!(err.len(), 0);
let Outcome { completed: ok, errors: err, .. } =
"E" => ProcessResult::Error("E is for error"),
_ => unreachable!(),
}
- }, |_|{}));
- assert_eq!(ok.len(), 0);
+ }, |_|{}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap().len(), 0);
assert_eq!(err, vec![super::Error {
error: "E is for error",
backtrace: vec!["E", "A"]
"D" => ProcessResult::Error("D is dead"),
_ => unreachable!(),
}
- }, |_|{}));
- assert_eq!(ok.len(), 0);
+ }, |_|{}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap().len(), 0);
assert_eq!(err, vec![super::Error {
error: "D is dead",
backtrace: vec!["D"]
"B" => ProcessResult::Changed(vec!["A"]),
_ => unreachable!(),
}
- }, |_|{}));
- assert_eq!(ok.len(), 0);
+ }, |_|{}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap().len(), 0);
assert_eq!(err, vec![super::Error {
error: "An error",
backtrace: vec!["A"]
"B" => ProcessResult::Changed(vec!["A"]),
_ => unreachable!(),
}
- }, |_|{}));
- assert_eq!(ok.len(), 0);
+ }, |_|{}), DoCompleted::Yes);
+ assert_eq!(ok.unwrap().len(), 0);
assert_eq!(err, vec![super::Error {
error: "An error",
backtrace: vec!["A"]
control.compilation_done.callback = box move |state| {
old_callback(state);
let sess = state.session;
- println!("Fuel used by {}: {}",
+ eprintln!("Fuel used by {}: {}",
sess.print_fuel_crate.as_ref().unwrap(),
sess.print_fuel.get());
}
let (t, actually) = match ty {
ty::Int(t) => {
let ity = attr::IntType::SignedInt(t);
- let bits = layout::Integer::from_attr(cx.tcx, ity).size().bits();
+ let bits = layout::Integer::from_attr(&cx.tcx, ity).size().bits();
let actually = (val << (128 - bits)) as i128 >> (128 - bits);
(format!("{:?}", t), actually.to_string())
}
ty::Uint(t) => {
let ity = attr::IntType::UnsignedInt(t);
- let bits = layout::Integer::from_attr(cx.tcx, ity).size().bits();
+ let bits = layout::Integer::from_attr(&cx.tcx, ity).size().bits();
let actually = (val << (128 - bits)) >> (128 - bits);
(format!("{:?}", t), actually.to_string())
}
Ok(layout) => {
let variants = &layout.variants;
if let layout::Variants::Tagged { ref variants, ref tag, .. } = variants {
- let discr_size = tag.value.size(cx.tcx).bytes();
+ let discr_size = tag.value.size(&cx.tcx).bytes();
debug!("enum `{}` is {} bytes large with layout:\n{:#?}",
t, layout.size.bytes(), layout);
declare_lint! {
pub UNUSED_MUST_USE,
Warn,
- "unused result of a type flagged as #[must_use]"
+ "unused result of a type flagged as #[must_use]",
+ report_in_external_macro: true
}
declare_lint! {
LitKind::Str(ref s, _) => {
let s = s.as_str();
let id = self.tcx.allocate_bytes(s.as_bytes());
- ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, self.tcx)
+ ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &self.tcx)
},
LitKind::ByteStr(ref data) => {
let id = self.tcx.allocate_bytes(data);
}
ty::Int(ity) if exhaustive_integer_patterns => {
// FIXME(49937): refactor these bit manipulations into interpret.
- let bits = Integer::from_attr(cx.tcx, SignedInt(ity)).size().bits() as u128;
+ let bits = Integer::from_attr(&cx.tcx, SignedInt(ity)).size().bits() as u128;
let min = 1u128 << (bits - 1);
let max = (1u128 << (bits - 1)) - 1;
vec![ConstantRange(min, max, pcx.ty, RangeEnd::Included)]
}
ty::Uint(uty) if exhaustive_integer_patterns => {
// FIXME(49937): refactor these bit manipulations into interpret.
- let bits = Integer::from_attr(cx.tcx, UnsignedInt(uty)).size().bits() as u128;
+ let bits = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size().bits() as u128;
let max = !0u128 >> (128 - bits);
vec![ConstantRange(0, max, pcx.ty, RangeEnd::Included)]
}
fn signed_bias(tcx: TyCtxt<'_, 'tcx, 'tcx>, ty: Ty<'tcx>) -> u128 {
match ty.sty {
ty::Int(ity) => {
- let bits = Integer::from_attr(tcx, SignedInt(ity)).size().bits() as u128;
+ let bits = Integer::from_attr(&tcx, SignedInt(ity)).size().bits() as u128;
1u128 << (bits - 1)
}
_ => 0
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
LitKind::Str(ref s, _) => {
let s = s.as_str();
let id = tcx.allocate_bytes(s.as_bytes());
- ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, tcx)
+ ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx)
},
LitKind::ByteStr(ref data) => {
let id = tcx.allocate_bytes(data);
let val = Immediate::new_slice(
ptr,
length.unwrap_usize(self.tcx.tcx),
- self.tcx.tcx,
+ self,
);
self.write_immediate(val, dest)
}
src_field.into()
}
Err(..) => {
- let src_field_layout = src.layout.field(&self, i)?;
+ let src_field_layout = src.layout.field(self, i)?;
// this must be a field covering the entire thing
assert_eq!(src.layout.fields.offset(i).bytes(), 0);
assert_eq!(src_field_layout.size, src.layout.size);
}
}
-impl<'b, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> HasDataLayout
- for &'b EvalContext<'a, 'mir, 'tcx, M>
+impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> HasDataLayout
+ for EvalContext<'a, 'mir, 'tcx, M>
{
#[inline]
fn data_layout(&self) -> &layout::TargetDataLayout {
}
}
-impl<'c, 'b, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> HasDataLayout
- for &'c &'b mut EvalContext<'a, 'mir, 'tcx, M>
-{
- #[inline]
- fn data_layout(&self) -> &layout::TargetDataLayout {
- &self.tcx.data_layout
- }
-}
-
-impl<'b, 'a, 'mir, 'tcx, M> layout::HasTyCtxt<'tcx> for &'b EvalContext<'a, 'mir, 'tcx, M>
+impl<'a, 'mir, 'tcx, M> layout::HasTyCtxt<'tcx> for EvalContext<'a, 'mir, 'tcx, M>
where M: Machine<'a, 'mir, 'tcx>
{
#[inline]
}
}
-impl<'c, 'b, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> layout::HasTyCtxt<'tcx>
- for &'c &'b mut EvalContext<'a, 'mir, 'tcx, M>
-{
- #[inline]
- fn tcx<'d>(&'d self) -> TyCtxt<'d, 'tcx, 'tcx> {
- *self.tcx
- }
-}
-
-impl<'b, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> LayoutOf
- for &'b EvalContext<'a, 'mir, 'tcx, M>
+impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> LayoutOf
+ for EvalContext<'a, 'mir, 'tcx, M>
{
type Ty = Ty<'tcx>;
type TyLayout = EvalResult<'tcx, TyLayout<'tcx>>;
#[inline]
- fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
+ fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
self.tcx.layout_of(self.param_env.and(ty))
.map_err(|layout| EvalErrorKind::Layout(layout).into())
}
}
-impl<'c, 'b, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> LayoutOf
- for &'c &'b mut EvalContext<'a, 'mir, 'tcx, M>
-{
- type Ty = Ty<'tcx>;
- type TyLayout = EvalResult<'tcx, TyLayout<'tcx>>;
-
- #[inline]
- fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
- (&**self).layout_of(ty)
- }
-}
-
impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
pub fn new(
tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
pub fn str_to_immediate(&mut self, s: &str) -> EvalResult<'tcx, Immediate<M::PointerTag>> {
let ptr = self.memory.allocate_static_bytes(s.as_bytes()).with_default_tag();
- Ok(Immediate::new_slice(Scalar::Ptr(ptr), s.len() as u64, self.tcx.tcx))
+ Ok(Immediate::new_slice(Scalar::Ptr(ptr), s.len() as u64, self))
}
/// Return the actual dynamic size and alignment of the place at the given type.
"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)?;
pub(super) tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
}
-impl<'b, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> HasDataLayout
- for &'b Memory<'a, 'mir, 'tcx, M>
-{
- #[inline]
- fn data_layout(&self) -> &TargetDataLayout {
- &self.tcx.data_layout
- }
-}
-impl<'a, 'b, 'c, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> HasDataLayout
- for &'b &'c mut Memory<'a, 'mir, 'tcx, M>
+impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> HasDataLayout
+ for Memory<'a, 'mir, 'tcx, M>
{
#[inline]
fn data_layout(&self) -> &TargetDataLayout {
if self.alloc_map.contains_key(&alloc) {
// Not yet interned, so proceed recursively
self.intern_static(alloc, mutability)?;
+ } else if self.dead_alloc_map.contains_key(&alloc) {
+ // dangling pointer
+ return err!(ValidationFailure(
+ "encountered dangling pointer in final constant".into(),
+ ))
}
}
Ok(())
}
#[inline(always)]
- pub fn to_usize(self, cx: impl HasDataLayout) -> EvalResult<'tcx, u64> {
+ pub fn to_usize(self, cx: &impl HasDataLayout) -> EvalResult<'tcx, u64> {
self.not_undef()?.to_usize(cx)
}
}
#[inline(always)]
- pub fn to_isize(self, cx: impl HasDataLayout) -> EvalResult<'tcx, i64> {
+ pub fn to_isize(self, cx: &impl HasDataLayout) -> EvalResult<'tcx, i64> {
self.not_undef()?.to_isize(cx)
}
}
pub fn new_slice(
val: Scalar<Tag>,
len: u64,
- cx: impl HasDataLayout
+ cx: &impl HasDataLayout
) -> Self {
Immediate::ScalarPair(
val.into(),
.ty_adt_def().expect("tagged layout corresponds to adt")
.repr
.discr_type();
- let discr_ty = layout::Integer::from_attr(self.tcx.tcx, discr_ty);
+ let discr_ty = layout::Integer::from_attr(self, discr_ty);
let shift = 128 - discr_ty.size().bits();
let truncatee = sexted as u128;
(truncatee << shift) >> shift
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>,
/// Produces a Place that will error if attempted to be read from or written to
#[inline(always)]
- pub fn null(cx: impl HasDataLayout) -> Self {
+ pub fn null(cx: &impl HasDataLayout) -> Self {
Self::from_scalar_ptr(Scalar::ptr_null(cx), Align::from_bytes(1, 1).unwrap())
}
impl<'tcx, Tag> MPlaceTy<'tcx, Tag> {
/// Produces a MemPlace that works for ZST but nothing else
#[inline]
- pub fn dangling(layout: TyLayout<'tcx>, cx: impl HasDataLayout) -> Self {
+ pub fn dangling(layout: TyLayout<'tcx>, cx: &impl HasDataLayout) -> Self {
MPlaceTy {
mplace: MemPlace::from_scalar_ptr(
Scalar::from_uint(layout.align.abi(), cx.pointer_size()),
}
#[inline]
- pub(super) fn len(self, cx: impl HasDataLayout) -> EvalResult<'tcx, u64> {
+ pub(super) fn len(self, cx: &impl HasDataLayout) -> EvalResult<'tcx, u64> {
if self.layout.is_unsized() {
// We need to consult `meta` metadata
match self.layout.ty.sty {
impl<'tcx, Tag: ::std::fmt::Debug> Place<Tag> {
/// Produces a Place that will error if attempted to be read from or written to
#[inline(always)]
- pub fn null(cx: impl HasDataLayout) -> Self {
+ pub fn null(cx: &impl HasDataLayout) -> Self {
Place::Ptr(MemPlace::null(cx))
}
Place::Ptr(mplace) =>
self.mplace_downcast(MPlaceTy { mplace, layout: base.layout }, variant)?.into(),
Place::Local { .. } => {
- let layout = base.layout.for_variant(&self, variant);
+ let layout = base.layout.for_variant(self, variant);
PlaceTy { layout, ..base }
}
})
_ => bug!("write_immediate_to_mplace: invalid ScalarPair layout: {:#?}",
dest.layout)
};
- let (a_size, b_size) = (a.size(&self), b.size(&self));
- let (a_align, b_align) = (a.align(&self), b.align(&self));
+ let (a_size, b_size) = (a.size(self), b.size(self));
+ let (a_align, b_align) = (a.align(self), b.align(self));
let b_offset = a_size.abi_align(b_align);
- let b_ptr = ptr.offset(b_offset, &self)?.into();
+ let b_ptr = ptr.offset(b_offset, self)?.into();
// It is tempting to verify `b_offset` against `layout.fields.offset(1)`,
// but that does not work: We could be a newtype around a pair, then the
if layout.is_unsized() {
assert!(self.tcx.features().unsized_locals, "cannot alloc memory for unsized type");
// FIXME: What should we do here? We should definitely also tag!
- Ok(MPlaceTy::dangling(layout, &self))
+ Ok(MPlaceTy::dangling(layout, self))
} else {
let ptr = self.memory.allocate(layout.size, layout.align, kind)?;
let ptr = M::tag_new_allocation(self, ptr, kind)?;
// raw discriminants for enums are isize or bigger during
// their computation, but the in-memory tag is the smallest possible
// representation
- let size = tag.value.size(self.tcx.tcx);
+ let size = tag.value.size(self);
let shift = 128 - size.bits();
let discr_val = (discr_val << shift) >> shift;
Repeat(ref operand, _) => {
let op = self.eval_operand(operand, None)?;
let dest = self.force_allocation(dest)?;
- let length = dest.len(&self)?;
+ let length = dest.len(self)?;
if length > 0 {
// write the first
if length > 1 {
// copy the rest
let (dest, dest_align) = first.to_scalar_ptr_align();
- let rest = dest.ptr_offset(first.layout.size, &self)?;
+ let rest = dest.ptr_offset(first.layout.size, self)?;
self.memory.copy_repeatedly(
dest, dest_align, rest, dest_align, first.layout.size, length - 1, true
)?;
// FIXME(CTFE): don't allow computing the length of arrays in const eval
let src = self.eval_place(place)?;
let mplace = self.force_allocation(src)?;
- let len = mplace.len(&self)?;
+ let len = mplace.len(self)?;
let size = self.pointer_size();
self.write_scalar(
Scalar::from_uint(len, size),
let ptr = self.ref_to_mplace(self.read_immediate(args[0])?)?;
let vtable = ptr.vtable()?;
let fn_ptr = self.memory.read_ptr_sized(
- vtable.offset(ptr_size * (idx as u64 + 3), &self)?,
+ vtable.offset(ptr_size * (idx as u64 + 3), self)?,
ptr_align
)?.to_ptr()?;
let instance = self.memory.get_fn(fn_ptr)?;
let mut args = args.to_vec();
let pointee = args[0].layout.ty.builtin_deref(true).unwrap().ty;
let fake_fat_ptr_ty = self.tcx.mk_mut_ptr(pointee);
- args[0].layout = self.layout_of(fake_fat_ptr_ty)?.field(&self, 0)?;
+ args[0].layout = self.layout_of(fake_fat_ptr_ty)?.field(self, 0)?;
args[0].op = Operand::Immediate(Immediate::Scalar(ptr.ptr.into())); // strip vtable
trace!("Patched self operand to {:#?}", args[0]);
// recurse with concrete function
};
let ty = self.tcx.mk_unit(); // return type is ()
- let dest = MPlaceTy::dangling(self.layout_of(ty)?, &self);
+ let dest = MPlaceTy::dangling(self.layout_of(ty)?, self);
self.eval_fn_call(
instance,
let drop = self.memory.create_fn_alloc(drop).with_default_tag();
self.memory.write_ptr_sized(vtable, ptr_align, Scalar::Ptr(drop).into())?;
- let size_ptr = vtable.offset(ptr_size, &self)?;
+ let size_ptr = vtable.offset(ptr_size, self)?;
self.memory.write_ptr_sized(size_ptr, ptr_align, Scalar::from_uint(size, ptr_size).into())?;
- let align_ptr = vtable.offset(ptr_size * 2, &self)?;
+ let align_ptr = vtable.offset(ptr_size * 2, self)?;
self.memory.write_ptr_sized(align_ptr, ptr_align,
Scalar::from_uint(align, ptr_size).into())?;
if let Some((def_id, substs)) = *method {
let instance = self.resolve(def_id, substs)?;
let fn_ptr = self.memory.create_fn_alloc(instance).with_default_tag();
- let method_ptr = vtable.offset(ptr_size * (3 + i as u64), &self)?;
+ let method_ptr = vtable.offset(ptr_size * (3 + i as u64), self)?;
self.memory.write_ptr_sized(method_ptr, ptr_align, Scalar::Ptr(fn_ptr).into())?;
}
}
//
// * 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
param_env: ParamEnv<'tcx>,
}
-impl<'a, 'b, 'tcx> LayoutOf for &'a ConstPropagator<'a, 'b, 'tcx> {
+impl<'a, 'b, 'tcx> LayoutOf for ConstPropagator<'a, 'b, 'tcx> {
type Ty = ty::Ty<'tcx>;
type TyLayout = Result<TyLayout<'tcx>, LayoutError<'tcx>>;
- fn layout_of(self, ty: ty::Ty<'tcx>) -> Self::TyLayout {
+ fn layout_of(&self, ty: ty::Ty<'tcx>) -> Self::TyLayout {
self.tcx.layout_of(self.param_env.and(ty))
}
}
-impl<'a, 'b, 'tcx> HasDataLayout for &'a ConstPropagator<'a, 'b, 'tcx> {
+impl<'a, 'b, 'tcx> HasDataLayout for ConstPropagator<'a, 'b, 'tcx> {
#[inline]
fn data_layout(&self) -> &TargetDataLayout {
&self.tcx.data_layout
}
}
-impl<'a, 'b, 'tcx> HasTyCtxt<'tcx> for &'a ConstPropagator<'a, 'b, 'tcx> {
+impl<'a, 'b, 'tcx> HasTyCtxt<'tcx> for ConstPropagator<'a, 'b, 'tcx> {
#[inline]
fn tcx<'c>(&'c self) -> TyCtxt<'c, 'tcx, 'tcx> {
self.tcx
})?;
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`"),
}
use std::cell::{Cell, RefCell};
use std::collections::BTreeMap;
-use std::fmt::Write;
use std::{mem, ptr};
/// Contains data for specific types of import directives.
let msg = format!("`{}` import is ambiguous", name);
let mut err = self.session.struct_span_err(span, &msg);
- let mut suggestion_choices = String::new();
+ let mut suggestion_choices = vec![];
if external_crate.is_some() {
- write!(suggestion_choices, "`::{}`", name);
+ suggestion_choices.push(format!("`::{}`", name));
err.span_label(span,
format!("can refer to external crate `::{}`", name));
}
if let Some(result) = results.module_scope {
- if !suggestion_choices.is_empty() {
- suggestion_choices.push_str(" or ");
- }
- write!(suggestion_choices, "`self::{}`", name);
+ suggestion_choices.push(format!("`self::{}`", name));
if uniform_paths_feature {
err.span_label(result.span,
format!("can refer to `self::{}`", name));
err.span_label(result.span,
format!("shadowed by block-scoped `{}`", name));
}
- err.help(&format!("write {} explicitly instead", suggestion_choices));
+ err.help(&format!("write {} explicitly instead", suggestion_choices.join(" or ")));
if uniform_paths_feature {
err.note("relative `use` paths enabled by `#![feature(uniform_paths)]`");
} else {
use abi::call::{FnType, ArgType, Reg, RegKind, Uniform};
use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
-fn is_homogeneous_aggregate<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>)
+fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>)
-> Option<Uniform>
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
})
}
-fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType<'a, Ty>)
+fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
ret.make_indirect();
}
-fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>)
+fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
arg.make_indirect();
}
-pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>)
+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
use abi::call::{ArgType, FnType, };
use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
-fn classify_ret_ty<'a, Ty, C>(_tuncx: C, ret: &mut ArgType<'a, Ty>)
+fn classify_ret_ty<'a, Ty, C>(_cx: &C, ret: &mut ArgType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
ret.extend_integer_width_to(32);
}
-fn classify_arg_ty<'a, Ty, C>(_cx: C, arg: &mut ArgType<'a, Ty>)
+fn classify_arg_ty<'a, Ty, C>(_cx: &C, arg: &mut ArgType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
arg.extend_integer_width_to(32);
}
-pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>)
+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
use spec::HasTargetSpec;
-fn is_homogeneous_aggregate<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>)
+fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>)
-> Option<Uniform>
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
})
}
-fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType<'a, Ty>, vfp: bool)
+fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'a, Ty>, vfp: bool)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
ret.make_indirect();
}
-fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>, vfp: bool)
+fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>, vfp: bool)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
});
}
-pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>)
+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout + HasTargetSpec
{
// See the https://github.com/kripken/emscripten-fastcomp-clang repository.
// The class `EmscriptenABIInfo` in `/lib/CodeGen/TargetInfo.cpp` contains the ABI definitions.
-fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType<'a, Ty>)
+fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
}
}
-pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>)
+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
use abi::call::{ArgType, FnType, Reg, Uniform};
use abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods};
-fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType<Ty>, offset: &mut Size)
+fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<Ty>, offset: &mut Size)
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
{
if !ret.layout.is_aggregate() {
}
}
-fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType<Ty>, offset: &mut Size)
+fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<Ty>, offset: &mut Size)
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
{
let dl = cx.data_layout();
*offset = offset.abi_align(align) + size.abi_align(align);
}
-pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<Ty>)
+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<Ty>)
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
{
let mut offset = Size::ZERO;
arg.extend_integer_width_to(bits);
}
-fn float_reg<'a, Ty, C>(cx: C, ret: &ArgType<'a, Ty>, i: usize) -> Option<Reg>
+fn float_reg<'a, Ty, C>(cx: &C, ret: &ArgType<'a, Ty>, i: usize) -> Option<Reg>
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
}
}
-fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType<'a, Ty>)
+fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
}
}
-fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>)
+fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
});
}
-pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>)
+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
}
impl Reg {
- pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
+ pub fn align<C: HasDataLayout>(&self, cx: &C) -> Align {
let dl = cx.data_layout();
match self.kind {
RegKind::Integer => {
}
impl Uniform {
- pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
+ pub fn align<C: HasDataLayout>(&self, cx: &C) -> Align {
self.unit.align(cx)
}
}
}
}
- pub fn size<C: HasDataLayout>(&self, cx: C) -> Size {
+ pub fn size<C: HasDataLayout>(&self, cx: &C) -> Size {
(self.prefix_chunk * self.prefix.iter().filter(|x| x.is_some()).count() as u64)
.abi_align(self.rest.align(cx)) + self.rest.total
}
- pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
+ pub fn align<C: HasDataLayout>(&self, cx: &C) -> Align {
self.prefix.iter()
.filter_map(|x| x.map(|kind| Reg { kind, size: self.prefix_chunk }.align(cx)))
.fold(cx.data_layout().aggregate_align.max(self.rest.align(cx)),
}
}
- fn homogeneous_aggregate<C>(&self, cx: C) -> Option<Reg>
- where Ty: TyLayoutMethods<'a, C> + Copy, C: LayoutOf<Ty = Ty, TyLayout = Self> + Copy
+ fn homogeneous_aggregate<C>(&self, cx: &C) -> Option<Reg>
+ where Ty: TyLayoutMethods<'a, C> + Copy, C: LayoutOf<Ty = Ty, TyLayout = Self>
{
match self.abi {
Abi::Uninhabited => None,
}
impl<'a, Ty> FnType<'a, Ty> {
- pub fn adjust_for_cabi<C>(&mut self, cx: C, abi: ::spec::abi::Abi) -> Result<(), String>
+ pub fn adjust_for_cabi<C>(&mut self, cx: &C, abi: ::spec::abi::Abi) -> Result<(), String>
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout + HasTargetSpec
{
use abi::call::{ArgType, FnType, Reg, Uniform};
use abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods};
-fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType<Ty>, offset: &mut Size)
+fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<Ty>, offset: &mut Size)
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
{
if !ret.layout.is_aggregate() {
}
}
-fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType<Ty>, offset: &mut Size)
+fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<Ty>, offset: &mut Size)
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
{
let dl = cx.data_layout();
*offset = offset.abi_align(align) + size.abi_align(align);
}
-pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<Ty>)
+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<Ty>)
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
{
let mut offset = Size::ZERO;
}
use self::ABI::*;
-fn is_homogeneous_aggregate<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>, abi: ABI)
+fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>, abi: ABI)
-> Option<Uniform>
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
})
}
-fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType<'a, Ty>, abi: ABI)
+fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'a, Ty>, abi: ABI)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
ret.make_indirect();
}
-fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>, abi: ABI)
+fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>, abi: ABI)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
});
}
-pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>)
+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
}
}
-fn is_single_fp_element<'a, Ty, C>(cx: C, layout: TyLayout<'a, Ty>) -> bool
+fn is_single_fp_element<'a, Ty, C>(cx: &C, layout: TyLayout<'a, Ty>) -> bool
where Ty: TyLayoutMethods<'a, C>,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
}
}
-fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>)
+fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
}
}
-pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>)
+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
use abi::call::{ArgType, FnType, Reg, Uniform};
use abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods};
-fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType<Ty>, offset: &mut Size)
+fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<Ty>, offset: &mut Size)
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
{
if !ret.layout.is_aggregate() {
}
}
-fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType<Ty>, offset: &mut Size)
+fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<Ty>, offset: &mut Size)
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
{
let dl = cx.data_layout();
*offset = offset.abi_align(align) + size.abi_align(align);
}
-pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<Ty>)
+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<Ty>)
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
{
let mut offset = Size::ZERO;
use abi::call::{FnType, ArgType, Reg, RegKind, Uniform};
use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
-fn is_homogeneous_aggregate<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>)
+fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>)
-> Option<Uniform>
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
})
}
-fn classify_ret_ty<'a, Ty, C>(cx: C, ret: &mut ArgType<'a, Ty>)
+fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
ret.make_indirect();
}
-fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>)
+fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
});
}
-pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>)
+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
Fastcall
}
-fn is_single_fp_element<'a, Ty, C>(cx: C, layout: TyLayout<'a, Ty>) -> bool
+fn is_single_fp_element<'a, Ty, C>(cx: &C, layout: TyLayout<'a, Ty>) -> bool
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
}
}
-pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>, flavor: Flavor)
+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>, flavor: Flavor)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout + HasTargetSpec
{
const LARGEST_VECTOR_SIZE: usize = 512;
const MAX_EIGHTBYTES: usize = LARGEST_VECTOR_SIZE / 64;
-fn classify_arg<'a, Ty, C>(cx: C, arg: &ArgType<'a, Ty>)
+fn classify_arg<'a, Ty, C>(cx: &C, arg: &ArgType<'a, Ty>)
-> Result<[Option<Class>; MAX_EIGHTBYTES], Memory>
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
- fn classify<'a, Ty, C>(cx: C, layout: TyLayout<'a, Ty>,
+ fn classify<'a, Ty, C>(cx: &C, layout: TyLayout<'a, Ty>,
cls: &mut [Option<Class>], off: Size) -> Result<(), Memory>
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
target
}
-pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>)
+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
}
}
-pub trait HasDataLayout: Copy {
+pub trait HasDataLayout {
fn data_layout(&self) -> &TargetDataLayout;
}
-impl<'a> HasDataLayout for &'a TargetDataLayout {
+impl HasDataLayout for TargetDataLayout {
fn data_layout(&self) -> &TargetDataLayout {
self
}
}
#[inline]
- pub fn checked_add<C: HasDataLayout>(self, offset: Size, cx: C) -> Option<Size> {
+ pub fn checked_add<C: HasDataLayout>(self, offset: Size, cx: &C) -> Option<Size> {
let dl = cx.data_layout();
let bytes = self.bytes().checked_add(offset.bytes())?;
}
#[inline]
- pub fn checked_mul<C: HasDataLayout>(self, count: u64, cx: C) -> Option<Size> {
+ pub fn checked_mul<C: HasDataLayout>(self, count: u64, cx: &C) -> Option<Size> {
let dl = cx.data_layout();
let bytes = self.bytes().checked_mul(count)?;
}
}
- pub fn align<C: HasDataLayout>(self, cx: C) -> Align {
+ pub fn align<C: HasDataLayout>(self, cx: &C) -> Align {
let dl = cx.data_layout();
match self {
}
/// Find the smallest integer with the given alignment.
- pub fn for_abi_align<C: HasDataLayout>(cx: C, align: Align) -> Option<Integer> {
+ pub fn for_abi_align<C: HasDataLayout>(cx: &C, align: Align) -> Option<Integer> {
let dl = cx.data_layout();
let wanted = align.abi();
}
/// Find the largest integer with the given alignment or less.
- pub fn approximate_abi_align<C: HasDataLayout>(cx: C, align: Align) -> Integer {
+ pub fn approximate_abi_align<C: HasDataLayout>(cx: &C, align: Align) -> Integer {
let dl = cx.data_layout();
let wanted = align.abi();
}
impl<'a, 'tcx> Primitive {
- pub fn size<C: HasDataLayout>(self, cx: C) -> Size {
+ pub fn size<C: HasDataLayout>(self, cx: &C) -> Size {
let dl = cx.data_layout();
match self {
}
}
- pub fn align<C: HasDataLayout>(self, cx: C) -> Align {
+ pub fn align<C: HasDataLayout>(self, cx: &C) -> Align {
let dl = cx.data_layout();
match self {
/// Returns the valid range as a `x..y` range.
///
/// If `x` and `y` are equal, the range is full, not empty.
- pub fn valid_range_exclusive<C: HasDataLayout>(&self, cx: C) -> Range<u128> {
+ pub fn valid_range_exclusive<C: HasDataLayout>(&self, cx: &C) -> Range<u128> {
// For a (max) value of -1, max will be `-1 as usize`, which overflows.
// However, that is fine here (it would still represent the full range),
// i.e., if the range is everything.
}
impl LayoutDetails {
- pub fn scalar<C: HasDataLayout>(cx: C, scalar: Scalar) -> Self {
+ pub fn scalar<C: HasDataLayout>(cx: &C, scalar: Scalar) -> Self {
let size = scalar.value.size(cx);
let align = scalar.value.align(cx);
LayoutDetails {
type Ty;
type TyLayout;
- fn layout_of(self, ty: Self::Ty) -> Self::TyLayout;
+ fn layout_of(&self, ty: Self::Ty) -> Self::TyLayout;
}
pub trait TyLayoutMethods<'a, C: LayoutOf<Ty = Self>>: Sized {
- fn for_variant(this: TyLayout<'a, Self>, cx: C, variant_index: usize) -> TyLayout<'a, Self>;
- fn field(this: TyLayout<'a, Self>, cx: C, i: usize) -> C::TyLayout;
+ fn for_variant(this: TyLayout<'a, Self>, cx: &C, variant_index: usize) -> TyLayout<'a, Self>;
+ fn field(this: TyLayout<'a, Self>, cx: &C, i: usize) -> C::TyLayout;
}
impl<'a, Ty> TyLayout<'a, Ty> {
- pub fn for_variant<C>(self, cx: C, variant_index: usize) -> Self
+ pub fn for_variant<C>(self, cx: &C, variant_index: usize) -> Self
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> {
Ty::for_variant(self, cx, variant_index)
}
- pub fn field<C>(self, cx: C, i: usize) -> C::TyLayout
+ pub fn field<C>(self, cx: &C, i: usize) -> C::TyLayout
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> {
Ty::field(self, cx, i)
}
// 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()),
pub options: TargetOptions,
}
-pub trait HasTargetSpec: Copy {
+pub trait HasTargetSpec {
fn target_spec(&self) -> &Target;
}
-impl<'a> HasTargetSpec for &'a Target {
+impl HasTargetSpec for Target {
fn target_spec(&self) -> &Target {
self
}
// 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() {
--- /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.
+
+use std::collections::{BTreeMap, BTreeSet};
+use std::fmt;
+use std::path::PathBuf;
+
+use errors;
+use errors::emitter::ColorConfig;
+use getopts;
+use rustc::lint::Level;
+use rustc::session::early_error;
+use rustc::session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs};
+use rustc::session::config::{nightly_options, build_codegen_options, build_debugging_options,
+ get_cmd_lint_options};
+use rustc::session::search_paths::SearchPaths;
+use rustc_driver;
+use rustc_target::spec::TargetTriple;
+use syntax::edition::Edition;
+
+use core::new_handler;
+use externalfiles::ExternalHtml;
+use html;
+use html::markdown::IdMap;
+use opts;
+use passes::{self, DefaultPassOption};
+use theme;
+
+/// Configuration options for rustdoc.
+#[derive(Clone)]
+pub struct Options {
+ // Basic options / Options passed directly to rustc
+
+ /// The crate root or Markdown file to load.
+ pub input: PathBuf,
+ /// The name of the crate being documented.
+ pub crate_name: Option<String>,
+ /// How to format errors and warnings.
+ pub error_format: ErrorOutputType,
+ /// Library search paths to hand to the compiler.
+ pub libs: SearchPaths,
+ /// The list of external crates to link against.
+ pub externs: Externs,
+ /// List of `cfg` flags to hand to the compiler. Always includes `rustdoc`.
+ pub cfgs: Vec<String>,
+ /// Codegen options to hand to the compiler.
+ pub codegen_options: CodegenOptions,
+ /// Debugging (`-Z`) options to pass to the compiler.
+ pub debugging_options: DebuggingOptions,
+ /// The target used to compile the crate against.
+ pub target: Option<TargetTriple>,
+ /// Edition used when reading the crate. Defaults to "2015". Also used by default when
+ /// compiling doctests from the crate.
+ pub edition: Edition,
+ /// The path to the sysroot. Used during the compilation process.
+ pub maybe_sysroot: Option<PathBuf>,
+ /// Linker to use when building doctests.
+ pub linker: Option<PathBuf>,
+ /// Lint information passed over the command-line.
+ pub lint_opts: Vec<(String, Level)>,
+ /// Whether to ask rustc to describe the lints it knows. Practically speaking, this will not be
+ /// used, since we abort if we have no input file, but it's included for completeness.
+ pub describe_lints: bool,
+ /// What level to cap lints at.
+ pub lint_cap: Option<Level>,
+
+ // Options specific to running doctests
+
+ /// Whether we should run doctests instead of generating docs.
+ pub should_test: bool,
+ /// List of arguments to pass to the test harness, if running tests.
+ pub test_args: Vec<String>,
+
+ // Options that affect the documentation process
+
+ /// The selected default set of passes to use.
+ ///
+ /// Be aware: This option can come both from the CLI and from crate attributes!
+ pub default_passes: DefaultPassOption,
+ /// Any passes manually selected by the user.
+ ///
+ /// Be aware: This option can come both from the CLI and from crate attributes!
+ pub manual_passes: Vec<String>,
+ /// Whether to display warnings during doc generation or while gathering doctests. By default,
+ /// all non-rustdoc-specific lints are allowed when generating docs.
+ pub display_warnings: bool,
+
+ // Options that alter generated documentation pages
+
+ /// Crate version to note on the sidebar of generated docs.
+ pub crate_version: Option<String>,
+ /// Collected options specific to outputting final pages.
+ pub render_options: RenderOptions,
+}
+
+impl fmt::Debug for Options {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ struct FmtExterns<'a>(&'a Externs);
+
+ impl<'a> fmt::Debug for FmtExterns<'a> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_map()
+ .entries(self.0.iter())
+ .finish()
+ }
+ }
+
+ f.debug_struct("Options")
+ .field("input", &self.input)
+ .field("crate_name", &self.crate_name)
+ .field("error_format", &self.error_format)
+ .field("libs", &self.libs)
+ .field("externs", &FmtExterns(&self.externs))
+ .field("cfgs", &self.cfgs)
+ .field("codegen_options", &"...")
+ .field("debugging_options", &"...")
+ .field("target", &self.target)
+ .field("edition", &self.edition)
+ .field("maybe_sysroot", &self.maybe_sysroot)
+ .field("linker", &self.linker)
+ .field("lint_opts", &self.lint_opts)
+ .field("describe_lints", &self.describe_lints)
+ .field("lint_cap", &self.lint_cap)
+ .field("should_test", &self.should_test)
+ .field("test_args", &self.test_args)
+ .field("default_passes", &self.default_passes)
+ .field("manual_passes", &self.manual_passes)
+ .field("display_warnings", &self.display_warnings)
+ .field("crate_version", &self.crate_version)
+ .field("render_options", &self.render_options)
+ .finish()
+ }
+}
+
+/// Configuration options for the HTML page-creation process.
+#[derive(Clone, Debug)]
+pub struct RenderOptions {
+ /// Output directory to generate docs into. Defaults to `doc`.
+ pub output: PathBuf,
+ /// External files to insert into generated pages.
+ pub external_html: ExternalHtml,
+ /// A pre-populated `IdMap` with the default headings and any headings added by Markdown files
+ /// processed by `external_html`.
+ pub id_map: IdMap,
+ /// If present, playground URL to use in the "Run" button added to code samples.
+ ///
+ /// Be aware: This option can come both from the CLI and from crate attributes!
+ pub playground_url: Option<String>,
+ /// Whether to sort modules alphabetically on a module page instead of using declaration order.
+ /// `true` by default.
+ ///
+ /// FIXME(misdreavus): the flag name is `--sort-modules-by-appearance` but the meaning is
+ /// inverted once read
+ pub sort_modules_alphabetically: bool,
+ /// List of themes to extend the docs with. Original argument name is included to assist in
+ /// displaying errors if it fails a theme check.
+ pub themes: Vec<PathBuf>,
+ /// If present, CSS file that contains rules to add to the default CSS.
+ pub extension_css: Option<PathBuf>,
+ /// A map of crate names to the URL to use instead of querying the crate's `html_root_url`.
+ pub extern_html_root_urls: BTreeMap<String, String>,
+ /// If present, suffix added to CSS/JavaScript files when referencing them in generated pages.
+ pub resource_suffix: String,
+ /// Whether to run the static CSS/JavaScript through a minifier when outputting them. `true` by
+ /// default.
+ ///
+ /// FIXME(misdreavus): the flag name is `--disable-minification` but the meaning is inverted
+ /// once read
+ pub enable_minification: bool,
+ /// Whether to create an index page in the root of the output directory. If this is true but
+ /// `enable_index_page` is None, generate a static listing of crates instead.
+ pub enable_index_page: bool,
+ /// A file to use as the index page at the root of the output directory. Overrides
+ /// `enable_index_page` to be true if set.
+ pub index_page: Option<PathBuf>,
+
+ // Options specific to reading standalone Markdown files
+
+ /// Whether to generate a table of contents on the output file when reading a standalone
+ /// Markdown file.
+ pub markdown_no_toc: bool,
+ /// Additional CSS files to link in pages generated from standlone Markdown files.
+ pub markdown_css: Vec<String>,
+ /// If present, playground URL to use in the "Run" button added to code samples generated from
+ /// standalone Markdown files. If not present, `playground_url` is used.
+ pub markdown_playground_url: Option<String>,
+}
+
+impl Options {
+ /// Parses the given command-line for options. If an error message or other early-return has
+ /// been printed, returns `Err` with the exit code.
+ pub fn from_matches(matches: &getopts::Matches) -> Result<Options, isize> {
+ // Check for unstable options.
+ nightly_options::check_nightly_options(&matches, &opts());
+
+ if matches.opt_present("h") || matches.opt_present("help") {
+ ::usage("rustdoc");
+ return Err(0);
+ } else if matches.opt_present("version") {
+ rustc_driver::version("rustdoc", &matches);
+ return Err(0);
+ }
+
+ if matches.opt_strs("passes") == ["list"] {
+ println!("Available passes for running rustdoc:");
+ for pass in passes::PASSES {
+ println!("{:>20} - {}", pass.name(), pass.description());
+ }
+ println!("\nDefault passes for rustdoc:");
+ for &name in passes::DEFAULT_PASSES {
+ println!("{:>20}", name);
+ }
+ println!("\nPasses run with `--document-private-items`:");
+ for &name in passes::DEFAULT_PRIVATE_PASSES {
+ println!("{:>20}", name);
+ }
+ return Err(0);
+ }
+
+ let color = match matches.opt_str("color").as_ref().map(|s| &s[..]) {
+ Some("auto") => ColorConfig::Auto,
+ Some("always") => ColorConfig::Always,
+ Some("never") => ColorConfig::Never,
+ None => ColorConfig::Auto,
+ Some(arg) => {
+ early_error(ErrorOutputType::default(),
+ &format!("argument for --color must be `auto`, `always` or `never` \
+ (instead was `{}`)", arg));
+ }
+ };
+ let error_format = match matches.opt_str("error-format").as_ref().map(|s| &s[..]) {
+ Some("human") => ErrorOutputType::HumanReadable(color),
+ Some("json") => ErrorOutputType::Json(false),
+ Some("pretty-json") => ErrorOutputType::Json(true),
+ Some("short") => ErrorOutputType::Short(color),
+ None => ErrorOutputType::HumanReadable(color),
+ Some(arg) => {
+ early_error(ErrorOutputType::default(),
+ &format!("argument for --error-format must be `human`, `json` or \
+ `short` (instead was `{}`)", arg));
+ }
+ };
+
+ let codegen_options = build_codegen_options(matches, error_format);
+ let debugging_options = build_debugging_options(matches, error_format);
+
+ let diag = new_handler(error_format,
+ None,
+ debugging_options.treat_err_as_bug,
+ debugging_options.ui_testing);
+
+ // check for deprecated options
+ check_deprecated_options(&matches, &diag);
+
+ let to_check = matches.opt_strs("theme-checker");
+ if !to_check.is_empty() {
+ let paths = theme::load_css_paths(include_bytes!("html/static/themes/light.css"));
+ let mut errors = 0;
+
+ println!("rustdoc: [theme-checker] Starting tests!");
+ for theme_file in to_check.iter() {
+ print!(" - Checking \"{}\"...", theme_file);
+ let (success, differences) = theme::test_theme_against(theme_file, &paths, &diag);
+ if !differences.is_empty() || !success {
+ println!(" FAILED");
+ errors += 1;
+ if !differences.is_empty() {
+ println!("{}", differences.join("\n"));
+ }
+ } else {
+ println!(" OK");
+ }
+ }
+ if errors != 0 {
+ return Err(1);
+ }
+ return Err(0);
+ }
+
+ if matches.free.is_empty() {
+ diag.struct_err("missing file operand").emit();
+ return Err(1);
+ }
+ if matches.free.len() > 1 {
+ diag.struct_err("too many file operands").emit();
+ return Err(1);
+ }
+ let input = PathBuf::from(&matches.free[0]);
+
+ let mut libs = SearchPaths::new();
+ for s in &matches.opt_strs("L") {
+ libs.add_path(s, error_format);
+ }
+ let externs = match parse_externs(&matches) {
+ Ok(ex) => ex,
+ Err(err) => {
+ diag.struct_err(&err).emit();
+ return Err(1);
+ }
+ };
+ let extern_html_root_urls = match parse_extern_html_roots(&matches) {
+ Ok(ex) => ex,
+ Err(err) => {
+ diag.struct_err(err).emit();
+ return Err(1);
+ }
+ };
+
+ let test_args = matches.opt_strs("test-args");
+ let test_args: Vec<String> = test_args.iter()
+ .flat_map(|s| s.split_whitespace())
+ .map(|s| s.to_string())
+ .collect();
+
+ let should_test = matches.opt_present("test");
+
+ let output = matches.opt_str("o")
+ .map(|s| PathBuf::from(&s))
+ .unwrap_or_else(|| PathBuf::from("doc"));
+ let mut cfgs = matches.opt_strs("cfg");
+ cfgs.push("rustdoc".to_string());
+
+ let extension_css = matches.opt_str("e").map(|s| PathBuf::from(&s));
+
+ if let Some(ref p) = extension_css {
+ if !p.is_file() {
+ diag.struct_err("option --extend-css argument must be a file").emit();
+ return Err(1);
+ }
+ }
+
+ let mut themes = Vec::new();
+ if matches.opt_present("themes") {
+ let paths = theme::load_css_paths(include_bytes!("html/static/themes/light.css"));
+
+ for (theme_file, theme_s) in matches.opt_strs("themes")
+ .iter()
+ .map(|s| (PathBuf::from(&s), s.to_owned())) {
+ if !theme_file.is_file() {
+ diag.struct_err("option --themes arguments must all be files").emit();
+ return Err(1);
+ }
+ let (success, ret) = theme::test_theme_against(&theme_file, &paths, &diag);
+ if !success || !ret.is_empty() {
+ diag.struct_err(&format!("invalid theme: \"{}\"", theme_s))
+ .help("check what's wrong with the --theme-checker option")
+ .emit();
+ return Err(1);
+ }
+ themes.push(theme_file);
+ }
+ }
+
+ let mut id_map = html::markdown::IdMap::new();
+ id_map.populate(html::render::initial_ids());
+ let external_html = match ExternalHtml::load(
+ &matches.opt_strs("html-in-header"),
+ &matches.opt_strs("html-before-content"),
+ &matches.opt_strs("html-after-content"),
+ &matches.opt_strs("markdown-before-content"),
+ &matches.opt_strs("markdown-after-content"), &diag, &mut id_map) {
+ Some(eh) => eh,
+ None => return Err(3),
+ };
+
+ let edition = matches.opt_str("edition").unwrap_or("2015".to_string());
+ let edition = match edition.parse() {
+ Ok(e) => e,
+ Err(_) => {
+ diag.struct_err("could not parse edition").emit();
+ return Err(1);
+ }
+ };
+
+ match matches.opt_str("r").as_ref().map(|s| &**s) {
+ Some("rust") | None => {}
+ Some(s) => {
+ diag.struct_err(&format!("unknown input format: {}", s)).emit();
+ return Err(1);
+ }
+ }
+
+ match matches.opt_str("w").as_ref().map(|s| &**s) {
+ Some("html") | None => {}
+ Some(s) => {
+ diag.struct_err(&format!("unknown output format: {}", s)).emit();
+ return Err(1);
+ }
+ }
+
+ let index_page = matches.opt_str("index-page").map(|s| PathBuf::from(&s));
+ if let Some(ref index_page) = index_page {
+ if !index_page.is_file() {
+ diag.struct_err("option `--index-page` argument must be a file").emit();
+ return Err(1);
+ }
+ }
+
+ let target = matches.opt_str("target").map(|target| {
+ if target.ends_with(".json") {
+ TargetTriple::TargetPath(PathBuf::from(target))
+ } else {
+ TargetTriple::TargetTriple(target)
+ }
+ });
+
+ let default_passes = if matches.opt_present("no-defaults") {
+ passes::DefaultPassOption::None
+ } else if matches.opt_present("document-private-items") {
+ passes::DefaultPassOption::Private
+ } else {
+ passes::DefaultPassOption::Default
+ };
+ let manual_passes = matches.opt_strs("passes");
+
+ let crate_name = matches.opt_str("crate-name");
+ let playground_url = matches.opt_str("playground-url");
+ let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from);
+ let display_warnings = matches.opt_present("display-warnings");
+ let linker = matches.opt_str("linker").map(PathBuf::from);
+ let sort_modules_alphabetically = !matches.opt_present("sort-modules-by-appearance");
+ let resource_suffix = matches.opt_str("resource-suffix").unwrap_or_default();
+ let enable_minification = !matches.opt_present("disable-minification");
+ let markdown_no_toc = matches.opt_present("markdown-no-toc");
+ let markdown_css = matches.opt_strs("markdown-css");
+ let markdown_playground_url = matches.opt_str("markdown-playground-url");
+ let crate_version = matches.opt_str("crate-version");
+ let enable_index_page = matches.opt_present("enable-index-page") || index_page.is_some();
+
+ let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
+
+ Ok(Options {
+ input,
+ crate_name,
+ error_format,
+ libs,
+ externs,
+ cfgs,
+ codegen_options,
+ debugging_options,
+ target,
+ edition,
+ maybe_sysroot,
+ linker,
+ lint_opts,
+ describe_lints,
+ lint_cap,
+ should_test,
+ test_args,
+ default_passes,
+ manual_passes,
+ display_warnings,
+ crate_version,
+ render_options: RenderOptions {
+ output,
+ external_html,
+ id_map,
+ playground_url,
+ sort_modules_alphabetically,
+ themes,
+ extension_css,
+ extern_html_root_urls,
+ resource_suffix,
+ enable_minification,
+ enable_index_page,
+ index_page,
+ markdown_no_toc,
+ markdown_css,
+ markdown_playground_url,
+ }
+ })
+ }
+
+ /// Returns whether the file given as `self.input` is a Markdown file.
+ pub fn markdown_input(&self) -> bool {
+ self.input.extension()
+ .map_or(false, |e| e == "md" || e == "markdown")
+ }
+}
+
+/// Prints deprecation warnings for deprecated options
+fn check_deprecated_options(matches: &getopts::Matches, diag: &errors::Handler) {
+ let deprecated_flags = [
+ "input-format",
+ "output-format",
+ "no-defaults",
+ "passes",
+ ];
+
+ for flag in deprecated_flags.into_iter() {
+ if matches.opt_present(flag) {
+ let mut err = diag.struct_warn(&format!("the '{}' flag is considered deprecated",
+ flag));
+ err.warn("please see https://github.com/rust-lang/rust/issues/44136");
+
+ if *flag == "no-defaults" {
+ err.help("you may want to use --document-private-items");
+ }
+
+ err.emit();
+ }
+ }
+
+ let removed_flags = [
+ "plugins",
+ "plugin-path",
+ ];
+
+ for &flag in removed_flags.iter() {
+ if matches.opt_present(flag) {
+ diag.struct_warn(&format!("the '{}' flag no longer functions", flag))
+ .warn("see CVE-2018-1000622")
+ .emit();
+ }
+ }
+}
+
+/// Extracts `--extern-html-root-url` arguments from `matches` and returns a map of crate names to
+/// the given URLs. If an `--extern-html-root-url` argument was ill-formed, returns an error
+/// describing the issue.
+fn parse_extern_html_roots(
+ matches: &getopts::Matches,
+) -> Result<BTreeMap<String, String>, &'static str> {
+ let mut externs = BTreeMap::new();
+ for arg in &matches.opt_strs("extern-html-root-url") {
+ let mut parts = arg.splitn(2, '=');
+ let name = parts.next().ok_or("--extern-html-root-url must not be empty")?;
+ let url = parts.next().ok_or("--extern-html-root-url must be of the form name=url")?;
+ externs.insert(name.to_string(), url.to_string());
+ }
+
+ Ok(externs)
+}
+
+/// Extracts `--extern CRATE=PATH` arguments from `matches` and
+/// returns a map mapping crate names to their paths or else an
+/// error message.
+// FIXME(eddyb) This shouldn't be duplicated with `rustc::session`.
+fn parse_externs(matches: &getopts::Matches) -> Result<Externs, String> {
+ let mut externs: BTreeMap<_, BTreeSet<_>> = BTreeMap::new();
+ for arg in &matches.opt_strs("extern") {
+ let mut parts = arg.splitn(2, '=');
+ let name = parts.next().ok_or("--extern value must not be empty".to_string())?;
+ let location = parts.next().map(|s| s.to_string());
+ if location.is_none() && !nightly_options::is_unstable_enabled(matches) {
+ return Err("the `-Z unstable-options` flag must also be passed to \
+ enable `--extern crate_name` without `=path`".to_string());
+ }
+ let name = name.to_string();
+ externs.entry(name).or_default().insert(location);
+ }
+ Ok(Externs::new(externs))
+}
use syntax::ast::{self, Ident, NodeId};
use syntax::source_map;
-use syntax::edition::Edition;
use syntax::feature_gate::UnstableFeatures;
use syntax::json::JsonEmitter;
use syntax::ptr::P;
use rustc_data_structures::sync::{self, Lrc};
use std::rc::Rc;
use std::sync::Arc;
-use std::path::PathBuf;
use visit_ast::RustdocVisitor;
+use config::{Options as RustdocOptions, RenderOptions};
use clean;
use clean::{get_path_for_type, Clean, MAX_DEF_ID, AttributesExt};
use html::render::RenderInfo;
)
}
-pub fn run_core(search_paths: SearchPaths,
- cfgs: Vec<String>,
- externs: config::Externs,
- input: Input,
- triple: Option<TargetTriple>,
- maybe_sysroot: Option<PathBuf>,
- allow_warnings: bool,
- crate_name: Option<String>,
- force_unstable_if_unmarked: bool,
- edition: Edition,
- cg: CodegenOptions,
- error_format: ErrorOutputType,
- cmd_lints: Vec<(String, lint::Level)>,
- lint_cap: Option<lint::Level>,
- describe_lints: bool,
- mut manual_passes: Vec<String>,
- mut default_passes: passes::DefaultPassOption,
- treat_err_as_bug: bool,
- ui_testing: bool,
-) -> (clean::Crate, RenderInfo, Vec<String>) {
+pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOptions, Vec<String>) {
// Parse, resolve, and typecheck the given crate.
- let cpath = match input {
- Input::File(ref p) => Some(p.clone()),
- _ => None
- };
+ let RustdocOptions {
+ input,
+ crate_name,
+ error_format,
+ libs,
+ externs,
+ cfgs,
+ codegen_options,
+ debugging_options,
+ target,
+ edition,
+ maybe_sysroot,
+ lint_opts,
+ describe_lints,
+ lint_cap,
+ mut default_passes,
+ mut manual_passes,
+ display_warnings,
+ render_options,
+ ..
+ } = options;
+
+ let cpath = Some(input.clone());
+ let input = Input::File(input);
let intra_link_resolution_failure_name = lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE.name;
let warnings_lint_name = lint::builtin::WARNINGS.name;
missing_docs.to_owned(),
missing_doc_example.to_owned()];
- whitelisted_lints.extend(cmd_lints.iter().map(|(lint, _)| lint).cloned());
+ whitelisted_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned());
let lints = lint::builtin::HardwiredLints.get_lints()
.into_iter()
Some((lint.name_lower(), lint::Allow))
}
})
- .chain(cmd_lints.into_iter())
+ .chain(lint_opts.into_iter())
.collect::<Vec<_>>();
let host_triple = TargetTriple::from_triple(config::host_triple());
// plays with error output here!
let sessopts = config::Options {
maybe_sysroot,
- search_paths,
+ search_paths: libs,
crate_types: vec![config::CrateType::Rlib],
- lint_opts: if !allow_warnings {
+ lint_opts: if !display_warnings {
lints
} else {
vec![]
},
lint_cap: Some(lint_cap.unwrap_or_else(|| lint::Forbid)),
- cg,
+ cg: codegen_options,
externs,
- target_triple: triple.unwrap_or(host_triple),
+ target_triple: target.unwrap_or(host_triple),
// Ensure that rustdoc works even if rustc is feature-staged
unstable_features: UnstableFeatures::Allow,
actually_rustdoc: true,
- debugging_opts: config::DebuggingOptions {
- force_unstable_if_unmarked,
- treat_err_as_bug,
- ui_testing,
- ..config::basic_debugging_options()
- },
+ debugging_opts: debugging_options.clone(),
error_format,
edition,
describe_lints,
let source_map = Lrc::new(source_map::SourceMap::new(sessopts.file_path_mapping()));
let diagnostic_handler = new_handler(error_format,
Some(source_map.clone()),
- treat_err_as_bug,
- ui_testing);
+ debugging_options.treat_err_as_bug,
+ debugging_options.ui_testing);
let mut sess = session::build_session_(
sessopts, cpath, diagnostic_handler, source_map,
ctxt.sess().abort_if_errors();
- (krate, ctxt.renderinfo.into_inner(), passes)
+ (krate, ctxt.renderinfo.into_inner(), render_options, passes)
}), &sess)
})
}
use html::markdown::{IdMap, ErrorCodes, Markdown};
use std::cell::RefCell;
-#[derive(Clone)]
+#[derive(Clone, Debug)]
pub struct ExternalHtml {
/// Content that will be included inline in the <head> section of a
/// rendered Markdown file or generated documentation
links
}
-#[derive(Default)]
+#[derive(Clone, Default, Debug)]
pub struct IdMap {
map: FxHashMap<String, usize>,
}
use std::sync::Arc;
use std::rc::Rc;
-use externalfiles::ExternalHtml;
-
use errors;
-use getopts;
-
use serialize::json::{ToJson, Json, as_json};
use syntax::ast;
use syntax::ext::base::MacroKind;
use rustc_data_structures::flock;
use clean::{self, AttributesExt, GetDefId, SelfTy, Mutability};
+use config::RenderOptions;
use doctree;
use fold::DocFolder;
use html::escape::Escape;
/// The map used to ensure all generated 'id=' attributes are unique.
id_map: Rc<RefCell<IdMap>>,
pub shared: Arc<SharedContext>,
- pub enable_index_page: bool,
- pub index_page: Option<PathBuf>,
}
struct SharedContext {
/// Generates the documentation for `crate` into the directory `dst`
pub fn run(mut krate: clean::Crate,
- extern_urls: BTreeMap<String, String>,
- external_html: &ExternalHtml,
- playground_url: Option<String>,
- dst: PathBuf,
- resource_suffix: String,
+ options: RenderOptions,
passes: FxHashSet<String>,
- css_file_extension: Option<PathBuf>,
renderinfo: RenderInfo,
- sort_modules_alphabetically: bool,
- themes: Vec<PathBuf>,
- enable_minification: bool,
- id_map: IdMap,
- enable_index_page: bool,
- index_page: Option<PathBuf>,
- matches: &getopts::Matches,
- diag: &errors::Handler,
-) -> Result<(), Error> {
+ diag: &errors::Handler) -> Result<(), Error> {
+ // need to save a copy of the options for rendering the index page
+ let md_opts = options.clone();
+ let RenderOptions {
+ output,
+ external_html,
+ id_map,
+ playground_url,
+ sort_modules_alphabetically,
+ themes,
+ extension_css,
+ extern_html_root_urls,
+ resource_suffix,
+ ..
+ } = options;
+
let src_root = match krate.src {
FileName::Real(ref p) => match p.parent() {
Some(p) => p.to_path_buf(),
layout: layout::Layout {
logo: String::new(),
favicon: String::new(),
- external_html: external_html.clone(),
+ external_html,
krate: krate.name.clone(),
},
- css_file_extension,
+ css_file_extension: extension_css,
created_dirs: Default::default(),
sort_modules_alphabetically,
themes,
}
}
}
+ let dst = output;
try_err!(fs::create_dir_all(&dst), &dst);
krate = render_sources(&dst, &mut scx, krate)?;
let cx = Context {
codes: ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()),
id_map: Rc::new(RefCell::new(id_map)),
shared: Arc::new(scx),
- enable_index_page,
- index_page,
};
// Crawl the crate to build various caches used for the output
},
_ => PathBuf::new(),
};
- let extern_url = extern_urls.get(&e.name).map(|u| &**u);
+ let extern_url = extern_html_root_urls.get(&e.name).map(|u| &**u);
cache.extern_locations.insert(n, (e.name.clone(), src_root,
extern_location(e, extern_url, &cx.dst)));
CACHE_KEY.with(|v| *v.borrow_mut() = cache.clone());
CURRENT_LOCATION_KEY.with(|s| s.borrow_mut().clear());
- write_shared(&cx, &krate, &*cache, index, enable_minification, matches, diag)?;
+ write_shared(&cx, &krate, &*cache, index, &md_opts, diag)?;
// And finally render the whole crate's documentation
cx.krate(krate)
krate: &clean::Crate,
cache: &Cache,
search_index: String,
- enable_minification: bool,
- matches: &getopts::Matches,
+ options: &RenderOptions,
diag: &errors::Handler,
) -> Result<(), Error> {
// Write out the shared files. Note that these are shared among all rustdoc
write_minify(cx.dst.join(&format!("rustdoc{}.css", cx.shared.resource_suffix)),
include_str!("static/rustdoc.css"),
- enable_minification)?;
+ options.enable_minification)?;
write_minify(cx.dst.join(&format!("settings{}.css", cx.shared.resource_suffix)),
include_str!("static/settings.css"),
- enable_minification)?;
+ options.enable_minification)?;
// To avoid "light.css" to be overwritten, we'll first run over the received themes and only
// then we'll run over the "official" styles.
include_bytes!("static/wheel.svg"))?;
write_minify(cx.dst.join(&format!("light{}.css", cx.shared.resource_suffix)),
include_str!("static/themes/light.css"),
- enable_minification)?;
+ options.enable_minification)?;
themes.insert("light".to_owned());
write_minify(cx.dst.join(&format!("dark{}.css", cx.shared.resource_suffix)),
include_str!("static/themes/dark.css"),
- enable_minification)?;
+ options.enable_minification)?;
themes.insert("dark".to_owned());
let mut themes: Vec<&String> = themes.iter().collect();
write_minify(cx.dst.join(&format!("main{}.js", cx.shared.resource_suffix)),
include_str!("static/main.js"),
- enable_minification)?;
+ options.enable_minification)?;
write_minify(cx.dst.join(&format!("settings{}.js", cx.shared.resource_suffix)),
include_str!("static/settings.js"),
- enable_minification)?;
+ options.enable_minification)?;
{
let mut data = format!("var resourcesSuffix = \"{}\";\n",
data.push_str(include_str!("static/storage.js"));
write_minify(cx.dst.join(&format!("storage{}.js", cx.shared.resource_suffix)),
&data,
- enable_minification)?;
+ options.enable_minification)?;
}
if let Some(ref css) = cx.shared.css_file_extension {
let out = cx.dst.join(&format!("theme{}.css", cx.shared.resource_suffix));
- if !enable_minification {
+ if !options.enable_minification {
try_err!(fs::copy(css, out), css);
} else {
let mut f = try_err!(File::open(css), css);
let mut buffer = String::with_capacity(1000);
try_err!(f.read_to_string(&mut buffer), css);
- write_minify(out, &buffer, enable_minification)?;
+ write_minify(out, &buffer, options.enable_minification)?;
}
}
write_minify(cx.dst.join(&format!("normalize{}.css", cx.shared.resource_suffix)),
include_str!("static/normalize.css"),
- enable_minification)?;
+ options.enable_minification)?;
write(cx.dst.join("FiraSans-Regular.woff"),
include_bytes!("static/FiraSans-Regular.woff"))?;
write(cx.dst.join("FiraSans-Medium.woff"),
let mut w = try_err!(File::create(&dst), &dst);
try_err!(writeln!(&mut w, "var N = null;var searchIndex = {{}};"), &dst);
for index in &all_indexes {
- try_err!(write_minify_replacer(&mut w, &*index, enable_minification,
+ try_err!(write_minify_replacer(&mut w, &*index, options.enable_minification,
&[(minifier::js::Keyword::Null, "N")]),
&dst);
}
try_err!(writeln!(&mut w, "initSearch(searchIndex);"), &dst);
- if cx.enable_index_page == true {
- if let Some(ref index_page) = cx.index_page {
- ::markdown::render(index_page,
- cx.dst.clone(),
- &matches, &(*cx.shared).layout.external_html,
- !matches.opt_present("markdown-no-toc"),
- diag);
+ if options.enable_index_page {
+ if let Some(index_page) = options.index_page.clone() {
+ let mut md_opts = options.clone();
+ md_opts.output = cx.dst.clone();
+ md_opts.external_html = (*cx.shared).layout.external_html.clone();
+
+ ::markdown::render(index_page, md_opts, diag);
} else {
let dst = cx.dst.join("index.html");
let mut w = BufWriter::new(try_err!(File::create(&dst), &dst));
extern crate serialize as rustc_serialize; // used by deriving
-use errors::ColorConfig;
-
-use std::collections::{BTreeMap, BTreeSet};
use std::default::Default;
use std::env;
use std::panic;
-use std::path::{Path, PathBuf};
use std::process;
use std::sync::mpsc::channel;
-use syntax::edition::Edition;
-use externalfiles::ExternalHtml;
use rustc::session::{early_warn, early_error};
-use rustc::session::search_paths::SearchPaths;
-use rustc::session::config::{ErrorOutputType, RustcOptGroup, Externs, CodegenOptions};
-use rustc::session::config::{nightly_options, build_codegen_options};
-use rustc_target::spec::TargetTriple;
-use rustc::session::config::get_cmd_lint_options;
+use rustc::session::config::{ErrorOutputType, RustcOptGroup};
#[macro_use]
mod externalfiles;
mod clean;
+mod config;
mod core;
mod doctree;
mod fold;
struct Output {
krate: clean::Crate,
renderinfo: html::render::RenderInfo,
+ renderopts: config::RenderOptions,
passes: Vec<String>,
}
early_error(ErrorOutputType::default(), &err.to_string());
}
};
- // Check for unstable options.
- nightly_options::check_nightly_options(&matches, &opts());
-
- if matches.opt_present("h") || matches.opt_present("help") {
- usage("rustdoc");
- return 0;
- } else if matches.opt_present("version") {
- rustc_driver::version("rustdoc", &matches);
- return 0;
- }
-
- if matches.opt_strs("passes") == ["list"] {
- println!("Available passes for running rustdoc:");
- for pass in passes::PASSES {
- println!("{:>20} - {}", pass.name(), pass.description());
- }
- println!("\nDefault passes for rustdoc:");
- for &name in passes::DEFAULT_PASSES {
- println!("{:>20}", name);
- }
- println!("\nPasses run with `--document-private-items`:");
- for &name in passes::DEFAULT_PRIVATE_PASSES {
- println!("{:>20}", name);
- }
- return 0;
- }
-
- let color = match matches.opt_str("color").as_ref().map(|s| &s[..]) {
- Some("auto") => ColorConfig::Auto,
- Some("always") => ColorConfig::Always,
- Some("never") => ColorConfig::Never,
- None => ColorConfig::Auto,
- Some(arg) => {
- early_error(ErrorOutputType::default(),
- &format!("argument for --color must be `auto`, `always` or `never` \
- (instead was `{}`)", arg));
- }
+ let options = match config::Options::from_matches(&matches) {
+ Ok(opts) => opts,
+ Err(code) => return code,
};
- let error_format = match matches.opt_str("error-format").as_ref().map(|s| &s[..]) {
- Some("human") => ErrorOutputType::HumanReadable(color),
- Some("json") => ErrorOutputType::Json(false),
- Some("pretty-json") => ErrorOutputType::Json(true),
- Some("short") => ErrorOutputType::Short(color),
- None => ErrorOutputType::HumanReadable(color),
- Some(arg) => {
- early_error(ErrorOutputType::default(),
- &format!("argument for --error-format must be `human`, `json` or \
- `short` (instead was `{}`)", arg));
- }
- };
- let treat_err_as_bug = matches.opt_strs("Z").iter().any(|x| {
- *x == "treat-err-as-bug"
- });
- let ui_testing = matches.opt_strs("Z").iter().any(|x| {
- *x == "ui-testing"
- });
-
- let diag = core::new_handler(error_format, None, treat_err_as_bug, ui_testing);
-
- // check for deprecated options
- check_deprecated_options(&matches, &diag);
-
- let to_check = matches.opt_strs("theme-checker");
- if !to_check.is_empty() {
- let paths = theme::load_css_paths(include_bytes!("html/static/themes/light.css"));
- let mut errors = 0;
-
- println!("rustdoc: [theme-checker] Starting tests!");
- for theme_file in to_check.iter() {
- print!(" - Checking \"{}\"...", theme_file);
- let (success, differences) = theme::test_theme_against(theme_file, &paths, &diag);
- if !differences.is_empty() || !success {
- println!(" FAILED");
- errors += 1;
- if !differences.is_empty() {
- println!("{}", differences.join("\n"));
- }
- } else {
- println!(" OK");
- }
- }
- if errors != 0 {
- return 1;
- }
- return 0;
- }
-
- if matches.free.is_empty() {
- diag.struct_err("missing file operand").emit();
- return 1;
- }
- if matches.free.len() > 1 {
- diag.struct_err("too many file operands").emit();
- return 1;
- }
- let input = matches.free[0].clone();
-
- let mut libs = SearchPaths::new();
- for s in &matches.opt_strs("L") {
- libs.add_path(s, error_format);
- }
- let externs = match parse_externs(&matches) {
- Ok(ex) => ex,
- Err(err) => {
- diag.struct_err(&err).emit();
- return 1;
- }
- };
- let extern_urls = match parse_extern_html_roots(&matches) {
- Ok(ex) => ex,
- Err(err) => {
- diag.struct_err(err).emit();
- return 1;
- }
- };
-
- let test_args = matches.opt_strs("test-args");
- let test_args: Vec<String> = test_args.iter()
- .flat_map(|s| s.split_whitespace())
- .map(|s| s.to_string())
- .collect();
-
- let should_test = matches.opt_present("test");
- let markdown_input = Path::new(&input).extension()
- .map_or(false, |e| e == "md" || e == "markdown");
-
- let output = matches.opt_str("o").map(|s| PathBuf::from(&s));
- let css_file_extension = matches.opt_str("e").map(|s| PathBuf::from(&s));
- let mut cfgs = matches.opt_strs("cfg");
- cfgs.push("rustdoc".to_string());
-
- if let Some(ref p) = css_file_extension {
- if !p.is_file() {
- diag.struct_err("option --extend-css argument must be a file").emit();
- return 1;
- }
- }
-
- let mut themes = Vec::new();
- if matches.opt_present("themes") {
- let paths = theme::load_css_paths(include_bytes!("html/static/themes/light.css"));
-
- for (theme_file, theme_s) in matches.opt_strs("themes")
- .iter()
- .map(|s| (PathBuf::from(&s), s.to_owned())) {
- if !theme_file.is_file() {
- diag.struct_err("option --themes arguments must all be files").emit();
- return 1;
- }
- let (success, ret) = theme::test_theme_against(&theme_file, &paths, &diag);
- if !success || !ret.is_empty() {
- diag.struct_err(&format!("invalid theme: \"{}\"", theme_s))
- .help("check what's wrong with the --theme-checker option")
- .emit();
- return 1;
- }
- themes.push(theme_file);
- }
- }
-
- let mut id_map = html::markdown::IdMap::new();
- id_map.populate(html::render::initial_ids());
- let external_html = match ExternalHtml::load(
- &matches.opt_strs("html-in-header"),
- &matches.opt_strs("html-before-content"),
- &matches.opt_strs("html-after-content"),
- &matches.opt_strs("markdown-before-content"),
- &matches.opt_strs("markdown-after-content"), &diag, &mut id_map) {
- Some(eh) => eh,
- None => return 3,
- };
- let crate_name = matches.opt_str("crate-name");
- let playground_url = matches.opt_str("playground-url");
- let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from);
- let display_warnings = matches.opt_present("display-warnings");
- let linker = matches.opt_str("linker").map(PathBuf::from);
- let sort_modules_alphabetically = !matches.opt_present("sort-modules-by-appearance");
- let resource_suffix = matches.opt_str("resource-suffix");
- let index_page = matches.opt_str("index-page").map(|s| PathBuf::from(&s));
- let enable_index_page = matches.opt_present("enable-index-page") || index_page.is_some();
- let enable_minification = !matches.opt_present("disable-minification");
-
- let edition = matches.opt_str("edition").unwrap_or("2015".to_string());
- let edition = match edition.parse() {
- Ok(e) => e,
- Err(_) => {
- diag.struct_err("could not parse edition").emit();
- return 1;
- }
- };
- if let Some(ref index_page) = index_page {
- if !index_page.is_file() {
- diag.struct_err("option `--index-page` argument must be a file").emit();
- return 1;
- }
- }
- let cg = build_codegen_options(&matches, ErrorOutputType::default());
+ let diag = core::new_handler(options.error_format,
+ None,
+ options.debugging_options.treat_err_as_bug,
+ options.debugging_options.ui_testing);
- match (should_test, markdown_input) {
- (true, true) => {
- return markdown::test(&input, cfgs, libs, externs, test_args, maybe_sysroot,
- display_warnings, linker, edition, cg, &diag)
- }
- (true, false) => {
- return test::run(Path::new(&input), cfgs, libs, externs, test_args, crate_name,
- maybe_sysroot, display_warnings, linker, edition, cg)
- }
- (false, true) => return markdown::render(Path::new(&input),
- output.unwrap_or(PathBuf::from("doc")),
- &matches, &external_html,
- !matches.opt_present("markdown-no-toc"), &diag),
+ match (options.should_test, options.markdown_input()) {
+ (true, true) => return markdown::test(options, &diag),
+ (true, false) => return test::run(options),
+ (false, true) => return markdown::render(options.input, options.render_options, &diag),
(false, false) => {}
}
- let output_format = matches.opt_str("w");
-
- let res = acquire_input(PathBuf::from(input), externs, edition, cg, matches, error_format,
- move |out, matches| {
- let Output { krate, passes, renderinfo } = out;
- let diag = core::new_handler(error_format, None, treat_err_as_bug, ui_testing);
+ // need to move these items separately because we lose them by the time the closure is called,
+ // but we can't crates the Handler ahead of time because it's not Send
+ let diag_opts = (options.error_format,
+ options.debugging_options.treat_err_as_bug,
+ options.debugging_options.ui_testing);
+ rust_input(options, move |out| {
+ let Output { krate, passes, renderinfo, renderopts } = out;
info!("going to format");
- match output_format.as_ref().map(|s| &**s) {
- Some("html") | None => {
- html::render::run(krate, extern_urls, &external_html, playground_url,
- output.unwrap_or(PathBuf::from("doc")),
- resource_suffix.unwrap_or(String::new()),
- passes.into_iter().collect(),
- css_file_extension,
- renderinfo,
- sort_modules_alphabetically,
- themes,
- enable_minification, id_map,
- enable_index_page, index_page,
- &matches,
- &diag)
- .expect("failed to generate documentation");
- 0
- }
- Some(s) => {
- diag.struct_err(&format!("unknown output format: {}", s)).emit();
- 1
- }
- }
- });
- res.unwrap_or_else(|s| {
- diag.struct_err(&format!("input error: {}", s)).emit();
- 1
+ let (error_format, treat_err_as_bug, ui_testing) = diag_opts;
+ let diag = core::new_handler(error_format, None, treat_err_as_bug, ui_testing);
+ html::render::run(krate, renderopts, passes.into_iter().collect(), renderinfo, &diag)
+ .expect("failed to generate documentation");
+ 0
})
}
-/// Looks inside the command line arguments to extract the relevant input format
-/// and files and then generates the necessary rustdoc output for formatting.
-fn acquire_input<R, F>(input: PathBuf,
- externs: Externs,
- edition: Edition,
- cg: CodegenOptions,
- matches: getopts::Matches,
- error_format: ErrorOutputType,
- f: F)
- -> Result<R, String>
-where R: 'static + Send, F: 'static + Send + FnOnce(Output, &getopts::Matches) -> R {
- match matches.opt_str("r").as_ref().map(|s| &**s) {
- Some("rust") => Ok(rust_input(input, externs, edition, cg, matches, error_format, f)),
- Some(s) => Err(format!("unknown input format: {}", s)),
- None => Ok(rust_input(input, externs, edition, cg, matches, error_format, f))
- }
-}
-
-/// Extracts `--extern CRATE=PATH` arguments from `matches` and
-/// returns a map mapping crate names to their paths or else an
-/// error message.
-// FIXME(eddyb) This shouldn't be duplicated with `rustc::session`.
-fn parse_externs(matches: &getopts::Matches) -> Result<Externs, String> {
- let mut externs: BTreeMap<_, BTreeSet<_>> = BTreeMap::new();
- for arg in &matches.opt_strs("extern") {
- let mut parts = arg.splitn(2, '=');
- let name = parts.next().ok_or("--extern value must not be empty".to_string())?;
- let location = parts.next().map(|s| s.to_string());
- if location.is_none() && !nightly_options::is_unstable_enabled(matches) {
- return Err("the `-Z unstable-options` flag must also be passed to \
- enable `--extern crate_name` without `=path`".to_string());
- }
- let name = name.to_string();
- externs.entry(name).or_default().insert(location);
- }
- Ok(Externs::new(externs))
-}
-
-/// Extracts `--extern-html-root-url` arguments from `matches` and returns a map of crate names to
-/// the given URLs. If an `--extern-html-root-url` argument was ill-formed, returns an error
-/// describing the issue.
-fn parse_extern_html_roots(matches: &getopts::Matches)
- -> Result<BTreeMap<String, String>, &'static str>
-{
- let mut externs = BTreeMap::new();
- for arg in &matches.opt_strs("extern-html-root-url") {
- let mut parts = arg.splitn(2, '=');
- let name = parts.next().ok_or("--extern-html-root-url must not be empty")?;
- let url = parts.next().ok_or("--extern-html-root-url must be of the form name=url")?;
- externs.insert(name.to_string(), url.to_string());
- }
-
- Ok(externs)
-}
-
/// Interprets the input file as a rust source file, passing it through the
/// compiler all the way through the analysis passes. The rustdoc output is then
/// generated from the cleaned AST of the crate.
///
/// This form of input will run all of the plug/cleaning passes
-fn rust_input<R, F>(cratefile: PathBuf,
- externs: Externs,
- edition: Edition,
- cg: CodegenOptions,
- matches: getopts::Matches,
- error_format: ErrorOutputType,
- f: F) -> R
+fn rust_input<R, F>(options: config::Options, f: F) -> R
where R: 'static + Send,
- F: 'static + Send + FnOnce(Output, &getopts::Matches) -> R
+ F: 'static + Send + FnOnce(Output) -> R
{
- let default_passes = if matches.opt_present("no-defaults") {
- passes::DefaultPassOption::None
- } else if matches.opt_present("document-private-items") {
- passes::DefaultPassOption::Private
- } else {
- passes::DefaultPassOption::Default
- };
-
- let manual_passes = matches.opt_strs("passes");
- let plugins = matches.opt_strs("plugins");
-
// First, parse the crate and extract all relevant information.
- let mut paths = SearchPaths::new();
- for s in &matches.opt_strs("L") {
- paths.add_path(s, ErrorOutputType::default());
- }
- let mut cfgs = matches.opt_strs("cfg");
- cfgs.push("rustdoc".to_string());
- let triple = matches.opt_str("target").map(|target| {
- if target.ends_with(".json") {
- TargetTriple::TargetPath(PathBuf::from(target))
- } else {
- TargetTriple::TargetTriple(target)
- }
- });
- let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from);
- let crate_name = matches.opt_str("crate-name");
- let crate_version = matches.opt_str("crate-version");
- let plugin_path = matches.opt_str("plugin-path");
-
info!("starting to run rustc");
- let display_warnings = matches.opt_present("display-warnings");
-
- let force_unstable_if_unmarked = matches.opt_strs("Z").iter().any(|x| {
- *x == "force-unstable-if-unmarked"
- });
- let treat_err_as_bug = matches.opt_strs("Z").iter().any(|x| {
- *x == "treat-err-as-bug"
- });
- let ui_testing = matches.opt_strs("Z").iter().any(|x| {
- *x == "ui-testing"
- });
-
- let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(&matches, error_format);
let (tx, rx) = channel();
let result = rustc_driver::monitor(move || syntax::with_globals(move || {
- use rustc::session::config::Input;
-
- let (mut krate, renderinfo, passes) =
- core::run_core(paths, cfgs, externs, Input::File(cratefile), triple, maybe_sysroot,
- display_warnings, crate_name.clone(),
- force_unstable_if_unmarked, edition, cg, error_format,
- lint_opts, lint_cap, describe_lints, manual_passes, default_passes,
- treat_err_as_bug, ui_testing);
+ let crate_name = options.crate_name.clone();
+ let crate_version = options.crate_version.clone();
+ let (mut krate, renderinfo, renderopts, passes) = core::run_core(options);
info!("finished with rustc");
krate.version = crate_version;
- if !plugins.is_empty() {
- eprintln!("WARNING: --plugins no longer functions; see CVE-2018-1000622");
- }
-
- if !plugin_path.is_none() {
- eprintln!("WARNING: --plugin-path no longer functions; see CVE-2018-1000622");
- }
-
info!("Executing passes");
for pass in &passes {
krate = pass(krate);
}
- tx.send(f(Output { krate: krate, renderinfo: renderinfo, passes: passes },
- &matches)).unwrap();
+ tx.send(f(Output {
+ krate: krate,
+ renderinfo: renderinfo,
+ renderopts,
+ passes: passes
+ })).unwrap();
}));
match result {
Err(_) => panic::resume_unwind(Box::new(errors::FatalErrorMarker)),
}
}
-
-/// Prints deprecation warnings for deprecated options
-fn check_deprecated_options(matches: &getopts::Matches, diag: &errors::Handler) {
- let deprecated_flags = [
- "input-format",
- "output-format",
- "no-defaults",
- "passes",
- ];
-
- for flag in deprecated_flags.into_iter() {
- if matches.opt_present(flag) {
- let mut err = diag.struct_warn(&format!("the '{}' flag is considered deprecated",
- flag));
- err.warn("please see https://github.com/rust-lang/rust/issues/44136");
-
- if *flag == "no-defaults" {
- err.help("you may want to use --document-private-items");
- }
-
- err.emit();
- }
- }
-}
use std::default::Default;
use std::fs::File;
use std::io::prelude::*;
-use std::path::{PathBuf, Path};
+use std::path::PathBuf;
use std::cell::RefCell;
use errors;
-use getopts;
use testing;
-use rustc::session::search_paths::SearchPaths;
-use rustc::session::config::{Externs, CodegenOptions};
use syntax::source_map::DUMMY_SP;
use syntax::feature_gate::UnstableFeatures;
-use syntax::edition::Edition;
-use externalfiles::{ExternalHtml, LoadStringError, load_string};
+use externalfiles::{LoadStringError, load_string};
+use config::{Options, RenderOptions};
use html::escape::Escape;
use html::markdown;
use html::markdown::{ErrorCodes, IdMap, Markdown, MarkdownWithToc, find_testable_code};
/// Render `input` (e.g. "foo.md") into an HTML file in `output`
/// (e.g. output = "bar" => "bar/foo.html").
-pub fn render(input: &Path, mut output: PathBuf, matches: &getopts::Matches,
- external_html: &ExternalHtml, include_toc: bool, diag: &errors::Handler) -> isize {
+pub fn render(input: PathBuf, options: RenderOptions, diag: &errors::Handler) -> isize {
+ let mut output = options.output;
output.push(input.file_stem().unwrap());
output.set_extension("html");
let mut css = String::new();
- for name in &matches.opt_strs("markdown-css") {
+ for name in &options.markdown_css {
let s = format!("<link rel=\"stylesheet\" type=\"text/css\" href=\"{}\">\n", name);
css.push_str(&s)
}
- let input_str = match load_string(input, diag) {
+ let input_str = match load_string(&input, diag) {
Ok(s) => s,
Err(LoadStringError::ReadFail) => return 1,
Err(LoadStringError::BadUtf8) => return 2,
};
- if let Some(playground) = matches.opt_str("markdown-playground-url").or(
- matches.opt_str("playground-url")) {
+ let playground_url = options.markdown_playground_url
+ .or(options.playground_url);
+ if let Some(playground) = playground_url {
markdown::PLAYGROUND.with(|s| { *s.borrow_mut() = Some((None, playground)); });
}
let mut ids = IdMap::new();
let error_codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
- let text = if include_toc {
+ let text = if !options.markdown_no_toc {
MarkdownWithToc(text, RefCell::new(&mut ids), error_codes).to_string()
} else {
Markdown(text, &[], RefCell::new(&mut ids), error_codes).to_string()
</html>"#,
title = Escape(title),
css = css,
- in_header = external_html.in_header,
- before_content = external_html.before_content,
+ in_header = options.external_html.in_header,
+ before_content = options.external_html.before_content,
text = text,
- after_content = external_html.after_content,
+ after_content = options.external_html.after_content,
);
match err {
}
/// Run any tests/code examples in the markdown file `input`.
-pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
- mut test_args: Vec<String>, maybe_sysroot: Option<PathBuf>,
- display_warnings: bool, linker: Option<PathBuf>, edition: Edition,
- cg: CodegenOptions, diag: &errors::Handler) -> isize {
- let input_str = match load_string(input, diag) {
+pub fn test(mut options: Options, diag: &errors::Handler) -> isize {
+ let input_str = match load_string(&options.input, diag) {
Ok(s) => s,
Err(LoadStringError::ReadFail) => return 1,
Err(LoadStringError::BadUtf8) => return 2,
let mut opts = TestOptions::default();
opts.no_crate_inject = true;
- opts.display_warnings = display_warnings;
- let mut collector = Collector::new(input.to_owned(), cfgs, libs, cg, externs,
- true, opts, maybe_sysroot, None,
- Some(PathBuf::from(input)),
- linker, edition);
+ opts.display_warnings = options.display_warnings;
+ let mut collector = Collector::new(options.input.display().to_string(), options.cfgs,
+ options.libs, options.codegen_options, options.externs,
+ true, opts, options.maybe_sysroot, None,
+ Some(options.input),
+ options.linker, options.edition);
collector.set_position(DUMMY_SP);
let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
let res = find_testable_code(&input_str, &mut collector, codes);
if let Err(err) = res {
diag.span_warn(DUMMY_SP, &err.to_string());
}
- test_args.insert(0, "rustdoctest".to_string());
- testing::test_main(&test_args, collector.tests,
- testing::Options::new().display_output(display_warnings));
+ options.test_args.insert(0, "rustdoctest".to_string());
+ testing::test_main(&options.test_args, collector.tests,
+ testing::Options::new().display_output(options.display_warnings));
0
}
use std::ffi::OsString;
use std::io::prelude::*;
use std::io;
-use std::path::{Path, PathBuf};
+use std::path::PathBuf;
use std::panic::{self, AssertUnwindSafe};
use std::process::Command;
use std::str;
use errors::emitter::ColorConfig;
use clean::Attributes;
+use config::Options;
use html::markdown::{self, ErrorCodes, LangString};
#[derive(Clone, Default)]
pub attrs: Vec<String>,
}
-pub fn run(input_path: &Path,
- cfgs: Vec<String>,
- libs: SearchPaths,
- externs: Externs,
- mut test_args: Vec<String>,
- crate_name: Option<String>,
- maybe_sysroot: Option<PathBuf>,
- display_warnings: bool,
- linker: Option<PathBuf>,
- edition: Edition,
- cg: CodegenOptions)
- -> isize {
- let input = config::Input::File(input_path.to_owned());
+pub fn run(mut options: Options) -> isize {
+ let input = config::Input::File(options.input.clone());
let sessopts = config::Options {
- maybe_sysroot: maybe_sysroot.clone().or_else(
+ maybe_sysroot: options.maybe_sysroot.clone().or_else(
|| Some(env::current_exe().unwrap().parent().unwrap().parent().unwrap().to_path_buf())),
- search_paths: libs.clone(),
+ search_paths: options.libs.clone(),
crate_types: vec![config::CrateType::Dylib],
- cg: cg.clone(),
- externs: externs.clone(),
+ cg: options.codegen_options.clone(),
+ externs: options.externs.clone(),
unstable_features: UnstableFeatures::from_environment(),
lint_cap: Some(::rustc::lint::Level::Allow),
actually_rustdoc: true,
debugging_opts: config::DebuggingOptions {
..config::basic_debugging_options()
},
- edition,
+ edition: options.edition,
..config::Options::default()
};
driver::spawn_thread_pool(sessopts, |sessopts| {
Some(source_map.clone()));
let mut sess = session::build_session_(
- sessopts, Some(input_path.to_owned()), handler, source_map.clone(),
+ sessopts, Some(options.input), handler, source_map.clone(),
);
let codegen_backend = rustc_driver::get_codegen_backend(&sess);
let cstore = CStore::new(codegen_backend.metadata_loader());
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
- let mut cfg = config::build_configuration(&sess, config::parse_cfgspecs(cfgs.clone()));
+ let mut cfg = config::build_configuration(&sess,
+ config::parse_cfgspecs(options.cfgs.clone()));
target_features::add_configuration(&mut cfg, &sess, &*codegen_backend);
sess.parse_sess.config = cfg;
).expect("phase_2_configure_and_expand aborted in rustdoc!")
};
- let crate_name = crate_name.unwrap_or_else(|| {
+ let crate_name = options.crate_name.unwrap_or_else(|| {
::rustc_codegen_utils::link::find_crate_name(None, &hir_forest.krate().attrs, &input)
});
let mut opts = scrape_test_config(hir_forest.krate());
- opts.display_warnings |= display_warnings;
+ opts.display_warnings |= options.display_warnings;
let mut collector = Collector::new(
crate_name,
- cfgs,
- libs,
- cg,
- externs,
+ options.cfgs,
+ options.libs,
+ options.codegen_options,
+ options.externs,
false,
opts,
- maybe_sysroot,
+ options.maybe_sysroot,
Some(source_map),
- None,
- linker,
- edition
+ None,
+ options.linker,
+ options.edition
);
{
});
}
- test_args.insert(0, "rustdoctest".to_string());
+ options.test_args.insert(0, "rustdoctest".to_string());
- testing::test_main(&test_args,
+ testing::test_main(&options.test_args,
collector.tests.into_iter().collect(),
- testing::Options::new().display_output(display_warnings));
+ testing::Options::new().display_output(options.display_warnings));
0
})
}
///
/// [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.
attrs.iter().find(|attr| attr.check_name(name))
}
+pub fn filter_by_name<'a>(attrs: &'a [Attribute], name: &'a str)
+ -> impl Iterator<Item = &'a Attribute> {
+ attrs.iter().filter(move |attr| attr.check_name(name))
+}
+
pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str) -> Option<Symbol> {
attrs.iter()
.find(|at| at.check_name(name))
}
},
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),
}
ast::ItemKind::Struct(..) => {
- if let Some(attr) = attr::find_by_name(&i.attrs[..], "repr") {
+ for attr in attr::filter_by_name(&i.attrs[..], "repr") {
for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
if item.check_name("simd") {
gate_feature_post!(&self, repr_simd, attr.span,
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)
})
}
extern "C" const char *
LLVMRustArchiveChildName(LLVMRustArchiveChildConstRef Child, size_t *Size) {
-#if LLVM_VERSION_GE(4, 0)
Expected<StringRef> NameOrErr = Child->getName();
if (!NameOrErr) {
// rustc_codegen_llvm currently doesn't use this error string, but it might be
LLVMRustSetLastError(toString(NameOrErr.takeError()).c_str());
return nullptr;
}
-#else
- ErrorOr<StringRef> NameOrErr = Child->getName();
- if (NameOrErr.getError())
- return nullptr;
-#endif
StringRef Name = NameOrErr.get();
*Size = Name.size();
return Name.data();
extern "C" const char *LLVMRustArchiveChildData(LLVMRustArchiveChildRef Child,
size_t *Size) {
StringRef Buf;
-#if LLVM_VERSION_GE(4, 0)
Expected<StringRef> BufOrErr = Child->getBuffer();
if (!BufOrErr) {
LLVMRustSetLastError(toString(BufOrErr.takeError()).c_str());
return nullptr;
}
-#else
- ErrorOr<StringRef> BufOrErr = Child->getBuffer();
- if (BufOrErr.getError()) {
- LLVMRustSetLastError(BufOrErr.getError().message().c_str());
- return nullptr;
- }
-#endif
Buf = BufOrErr.get();
*Size = Buf.size();
return Buf.data();
std::unique_ptr<MemoryBuffer> Buf =
MemoryBuffer::getMemBufferCopy(StringRef(BC, Len));
-#if LLVM_VERSION_GE(4, 0)
Expected<std::unique_ptr<Module>> SrcOrError =
llvm::getLazyBitcodeModule(Buf->getMemBufferRef(), L->Ctx);
if (!SrcOrError) {
}
auto Src = std::move(*SrcOrError);
-#else
- ErrorOr<std::unique_ptr<Module>> Src =
- llvm::getLazyBitcodeModule(std::move(Buf), L->Ctx);
- if (!Src) {
- LLVMRustSetLastError(Src.getError().message().c_str());
- return false;
- }
-#endif
-#if LLVM_VERSION_GE(4, 0)
if (L->L.linkInModule(std::move(Src))) {
-#else
- if (L->L.linkInModule(std::move(Src.get()))) {
-#endif
LLVMRustSetLastError("");
return false;
}
#include "llvm/Target/TargetSubtargetInfo.h"
#endif
-#if LLVM_VERSION_GE(4, 0)
#include "llvm/Transforms/IPO/AlwaysInliner.h"
#include "llvm/Transforms/IPO/FunctionImport.h"
#include "llvm/Transforms/Utils/FunctionImportUtils.h"
#if LLVM_VERSION_LE(4, 0)
#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
#endif
-#endif
#include "llvm-c/Transforms/PassManagerBuilder.h"
-#if LLVM_VERSION_GE(4, 0)
-#define PGO_AVAILABLE
-#endif
-
using namespace llvm;
using namespace llvm::legacy;
LLVMPassManagerBuilderRef PMBR,
LLVMPassManagerRef PMR
) {
-#if LLVM_VERSION_GE(4, 0)
unwrap(PMBR)->populateThinLTOPassManager(*unwrap(PMR));
return true;
-#else
- return false;
-#endif
}
#ifdef LLVM_COMPONENT_X86
return Reloc::PIC_;
case LLVMRustRelocMode::DynamicNoPic:
return Reloc::DynamicNoPIC;
-#if LLVM_VERSION_GE(4, 0)
case LLVMRustRelocMode::ROPI:
return Reloc::ROPI;
case LLVMRustRelocMode::RWPI:
return Reloc::RWPI;
case LLVMRustRelocMode::ROPIRWPI:
return Reloc::ROPI_RWPI;
-#else
- default:
- break;
-#endif
}
report_fatal_error("Bad RelocModel.");
}
unwrap(PMBR)->SLPVectorize = SLPVectorize;
unwrap(PMBR)->OptLevel = fromRust(OptLevel);
unwrap(PMBR)->LoopVectorize = LoopVectorize;
-#if LLVM_VERSION_GE(4, 0)
unwrap(PMBR)->PrepareForThinLTO = PrepareForThinLTO;
-#endif
-#ifdef PGO_AVAILABLE
if (PGOGenPath) {
assert(!PGOUsePath);
unwrap(PMBR)->EnablePGOInstrGen = true;
assert(!PGOGenPath);
unwrap(PMBR)->PGOInstrUse = PGOUsePath;
}
-#else
- assert(!PGOGenPath && !PGOUsePath && "Should've caught earlier");
-#endif
}
// Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`
LLVMInitializePasses();
struct MyListener : PassRegistrationListener {
void passEnumerate(const PassInfo *Info) {
-#if LLVM_VERSION_GE(4, 0)
StringRef PassArg = Info->getPassArgument();
StringRef PassName = Info->getPassName();
if (!PassArg.empty()) {
printf("%15.*s - %.*s\n", (int)PassArg.size(), PassArg.data(),
(int)PassName.size(), PassName.data());
}
-#else
- if (Info->getPassArgument() && *Info->getPassArgument()) {
- printf("%15s - %s\n", Info->getPassArgument(), Info->getPassName());
- }
-#endif
}
} Listener;
extern "C" void LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMBR,
bool AddLifetimes) {
-#if LLVM_VERSION_GE(4, 0)
unwrap(PMBR)->Inliner = llvm::createAlwaysInlinerLegacyPass(AddLifetimes);
-#else
- unwrap(PMBR)->Inliner = createAlwaysInlinerPass(AddLifetimes);
-#endif
}
extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
unwrap(M)->setPIELevel(PIELevel::Level::Large);
}
-extern "C" bool
-LLVMRustThinLTOAvailable() {
-#if LLVM_VERSION_GE(4, 0)
- return true;
-#else
- return false;
-#endif
-}
-
-extern "C" bool
-LLVMRustPGOAvailable() {
-#ifdef PGO_AVAILABLE
- return true;
-#else
- return false;
-#endif
-}
-
-#if LLVM_VERSION_GE(4, 0)
-
// Here you'll find an implementation of ThinLTO as used by the Rust compiler
// right now. This ThinLTO support is only enabled on "recent ish" versions of
// LLVM, and otherwise it's just blanket rejected from other compilers.
MD->clearOperands();
MD->addOperand(Unit);
}
-
-#else
-
-struct LLVMRustThinLTOData {
-};
-
-struct LLVMRustThinLTOModule {
-};
-
-extern "C" LLVMRustThinLTOData*
-LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
- int num_modules,
- const char **preserved_symbols,
- int num_symbols) {
- report_fatal_error("ThinLTO not available");
-}
-
-extern "C" bool
-LLVMRustPrepareThinLTORename(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
- report_fatal_error("ThinLTO not available");
-}
-
-extern "C" bool
-LLVMRustPrepareThinLTOResolveWeak(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
- report_fatal_error("ThinLTO not available");
-}
-
-extern "C" bool
-LLVMRustPrepareThinLTOInternalize(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
- report_fatal_error("ThinLTO not available");
-}
-
-extern "C" bool
-LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
- report_fatal_error("ThinLTO not available");
-}
-
-extern "C" LLVMRustThinLTOModuleImports
-LLVMRustGetLLVMRustThinLTOModuleImports(const LLVMRustThinLTOData *Data) {
- report_fatal_error("ThinLTO not available");
-}
-
-extern "C" void
-LLVMRustFreeThinLTOData(LLVMRustThinLTOData *Data) {
- report_fatal_error("ThinLTO not available");
-}
-
-struct LLVMRustThinLTOBuffer {
-};
-
-extern "C" LLVMRustThinLTOBuffer*
-LLVMRustThinLTOBufferCreate(LLVMModuleRef M) {
- report_fatal_error("ThinLTO not available");
-}
-
-extern "C" void
-LLVMRustThinLTOBufferFree(LLVMRustThinLTOBuffer *Buffer) {
- report_fatal_error("ThinLTO not available");
-}
-
-extern "C" const void*
-LLVMRustThinLTOBufferPtr(const LLVMRustThinLTOBuffer *Buffer) {
- report_fatal_error("ThinLTO not available");
-}
-
-extern "C" size_t
-LLVMRustThinLTOBufferLen(const LLVMRustThinLTOBuffer *Buffer) {
- report_fatal_error("ThinLTO not available");
-}
-
-extern "C" LLVMModuleRef
-LLVMRustParseBitcodeForThinLTO(LLVMContextRef Context,
- const char *data,
- size_t len,
- const char *identifier) {
- report_fatal_error("ThinLTO not available");
-}
-
-extern "C" void
-LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod,
- DICompileUnit **A,
- DICompileUnit **B) {
- report_fatal_error("ThinLTO not available");
-}
-
-extern "C" void
-LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod) {
- report_fatal_error("ThinLTO not available");
-}
-
-#endif // LLVM_VERSION_GE(4, 0)
,
unwrapDI<DIFile>(File), LineNo
#endif
-#if LLVM_VERSION_GE(4, 0)
,
false // ExportSymbols (only relevant for C++ anonymous namespaces)
-#endif
));
}
}
#endif
-#if LLVM_VERSION_LT(4, 0)
-extern "C" LLVMValueRef
-LLVMBuildExactUDiv(LLVMBuilderRef B, LLVMValueRef LHS,
- LLVMValueRef RHS, const char *Name) {
- return wrap(unwrap(B)->CreateExactUDiv(unwrap(LHS), unwrap(RHS), Name));
-}
-#endif
-
#if LLVM_VERSION_GE(6, 0)
extern "C" LLVMValueRef
LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
#include "llvm/IR/LegacyPassManager.h"
-#if LLVM_VERSION_GE(4, 0)
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/Bitcode/BitcodeWriter.h"
-#else
-#include "llvm/Bitcode/ReaderWriter.h"
-#endif
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
-Subproject commit 431766a3fbcfb6dafb2d5a3866c1609bf44ee554
+Subproject commit 0309be1ade6bf61066f2c69f77ac3567b7dc31b5
// lldb-command:print padded_tuple
// lldbg-check:[...]$4 = &[(6, 7), (8, 9)]
-// lldbr-check:(&[(i32, i16)]) padded_tuple = { data_ptr = *0x555555555030 length = 2 }
+// lldbr-check:(&[(i32, i16)]) padded_tuple = { data_ptr = *[...] length = 2 }
// lldb-command:print padded_struct
// lldbg-check:[...]$5 = &[AStruct { x: 10, y: 11, z: 12 }, AStruct { x: 13, y: 14, z: 15 }]
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);
--- /dev/null
+-include ../../run-make-fulldeps/tools.mk
+
+# How to run this
+# $ ./x.py clean
+# $ ./x.py test --target thumbv7m-none-eabi src/test/run-make
+
+ifneq (,$(filter $(TARGET),thumbv6m-none-eabi thumbv7m-none-eabi))
+
+# For cargo setting
+export RUSTC := $(RUSTC_ORIGINAL)
+export LD_LIBRARY_PATH := $(HOST_RPATH_DIR)
+# We need to be outside of 'src' dir in order to run cargo
+export WORK_DIR := $(TMPDIR)
+export HERE := $(shell pwd)
+
+## clean up unused env variables which might cause harm.
+unexport RUSTC_LINKER
+unexport RUSTC_BOOTSTRAP
+unexport RUST_BUILD_STAGE
+unexport RUST_TEST_THREADS
+unexport RUST_TEST_TMPDIR
+unexport AR
+unexport CC
+unexport CXX
+
+all:
+ bash script.sh
+else
+all:
+endif
--- /dev/null
+[target.thumbv7m-none-eabi]
+# uncomment this to make `cargo run` execute programs on QEMU
+runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel"
+
+[target.thumbv6m-none-eabi]
+# uncomment this to make `cargo run` execute programs on QEMU
+# For now, we use cortex-m3 instead of cortex-m0 which are not supported by QEMU
+runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel"
+
+[target.'cfg(all(target_arch = "arm", target_os = "none"))']
+# uncomment ONE of these three option to make `cargo run` start a GDB session
+# which option to pick depends on your system
+# runner = "arm-none-eabi-gdb -q -x openocd.gdb"
+# runner = "gdb-multiarch -q -x openocd.gdb"
+# runner = "gdb -q -x openocd.gdb"
+
+rustflags = [
+ # LLD (shipped with the Rust toolchain) is used as the default linker
+ "-C", "link-arg=-Tlink.x",
+
+ # if you run into problems with LLD switch to the GNU linker by commenting out
+ # this line
+ # "-C", "linker=arm-none-eabi-ld",
+
+ # if you need to link to pre-compiled C libraries provided by a C toolchain
+ # use GCC as the linker by commenting out both lines above and then
+ # uncommenting the three lines below
+ # "-C", "linker=arm-none-eabi-gcc",
+ # "-C", "link-arg=-Wl,-Tlink.x",
+ # "-C", "link-arg=-nostartfiles",
+]
\ No newline at end of file
--- /dev/null
+[package]
+name = "example"
+version = "0.1.0"
+authors = ["Hideki Sekine <sekineh@me.com>"]
+# edition = "2018"
+
+[dependencies]
+cortex-m = "0.5.4"
+cortex-m-rt = "=0.5.4"
+panic-halt = "0.2.0"
+cortex-m-semihosting = "0.3.1"
--- /dev/null
+/* Device specific memory layout */
+
+/* This file is used to build the cortex-m-rt examples,
+ but not other applications using cortex-m-rt. */
+
+MEMORY
+{
+ /* FLASH and RAM are mandatory memory regions */
+ /* Update examples/data_overflow.rs if you change these sizes. */
+ FLASH : ORIGIN = 0x00000000, LENGTH = 256K
+ RAM : ORIGIN = 0x20000000, LENGTH = 64K
+
+ /* More memory regions can declared: for example this is a second RAM region */
+ /* CCRAM : ORIGIN = 0x10000000, LENGTH = 8K */
+}
+
+/* The location of the stack can be overridden using the `_stack_start` symbol.
+ By default it will be placed at the end of the RAM region */
+/* _stack_start = ORIGIN(CCRAM) + LENGTH(CCRAM); */
+
+/* The location of the .text section can be overridden using the `_stext` symbol.
+ By default it will place after .vector_table */
+/* _stext = ORIGIN(FLASH) + 0x40c; */
\ No newline at end of file
--- /dev/null
+// #![feature(stdsimd)]
+#![no_main]
+#![no_std]
+
+extern crate cortex_m;
+
+extern crate cortex_m_rt as rt;
+extern crate cortex_m_semihosting as semihosting;
+extern crate panic_halt;
+
+use core::fmt::Write;
+use cortex_m::asm;
+use rt::entry;
+
+entry!(main);
+
+fn main() -> ! {
+ let x = 42;
+
+ loop {
+ asm::nop();
+
+ // write something through semihosting interface
+ let mut hstdout = semihosting::hio::hstdout().unwrap();
+ write!(hstdout, "x = {}\n", x);
+
+ // exit from qemu
+ semihosting::debug::exit(semihosting::debug::EXIT_SUCCESS);
+ }
+}
--- /dev/null
+set -exuo pipefail
+
+CRATE=example
+
+env | sort
+mkdir -p $WORK_DIR
+pushd $WORK_DIR
+ rm -rf $CRATE || echo OK
+ cp -a $HERE/example .
+ pushd $CRATE
+ env RUSTFLAGS="-C linker=arm-none-eabi-ld -C link-arg=-Tlink.x" \
+ $CARGO run --target $TARGET | grep "x = 42"
+ env RUSTFLAGS="-C linker=arm-none-eabi-ld -C link-arg=-Tlink.x" \
+ $CARGO run --target $TARGET --release | grep "x = 42"
+ popd
+popd
$(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>());
+}
where Self::Item: std::fmt::Display {
let mut s = String::new();
if let Some(e) = self.next() {
- write!(s, "{}", e);
+ write!(s, "{}", e).unwrap();
for e in self {
s.push_str(sep);
- write!(s, "{}", e);
+ write!(s, "{}", e).unwrap();
}
}
s
first = false;
}
- write!(buf, " {:>2}", d.day());
+ write!(buf, " {:>2}", d.day()).unwrap();
}
// Insert more filler at the end to fill up the remainder of the week,
}
fn borrowing_writer_from_struct_and_formatting_struct_field(foo: Foo) {
- write!(foo.writer, "{}", foo.other);
+ write!(foo.writer, "{}", foo.other).unwrap();
}
fn main() {
let mut w = Vec::new();
- write!(&mut w as &mut Write, "");
- write!(&mut w, ""); // should coerce
+ write!(&mut w as &mut Write, "").unwrap();
+ write!(&mut w, "").unwrap(); // should coerce
println!("ok");
let mut s = Bar;
{
use std::fmt::Write;
- write!(&mut s, "test");
+ write!(&mut s, "test").unwrap();
}
}
use std::mem::size_of;
-// compile-flags: -Z fuel=foo=0
+// (#55495: The --error-format is to sidestep an issue in our test harness)
+// compile-flags: --error-format human -Z fuel=foo=0
struct S1(u8, u16, u8);
struct S2(u8, u16, u8);
--- /dev/null
+optimization-fuel-exhausted: Reorder fields of "S1"
+++ /dev/null
-optimization-fuel-exhausted: Reorder fields of "S1"
use std::mem::size_of;
-// compile-flags: -Z fuel=foo=1
+// (#55495: The --error-format is to sidestep an issue in our test harness)
+// compile-flags: --error-format human -Z fuel=foo=1
struct S1(u8, u16, u8);
struct S2(u8, u16, u8);
--- /dev/null
+optimization-fuel-exhausted: Reorder fields of "S2"
+++ /dev/null
-optimization-fuel-exhausted: Reorder fields of "S2"
--- /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() {
+}
3 | no
| ^^ not found in this scope
-thread '$DIR/failed-doctest-output.rs - OtherStruct (line 27)' panicked at 'couldn't compile the test', librustdoc/test.rs:332:13
+thread '$DIR/failed-doctest-output.rs - OtherStruct (line 27)' panicked at 'couldn't compile the test', librustdoc/test.rs:323:13
note: Run with `RUST_BACKTRACE=1` for a backtrace.
---- $DIR/failed-doctest-output.rs - SomeStruct (line 21) stdout ----
thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:3:1
note: Run with `RUST_BACKTRACE=1` for a backtrace.
-', librustdoc/test.rs:367:17
+', librustdoc/test.rs:358:17
failures:
--- /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.
+
+
+pub trait ScopeHandle<'scope> {}
+
+
+
+// @has issue_54705/struct.ScopeFutureContents.html
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'scope, S> \
+// Send for ScopeFutureContents<'scope, S> where S: Sync"
+//
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'scope, S> \
+// Sync for ScopeFutureContents<'scope, S> where S: Sync"
+pub struct ScopeFutureContents<'scope, S>
+ where S: ScopeHandle<'scope>,
+{
+ dummy: &'scope S,
+ this: Box<ScopeFuture<'scope, S>>,
+}
+
+struct ScopeFuture<'scope, S>
+ where S: ScopeHandle<'scope>,
+{
+ contents: ScopeFutureContents<'scope, S>,
+}
+
+unsafe impl<'scope, S> Send for ScopeFuture<'scope, S>
+ where S: ScopeHandle<'scope>,
+{}
+unsafe impl<'scope, S> Sync for ScopeFuture<'scope, S>
+ where S: ScopeHandle<'scope>,
+{}
|
= note: move occurs because `x` has type `T`, which does not implement the `Copy` trait
+error[E0505]: cannot move out of `x` because it is borrowed
+ --> $DIR/binop-move-semantics.rs:31:5
+ |
+LL | let m = &x;
+ | -- borrow of `x` occurs here
+...
+LL | x //~ ERROR: cannot move out of `x` because it is borrowed
+ | ^ move out of `x` occurs here
+...
+LL | use_mut(n); use_imm(m);
+ | - borrow later used here
+
+error[E0505]: cannot move out of `y` because it is borrowed
+ --> $DIR/binop-move-semantics.rs:33:5
+ |
+LL | let n = &mut y;
+ | ------ borrow of `y` occurs here
+...
+LL | y; //~ ERROR: cannot move out of `y` because it is borrowed
+ | ^ move out of `y` occurs here
+LL | use_mut(n); use_imm(m);
+ | - borrow later used here
+
error[E0507]: cannot move out of borrowed content
--> $DIR/binop-move-semantics.rs:40:5
|
| | immutable borrow later used here
| mutable borrow occurs here
-error: aborting due to 6 previous errors
+error: aborting due to 8 previous errors
-Some errors occurred: E0382, E0502, E0507.
+Some errors occurred: E0382, E0502, E0505, E0507.
For more information about an error, try `rustc --explain E0382`.
x //~ ERROR: cannot move out of `x` because it is borrowed
+
y; //~ ERROR: cannot move out of `y` because it is borrowed
+ use_mut(n); use_imm(m);
}
-
fn illegal_dereference<T: Add<Output=()>>(mut x: T, y: T) {
let m = &mut x;
let n = &y;
*m //~ ERROR: cannot move out of borrowed content
+
*n; //~ ERROR: cannot move out of borrowed content
+ use_imm(n); use_mut(m);
}
-
struct Foo;
impl<'a, 'b> Add<&'b Foo> for &'a mut Foo {
}
fn main() {}
+
+fn use_mut<T>(_: &mut T) { }
+fn use_imm<T>(_: &T) { }
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
- --> $DIR/borrowck-closures-mut-of-imm.rs:23:21
+ --> $DIR/borrowck-closures-mut-of-imm.rs:23:25
|
-LL | let c1 = || set(&mut *x);
- | ^^^^^^^ cannot borrow as mutable
+LL | let mut c1 = || set(&mut *x);
+ | ^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
- --> $DIR/borrowck-closures-mut-of-imm.rs:25:21
+ --> $DIR/borrowck-closures-mut-of-imm.rs:25:25
|
-LL | let c2 = || set(&mut *x);
- | ^^^^^^^ cannot borrow as mutable
+LL | let mut c2 = || set(&mut *x);
+ | ^^^^^^^ cannot borrow as mutable
-error: aborting due to 2 previous errors
+error[E0524]: two closures require unique access to `x` at the same time
+ --> $DIR/borrowck-closures-mut-of-imm.rs:25:18
+ |
+LL | let mut c1 = || set(&mut *x);
+ | -- - first borrow occurs due to use of `x` in closure
+ | |
+ | first closure is constructed here
+LL | //~^ ERROR cannot borrow
+LL | let mut c2 = || set(&mut *x);
+ | ^^ - second borrow occurs due to use of `x` in closure
+ | |
+ | second closure is constructed here
+...
+LL | c2(); c1();
+ | -- first borrow later used here
+
+error: aborting due to 3 previous errors
-For more information about this error, try `rustc --explain E0596`.
+Some errors occurred: E0524, E0596.
+For more information about an error, try `rustc --explain E0524`.
}
fn a(x: &isize) {
- let c1 = || set(&mut *x);
+ let mut c1 = || set(&mut *x);
//~^ ERROR cannot borrow
- let c2 = || set(&mut *x);
+ let mut c2 = || set(&mut *x);
//~^ ERROR cannot borrow
//~| ERROR two closures require unique access to `x` at the same time
+ c2(); c1();
}
fn main() {
error[E0524]: two closures require unique access to `x` at the same time
- --> $DIR/borrowck-closures-mut-of-imm.rs:25:14
+ --> $DIR/borrowck-closures-mut-of-imm.rs:25:18
|
-LL | let c1 = || set(&mut *x);
- | -- - previous borrow occurs due to use of `x` in closure
- | |
- | first closure is constructed here
+LL | let mut c1 = || set(&mut *x);
+ | -- - previous borrow occurs due to use of `x` in closure
+ | |
+ | first closure is constructed here
LL | //~^ ERROR cannot borrow
-LL | let c2 = || set(&mut *x);
- | ^^ - borrow occurs due to use of `x` in closure
- | |
- | second closure is constructed here
+LL | let mut c2 = || set(&mut *x);
+ | ^^ - borrow occurs due to use of `x` in closure
+ | |
+ | second closure is constructed here
...
LL | }
| - borrow from first closure ends here
error[E0596]: cannot borrow immutable borrowed content `***x` as mutable
- --> $DIR/borrowck-closures-mut-of-imm.rs:23:26
+ --> $DIR/borrowck-closures-mut-of-imm.rs:23:30
|
-LL | let c1 = || set(&mut *x);
- | ^^ cannot borrow as mutable
+LL | let mut c1 = || set(&mut *x);
+ | ^^ cannot borrow as mutable
error[E0596]: cannot borrow immutable borrowed content `***x` as mutable
- --> $DIR/borrowck-closures-mut-of-imm.rs:25:26
+ --> $DIR/borrowck-closures-mut-of-imm.rs:25:30
|
-LL | let c2 = || set(&mut *x);
- | ^^ cannot borrow as mutable
+LL | let mut c2 = || set(&mut *x);
+ | ^^ cannot borrow as mutable
error: aborting due to 3 previous errors
--- /dev/null
+error[E0524]: two closures require unique access to `x` at the same time
+ --> $DIR/borrowck-closures-mut-of-mut.rs:14:18
+ |
+LL | let mut c1 = || set(&mut *x);
+ | -- - first borrow occurs due to use of `x` in closure
+ | |
+ | first closure is constructed here
+LL | let mut c2 = || set(&mut *x);
+ | ^^ - second borrow occurs due to use of `x` in closure
+ | |
+ | second closure is constructed here
+LL | //~^ ERROR two closures require unique access to `x` at the same time
+LL | c2(); c1();
+ | -- first borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0524`.
--- /dev/null
+// Tests that two closures cannot simultaneously both have mutable
+// access to the variable. Related to issue #6801.
+
+fn get(x: &isize) -> isize {
+ *x
+}
+
+fn set(x: &mut isize) {
+ *x = 4;
+}
+
+fn a(x: &mut isize) {
+ let mut c1 = || set(&mut *x);
+ let mut c2 = || set(&mut *x);
+ //~^ ERROR two closures require unique access to `x` at the same time
+ c2(); c1();
+}
+
+fn main() {
+}
--- /dev/null
+error[E0524]: two closures require unique access to `x` at the same time
+ --> $DIR/borrowck-closures-mut-of-mut.rs:14:18
+ |
+LL | let mut c1 = || set(&mut *x);
+ | -- - previous borrow occurs due to use of `x` in closure
+ | |
+ | first closure is constructed here
+LL | let mut c2 = || set(&mut *x);
+ | ^^ - borrow occurs due to use of `x` in closure
+ | |
+ | second closure is constructed here
+...
+LL | }
+ | - borrow from first closure ends here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0524`.
--- /dev/null
+error[E0502]: cannot borrow `*v` as immutable because `v` is also borrowed as mutable
+ --> $DIR/borrowck-lend-flow-loop.rs:35:17
+ |
+LL | let mut x = &mut v;
+ | - mutable borrow occurs here
+...
+LL | borrow(&*v); //[ast]~ ERROR cannot borrow
+ | ^^ immutable borrow occurs here
+LL | }
+LL | }
+ | - mutable borrow ends here
+
+error[E0502]: cannot borrow `*v` as immutable because `v` is also borrowed as mutable
+ --> $DIR/borrowck-lend-flow-loop.rs:45:17
+ |
+LL | let mut x = &mut v;
+ | - mutable borrow occurs here
+LL | for _ in 0..3 {
+LL | borrow(&*v); //[ast]~ ERROR cannot borrow
+ | ^^ immutable borrow occurs here
+...
+LL | }
+ | - mutable borrow ends here
+
+error[E0502]: cannot borrow `*v` as mutable because `v` is also borrowed as immutable
+ --> $DIR/borrowck-lend-flow-loop.rs:57:25
+ |
+LL | borrow_mut(&mut *v); //[ast]~ ERROR cannot borrow
+ | ^^ mutable borrow occurs here
+LL | _x = &v;
+ | - immutable borrow occurs here
+LL | }
+LL | }
+ | - immutable borrow ends here
+
+error[E0502]: cannot borrow `*v` as mutable because `v` is also borrowed as immutable
+ --> $DIR/borrowck-lend-flow-loop.rs:69:25
+ |
+LL | borrow_mut(&mut *v); //[ast]~ ERROR cannot borrow
+ | ^^ mutable borrow occurs here
+LL | _x = &v;
+ | - immutable borrow occurs here
+LL | }
+LL | }
+ | - immutable borrow ends here
+
+error[E0502]: cannot borrow `*v` as mutable because `v` is also borrowed as immutable
+ --> $DIR/borrowck-lend-flow-loop.rs:86:21
+ |
+LL | _x = &v;
+ | - immutable borrow occurs here
+...
+LL | borrow_mut(&mut *v); //[ast]~ ERROR cannot borrow
+ | ^^ mutable borrow occurs here
+LL | }
+ | - immutable borrow ends here
+
+error[E0502]: cannot borrow `*v` as mutable because `v` is also borrowed as immutable
+ --> $DIR/borrowck-lend-flow-loop.rs:100:21
+ |
+LL | _x = &v;
+ | - immutable borrow occurs here
+...
+LL | borrow_mut(&mut *v); //[ast]~ ERROR cannot borrow
+ | ^^ mutable borrow occurs here
+LL | }
+ | - immutable borrow ends here
+
+error[E0502]: cannot borrow `*v` as immutable because `v` is also borrowed as mutable
+ --> $DIR/borrowck-lend-flow-loop.rs:109:17
+ |
+LL | borrow(&*v); //[ast]~ ERROR cannot borrow
+ | ^^ immutable borrow occurs here
+...
+LL | x = &mut v; //[ast]~ ERROR cannot borrow
+ | - mutable borrow occurs here
+...
+LL | }
+ | - mutable borrow ends here
+
+error[E0499]: cannot borrow `v` as mutable more than once at a time
+ --> $DIR/borrowck-lend-flow-loop.rs:112:22
+ |
+LL | x = &mut v; //[ast]~ ERROR cannot borrow
+ | ^ mutable borrow starts here in previous iteration of loop
+...
+LL | }
+ | - mutable borrow ends here
+
+error: aborting due to 8 previous errors
+
+Some errors occurred: E0499, E0502.
+For more information about an error, try `rustc --explain E0499`.
LL | let mut x = &mut v;
| ------ mutable borrow occurs here
LL | for _ in 0..3 {
-LL | borrow(&*v); //~ ERROR cannot borrow
+LL | borrow(&*v); //[ast]~ ERROR cannot borrow
| ^^^ immutable borrow occurs here
-LL | }
+...
LL | *x = box 5;
| -- mutable borrow used here, in later iteration of loop
|
LL | **x += 1;
| -------- mutable borrow used here, in later iteration of loop
-LL | borrow(&*v); //~ ERROR cannot borrow
+LL | borrow(&*v); //[ast]~ ERROR cannot borrow
| ^^^ immutable borrow occurs here
-LL | if cond2 {
-LL | x = &mut v; //~ ERROR cannot borrow
+...
+LL | x = &mut v; //[ast]~ ERROR cannot borrow
| ------ mutable borrow occurs here
error: aborting due to 2 previous errors
-// Copyright 2012 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.
-
-// Note: the borrowck analysis is currently flow-insensitive.
-// Therefore, some of these errors are marked as spurious and could be
-// corrected by a simple change to the analysis. The others are
-// either genuine or would require more advanced changes. The latter
-// cases are noted.
+// revisions: ast nll
+
+// Since we are testing nll migration explicitly as a separate
+// revision, don't worry about the --compare-mode=nll on this test.
+
+// ignore-compare-mode-nll
+
+//[ast]compile-flags: -Z borrowck=ast
+//[nll]compile-flags: -Z borrowck=migrate -Z two-phase-borrows
+
+// Note: the borrowck analysis was originally a flow-insensitive pass
+// over the AST. Therefore, some of these (AST) errors are marked as
+// spurious and are corrected by the flow-sensitive (NLL) analysis.
+// The others are either genuine or would require more advanced
+// changes. The latter cases are noted.
#![feature(box_syntax)]
let mut x = &mut v;
**x += 1;
loop {
- borrow(&*v); //~ ERROR cannot borrow
+ borrow(&*v); //[ast]~ ERROR cannot borrow
}
}
let mut v: Box<_> = box 3;
let mut x = &mut v;
for _ in 0..3 {
- borrow(&*v); //~ ERROR cannot borrow
+ borrow(&*v); //[ast]~ ERROR cannot borrow
+ //[nll]~^ ERROR cannot borrow
}
*x = box 5;
}
-
fn loop_aliased_mut() {
// In this instance, the borrow is carried through the loop.
let mut w: Box<_> = box 4;
let mut _x = &w;
loop {
- borrow_mut(&mut *v); //~ ERROR cannot borrow
+ borrow_mut(&mut *v); //[ast]~ ERROR cannot borrow
_x = &v;
}
}
let mut w: Box<_> = box 4;
let mut _x = &w;
while cond() {
- borrow_mut(&mut *v); //~ ERROR cannot borrow
+ borrow_mut(&mut *v); //[ast]~ ERROR cannot borrow
_x = &v;
}
}
_x = &v;
break;
}
- borrow_mut(&mut *v); //~ ERROR cannot borrow
+ borrow_mut(&mut *v); //[ast]~ ERROR cannot borrow
}
fn while_aliased_mut_break() {
_x = &v;
break;
}
- borrow_mut(&mut *v); //~ ERROR cannot borrow
+ borrow_mut(&mut *v); //[ast]~ ERROR cannot borrow
}
fn while_aliased_mut_cond(cond: bool, cond2: bool) {
let mut x = &mut w;
while cond {
**x += 1;
- borrow(&*v); //~ ERROR cannot borrow
+ borrow(&*v); //[ast]~ ERROR cannot borrow
+ //[nll]~^ ERROR cannot borrow
if cond2 {
- x = &mut v; //~ ERROR cannot borrow
+ x = &mut v; //[ast]~ ERROR cannot borrow
}
}
}
-
fn loop_break_pops_scopes<'r, F>(_v: &'r mut [usize], mut f: F) where
F: FnMut(&'r mut usize) -> bool,
{
+++ /dev/null
-error[E0502]: cannot borrow `*v` as immutable because `v` is also borrowed as mutable
- --> $DIR/borrowck-lend-flow-loop.rs:35:17
- |
-LL | let mut x = &mut v;
- | - mutable borrow occurs here
-...
-LL | borrow(&*v); //~ ERROR cannot borrow
- | ^^ immutable borrow occurs here
-LL | }
-LL | }
- | - mutable borrow ends here
-
-error[E0502]: cannot borrow `*v` as immutable because `v` is also borrowed as mutable
- --> $DIR/borrowck-lend-flow-loop.rs:45:17
- |
-LL | let mut x = &mut v;
- | - mutable borrow occurs here
-LL | for _ in 0..3 {
-LL | borrow(&*v); //~ ERROR cannot borrow
- | ^^ immutable borrow occurs here
-...
-LL | }
- | - mutable borrow ends here
-
-error[E0502]: cannot borrow `*v` as mutable because `v` is also borrowed as immutable
- --> $DIR/borrowck-lend-flow-loop.rs:57:25
- |
-LL | borrow_mut(&mut *v); //~ ERROR cannot borrow
- | ^^ mutable borrow occurs here
-LL | _x = &v;
- | - immutable borrow occurs here
-LL | }
-LL | }
- | - immutable borrow ends here
-
-error[E0502]: cannot borrow `*v` as mutable because `v` is also borrowed as immutable
- --> $DIR/borrowck-lend-flow-loop.rs:69:25
- |
-LL | borrow_mut(&mut *v); //~ ERROR cannot borrow
- | ^^ mutable borrow occurs here
-LL | _x = &v;
- | - immutable borrow occurs here
-LL | }
-LL | }
- | - immutable borrow ends here
-
-error[E0502]: cannot borrow `*v` as mutable because `v` is also borrowed as immutable
- --> $DIR/borrowck-lend-flow-loop.rs:86:21
- |
-LL | _x = &v;
- | - immutable borrow occurs here
-...
-LL | borrow_mut(&mut *v); //~ ERROR cannot borrow
- | ^^ mutable borrow occurs here
-LL | }
- | - immutable borrow ends here
-
-error[E0502]: cannot borrow `*v` as mutable because `v` is also borrowed as immutable
- --> $DIR/borrowck-lend-flow-loop.rs:100:21
- |
-LL | _x = &v;
- | - immutable borrow occurs here
-...
-LL | borrow_mut(&mut *v); //~ ERROR cannot borrow
- | ^^ mutable borrow occurs here
-LL | }
- | - immutable borrow ends here
-
-error[E0502]: cannot borrow `*v` as immutable because `v` is also borrowed as mutable
- --> $DIR/borrowck-lend-flow-loop.rs:109:17
- |
-LL | borrow(&*v); //~ ERROR cannot borrow
- | ^^ immutable borrow occurs here
-LL | if cond2 {
-LL | x = &mut v; //~ ERROR cannot borrow
- | - mutable borrow occurs here
-...
-LL | }
- | - mutable borrow ends here
-
-error[E0499]: cannot borrow `v` as mutable more than once at a time
- --> $DIR/borrowck-lend-flow-loop.rs:111:22
- |
-LL | x = &mut v; //~ ERROR cannot borrow
- | ^ mutable borrow starts here in previous iteration of loop
-...
-LL | }
- | - mutable borrow ends here
-
-error: aborting due to 8 previous errors
-
-Some errors occurred: E0499, E0502.
-For more information about an error, try `rustc --explain E0499`.
+error[E0502]: cannot borrow `s` as immutable because it is also borrowed as mutable
+ --> $DIR/borrowck-overloaded-call.rs:69:5
+ |
+LL | let sp = &mut s;
+ | ------ mutable borrow occurs here
+LL | s(3); //~ ERROR cannot borrow `s` as immutable because it is also borrowed as mutable
+ | ^ immutable borrow occurs here
+LL | use_mut(sp);
+ | -- mutable borrow later used here
+
error[E0596]: cannot borrow `s` as mutable, as it is not declared as mutable
--> $DIR/borrowck-overloaded-call.rs:77:5
|
|
= note: move occurs because `s` has type `SFnOnce`, which does not implement the `Copy` trait
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
-Some errors occurred: E0382, E0596.
+Some errors occurred: E0382, E0502, E0596.
For more information about an error, try `rustc --explain E0382`.
};
let sp = &mut s;
s(3); //~ ERROR cannot borrow `s` as immutable because it is also borrowed as mutable
+ use_mut(sp);
}
-
fn g() {
let s = SFnMut {
x: 1,
}
fn main() {}
+
+fn use_mut<T>(_: &mut T) { }
| - mutable borrow occurs here
LL | s(3); //~ ERROR cannot borrow `s` as immutable because it is also borrowed as mutable
| ^ immutable borrow occurs here
+LL | use_mut(sp);
LL | }
| - mutable borrow ends here
+error[E0505]: cannot move out of `s` because it is borrowed
+ --> $DIR/borrowck-overloaded-index-move-index.rs:60:22
+ |
+LL | let rs = &mut s;
+ | ------ borrow of `s` occurs here
+LL |
+LL | println!("{}", f[s]);
+ | ^ move out of `s` occurs here
+...
+LL | use_mut(rs);
+ | -- borrow later used here
+
+error[E0505]: cannot move out of `s` because it is borrowed
+ --> $DIR/borrowck-overloaded-index-move-index.rs:63:7
+ |
+LL | let rs = &mut s;
+ | ------ borrow of `s` occurs here
+...
+LL | f[s] = 10;
+ | ^ move out of `s` occurs here
+...
+LL | use_mut(rs);
+ | -- borrow later used here
+
error[E0382]: use of moved value: `s`
--> $DIR/borrowck-overloaded-index-move-index.rs:63:7
|
|
= note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
-error: aborting due to previous error
+error: aborting due to 3 previous errors
-For more information about this error, try `rustc --explain E0382`.
+Some errors occurred: E0382, E0505.
+For more information about an error, try `rustc --explain E0382`.
let _j = &i;
println!("{}", s[i]); // no error, i is copy
println!("{}", s[i]);
+
+ use_mut(rs);
}
+
+fn use_mut<T>(_: &mut T) { }
+error[E0499]: cannot borrow `foo.bar1` as mutable more than once at a time
+ --> $DIR/borrowck-reborrow-from-mut.rs:23:17
+ |
+LL | let _bar1 = &mut foo.bar1;
+ | ------------- first mutable borrow occurs here
+LL | let _bar2 = &mut foo.bar1; //~ ERROR cannot borrow
+ | ^^^^^^^^^^^^^ second mutable borrow occurs here
+LL | use_mut(_bar1);
+ | ----- first borrow later used here
+
+error[E0502]: cannot borrow `foo.bar1` as immutable because it is also borrowed as mutable
+ --> $DIR/borrowck-reborrow-from-mut.rs:28:17
+ |
+LL | let _bar1 = &mut foo.bar1;
+ | ------------- mutable borrow occurs here
+LL | let _bar2 = &foo.bar1; //~ ERROR cannot borrow
+ | ^^^^^^^^^ immutable borrow occurs here
+LL | use_mut(_bar1);
+ | ----- mutable borrow later used here
+
+error[E0502]: cannot borrow `foo.bar1` as mutable because it is also borrowed as immutable
+ --> $DIR/borrowck-reborrow-from-mut.rs:33:17
+ |
+LL | let _bar1 = &foo.bar1;
+ | --------- immutable borrow occurs here
+LL | let _bar2 = &mut foo.bar1; //~ ERROR cannot borrow
+ | ^^^^^^^^^^^^^ mutable borrow occurs here
+LL | use_imm(_bar1);
+ | ----- immutable borrow later used here
+
+error[E0499]: cannot borrow `foo.bar1` as mutable more than once at a time
+ --> $DIR/borrowck-reborrow-from-mut.rs:55:21
+ |
+LL | let _bar1 = &mut foo.bar1;
+ | ------------- first mutable borrow occurs here
+LL | match *foo {
+LL | Foo { bar1: ref mut _bar1, bar2: _ } => {}
+ | ^^^^^^^^^^^^^ second mutable borrow occurs here
+...
+LL | use_mut(_bar1);
+ | ----- first borrow later used here
+
+error[E0502]: cannot borrow `foo.bar1` as immutable because it is also borrowed as mutable
+ --> $DIR/borrowck-reborrow-from-mut.rs:62:17
+ |
+LL | let _bar1 = &mut foo.bar1.int1;
+ | ------------------ mutable borrow occurs here
+LL | let _foo1 = &foo.bar1; //~ ERROR cannot borrow
+ | ^^^^^^^^^ immutable borrow occurs here
+LL | let _foo2 = &*foo; //~ ERROR cannot borrow
+LL | use_mut(_bar1);
+ | ----- mutable borrow later used here
+
+error[E0502]: cannot borrow `*foo` as immutable because it is also borrowed as mutable
+ --> $DIR/borrowck-reborrow-from-mut.rs:63:17
+ |
+LL | let _bar1 = &mut foo.bar1.int1;
+ | ------------------ mutable borrow occurs here
+LL | let _foo1 = &foo.bar1; //~ ERROR cannot borrow
+LL | let _foo2 = &*foo; //~ ERROR cannot borrow
+ | ^^^^^ immutable borrow occurs here
+LL | use_mut(_bar1);
+ | ----- mutable borrow later used here
+
+error[E0499]: cannot borrow `foo.bar1` as mutable more than once at a time
+ --> $DIR/borrowck-reborrow-from-mut.rs:68:17
+ |
+LL | let _bar1 = &mut foo.bar1.int1;
+ | ------------------ first mutable borrow occurs here
+LL | let _foo1 = &mut foo.bar1; //~ ERROR cannot borrow
+ | ^^^^^^^^^^^^^ second mutable borrow occurs here
+LL | use_mut(_bar1);
+ | ----- first borrow later used here
+
+error[E0499]: cannot borrow `*foo` as mutable more than once at a time
+ --> $DIR/borrowck-reborrow-from-mut.rs:73:17
+ |
+LL | let _bar1 = &mut foo.bar1.int1;
+ | ------------------ first mutable borrow occurs here
+LL | let _foo2 = &mut *foo; //~ ERROR cannot borrow
+ | ^^^^^^^^^ second mutable borrow occurs here
+LL | use_mut(_bar1);
+ | ----- first borrow later used here
+
+error[E0502]: cannot borrow `foo.bar1` as mutable because it is also borrowed as immutable
+ --> $DIR/borrowck-reborrow-from-mut.rs:78:17
+ |
+LL | let _bar1 = &foo.bar1.int1;
+ | -------------- immutable borrow occurs here
+LL | let _foo1 = &mut foo.bar1; //~ ERROR cannot borrow
+ | ^^^^^^^^^^^^^ mutable borrow occurs here
+LL | use_imm(_bar1);
+ | ----- immutable borrow later used here
+
+error[E0502]: cannot borrow `*foo` as mutable because it is also borrowed as immutable
+ --> $DIR/borrowck-reborrow-from-mut.rs:83:17
+ |
+LL | let _bar1 = &foo.bar1.int1;
+ | -------------- immutable borrow occurs here
+LL | let _foo2 = &mut *foo; //~ ERROR cannot borrow
+ | ^^^^^^^^^ mutable borrow occurs here
+LL | use_imm(_bar1);
+ | ----- immutable borrow later used here
+
error[E0596]: cannot borrow `foo.bar1` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-reborrow-from-mut.rs:98:17
|
LL | let _bar1 = &mut foo.bar1; //~ ERROR cannot borrow
| ^^^^^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be borrowed as mutable
-error: aborting due to previous error
+error: aborting due to 11 previous errors
-For more information about this error, try `rustc --explain E0596`.
+Some errors occurred: E0499, E0502, E0596.
+For more information about an error, try `rustc --explain E0499`.
fn borrow_same_field_twice_mut_mut(foo: &mut Foo) {
let _bar1 = &mut foo.bar1;
let _bar2 = &mut foo.bar1; //~ ERROR cannot borrow
+ use_mut(_bar1);
}
-
fn borrow_same_field_twice_mut_imm(foo: &mut Foo) {
let _bar1 = &mut foo.bar1;
let _bar2 = &foo.bar1; //~ ERROR cannot borrow
+ use_mut(_bar1);
}
-
fn borrow_same_field_twice_imm_mut(foo: &mut Foo) {
let _bar1 = &foo.bar1;
let _bar2 = &mut foo.bar1; //~ ERROR cannot borrow
+ use_imm(_bar1);
}
-
fn borrow_same_field_twice_imm_imm(foo: &mut Foo) {
let _bar1 = &foo.bar1;
let _bar2 = &foo.bar1;
+ use_imm(_bar1);
}
-
fn borrow_both_mut(foo: &mut Foo) {
let _bar1 = &mut foo.bar1;
let _bar2 = &mut foo.bar2;
+ use_mut(_bar1);
}
-
fn borrow_both_mut_pattern(foo: &mut Foo) {
match *foo {
- Foo { bar1: ref mut _bar1, bar2: ref mut _bar2 } => {}
+ Foo { bar1: ref mut _bar1, bar2: ref mut _bar2 } =>
+ { use_mut(_bar1); use_mut(_bar2); }
}
}
-
fn borrow_var_and_pattern(foo: &mut Foo) {
let _bar1 = &mut foo.bar1;
match *foo {
Foo { bar1: ref mut _bar1, bar2: _ } => {}
//~^ ERROR cannot borrow
}
+ use_mut(_bar1);
}
-
fn borrow_mut_and_base_imm(foo: &mut Foo) {
let _bar1 = &mut foo.bar1.int1;
let _foo1 = &foo.bar1; //~ ERROR cannot borrow
let _foo2 = &*foo; //~ ERROR cannot borrow
+ use_mut(_bar1);
}
-
fn borrow_mut_and_base_mut(foo: &mut Foo) {
let _bar1 = &mut foo.bar1.int1;
let _foo1 = &mut foo.bar1; //~ ERROR cannot borrow
+ use_mut(_bar1);
}
-
fn borrow_mut_and_base_mut2(foo: &mut Foo) {
let _bar1 = &mut foo.bar1.int1;
let _foo2 = &mut *foo; //~ ERROR cannot borrow
+ use_mut(_bar1);
}
-
fn borrow_imm_and_base_mut(foo: &mut Foo) {
let _bar1 = &foo.bar1.int1;
let _foo1 = &mut foo.bar1; //~ ERROR cannot borrow
+ use_imm(_bar1);
}
-
fn borrow_imm_and_base_mut2(foo: &mut Foo) {
let _bar1 = &foo.bar1.int1;
let _foo2 = &mut *foo; //~ ERROR cannot borrow
+ use_imm(_bar1);
}
-
fn borrow_imm_and_base_imm(foo: &mut Foo) {
let _bar1 = &foo.bar1.int1;
let _foo1 = &foo.bar1;
let _foo2 = &*foo;
+ use_imm(_bar1);
}
-
fn borrow_mut_and_imm(foo: &mut Foo) {
let _bar1 = &mut foo.bar1;
let _foo1 = &foo.bar2;
+ use_mut(_bar1);
}
-
fn borrow_mut_from_imm(foo: &Foo) {
let _bar1 = &mut foo.bar1; //~ ERROR cannot borrow
}
fn borrow_long_path_both_mut(foo: &mut Foo) {
let _bar1 = &mut foo.bar1.int1;
let _foo1 = &mut foo.bar2.int2;
+ use_mut(_bar1);
}
-
fn main() {}
+
+fn use_mut<T>(_: &mut T) { }
+fn use_imm<T>(_: &T) { }
| -------- first mutable borrow occurs here
LL | let _bar2 = &mut foo.bar1; //~ ERROR cannot borrow
| ^^^^^^^^ second mutable borrow occurs here
+LL | use_mut(_bar1);
LL | }
| - first borrow ends here
| -------- mutable borrow occurs here
LL | let _bar2 = &foo.bar1; //~ ERROR cannot borrow
| ^^^^^^^^ immutable borrow occurs here
+LL | use_mut(_bar1);
LL | }
| - mutable borrow ends here
| -------- immutable borrow occurs here
LL | let _bar2 = &mut foo.bar1; //~ ERROR cannot borrow
| ^^^^^^^^ mutable borrow occurs here
+LL | use_imm(_bar1);
LL | }
| - immutable borrow ends here
| ------------- mutable borrow occurs here
LL | let _foo1 = &foo.bar1; //~ ERROR cannot borrow
| ^^^^^^^^ immutable borrow occurs here
-LL | let _foo2 = &*foo; //~ ERROR cannot borrow
+...
LL | }
| - mutable borrow ends here
LL | let _foo1 = &foo.bar1; //~ ERROR cannot borrow
LL | let _foo2 = &*foo; //~ ERROR cannot borrow
| ^^^^ immutable borrow occurs here
+LL | use_mut(_bar1);
LL | }
| - mutable borrow ends here
| ------------- first mutable borrow occurs here
LL | let _foo1 = &mut foo.bar1; //~ ERROR cannot borrow
| ^^^^^^^^ second mutable borrow occurs here
+LL | use_mut(_bar1);
LL | }
| - first borrow ends here
| ------------- first mutable borrow occurs here
LL | let _foo2 = &mut *foo; //~ ERROR cannot borrow
| ^^^^ second mutable borrow occurs here
+LL | use_mut(_bar1);
LL | }
| - first borrow ends here
| ------------- immutable borrow occurs here
LL | let _foo1 = &mut foo.bar1; //~ ERROR cannot borrow
| ^^^^^^^^ mutable borrow occurs here
+LL | use_imm(_bar1);
LL | }
| - immutable borrow ends here
| ------------- immutable borrow occurs here
LL | let _foo2 = &mut *foo; //~ ERROR cannot borrow
| ^^^^ mutable borrow occurs here
+LL | use_imm(_bar1);
LL | }
| - immutable borrow ends here
+error[E0502]: cannot borrow `f` as immutable because it is also borrowed as mutable
+ --> $DIR/borrowck-unboxed-closures.rs:13:5
+ |
+LL | let g = &mut f;
+ | ------ mutable borrow occurs here
+LL | f(1, 2); //~ ERROR cannot borrow `f` as immutable
+ | ^ immutable borrow occurs here
+LL | use_mut(g);
+ | - mutable borrow later used here
+
error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable
--> $DIR/borrowck-unboxed-closures.rs:17:5
|
|
= note: move occurs because `f` has type `F`, which does not implement the `Copy` trait
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
-Some errors occurred: E0382, E0596.
+Some errors occurred: E0382, E0502, E0596.
For more information about an error, try `rustc --explain E0382`.
fn a<F:Fn(isize, isize) -> isize>(mut f: F) {
let g = &mut f;
f(1, 2); //~ ERROR cannot borrow `f` as immutable
+ use_mut(g);
}
-
fn b<F:FnMut(isize, isize) -> isize>(f: F) {
f(1, 2); //~ ERROR cannot borrow immutable argument
}
}
fn main() {}
+
+fn use_mut<T>(_: &mut T) { }
| - mutable borrow occurs here
LL | f(1, 2); //~ ERROR cannot borrow `f` as immutable
| ^ immutable borrow occurs here
+LL | use_mut(g);
LL | }
| - mutable borrow ends here
+++ /dev/null
-error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
- --> $DIR/overlapping_spans.rs:20:11
- |
-LL | match (S {f:"foo".to_string()}) {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of here
-LL | S {f:_s} => {} //~ ERROR cannot move out
- | -- data moved here
- |
-note: move occurs because `_s` has type `std::string::String`, which does not implement the `Copy` trait
- --> $DIR/overlapping_spans.rs:21:14
- |
-LL | S {f:_s} => {} //~ ERROR cannot move out
- | ^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0509`.
+++ /dev/null
-// Copyright 2016 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.
-
-#[derive(Debug)]
-struct Foo { }
-
-struct S {f:String}
-impl Drop for S {
- fn drop(&mut self) { println!("{}", self.f); }
-}
-
-fn main() {
- match (S {f:"foo".to_string()}) {
- S {f:_s} => {} //~ ERROR cannot move out
- }
-}
+++ /dev/null
-error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
- --> $DIR/overlapping_spans.rs:21:9
- |
-LL | S {f:_s} => {} //~ ERROR cannot move out
- | ^^^^^--^
- | | |
- | | hint: to prevent move, use `ref _s` or `ref mut _s`
- | cannot move out of here
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0509`.
--- /dev/null
+// https://github.com/rust-lang/rust/issues/55223
+
+#![feature(const_let)]
+
+union Foo<'a> {
+ y: &'a (),
+ long_live_the_unit: &'static (),
+}
+
+const FOO: &() = { //~ ERROR any use of this value will cause an error
+ let y = ();
+ unsafe { Foo { y: &y }.long_live_the_unit }
+};
+
+fn main() {}
--- /dev/null
+error: any use of this value will cause an error
+ --> $DIR/dangling-alloc-id-ice.rs:10:1
+ |
+LL | / const FOO: &() = { //~ ERROR any use of this value will cause an error
+LL | | let y = ();
+LL | | unsafe { Foo { y: &y }.long_live_the_unit }
+LL | | };
+ | |__^ type validation failed: encountered dangling pointer in final constant
+ |
+ = note: #[deny(const_err)] on by default
+
+error: aborting due to previous error
+
--- /dev/null
+#![feature(const_let)]
+
+const FOO: *const u32 = { //~ ERROR any use of this value will cause an error
+ let x = 42;
+ &x
+};
+
+fn main() {
+ let x = FOO;
+}
--- /dev/null
+error: any use of this value will cause an error
+ --> $DIR/dangling_raw_ptr.rs:3:1
+ |
+LL | / const FOO: *const u32 = { //~ ERROR any use of this value will cause an error
+LL | | let x = 42;
+LL | | &x
+LL | | };
+ | |__^ type validation failed: encountered dangling pointer in final constant
+ |
+ = note: #[deny(const_err)] on by default
+
+error: aborting due to previous error
+
--- /dev/null
+error[E0597]: `c` does not live long enough
+ --> $DIR/dropck-eyepatch-extern-crate.rs:41:20
+ |
+LL | dt = Dt("dt", &c);
+ | ^ borrowed value does not live long enough
+...
+LL | }
+ | - `c` dropped here while still borrowed
+ |
+ = note: values in a scope are dropped in the opposite order they are created
+
+error[E0597]: `c` does not live long enough
+ --> $DIR/dropck-eyepatch-extern-crate.rs:43:20
+ |
+LL | dr = Dr("dr", &c);
+ | ^ borrowed value does not live long enough
+...
+LL | }
+ | - `c` dropped here while still borrowed
+ |
+ = note: values in a scope are dropped in the opposite order they are created
+
+error[E0597]: `c_shortest` does not live long enough
+ --> $DIR/dropck-eyepatch-extern-crate.rs:47:20
+ |
+LL | dt = Dt("dt", &c_shortest);
+ | ^^^^^^^^^^ borrowed value does not live long enough
+...
+LL | }
+ | - `c_shortest` dropped here while still borrowed
+ |
+ = note: values in a scope are dropped in the opposite order they are created
+
+error[E0597]: `c_shortest` does not live long enough
+ --> $DIR/dropck-eyepatch-extern-crate.rs:50:20
+ |
+LL | dr = Dr("dr", &c_shortest);
+ | ^^^^^^^^^^ borrowed value does not live long enough
+...
+LL | }
+ | - `c_shortest` dropped here while still borrowed
+ |
+ = note: values in a scope are dropped in the opposite order they are created
+
+error[E0597]: `c_shortest` does not live long enough
+ --> $DIR/dropck-eyepatch-extern-crate.rs:57:29
+ |
+LL | pt = Pt("pt", &c_long, &c_shortest);
+ | ^^^^^^^^^^ borrowed value does not live long enough
+...
+LL | }
+ | - `c_shortest` dropped here while still borrowed
+ |
+ = note: values in a scope are dropped in the opposite order they are created
+
+error[E0597]: `c_shortest` does not live long enough
+ --> $DIR/dropck-eyepatch-extern-crate.rs:59:29
+ |
+LL | pr = Pr("pr", &c_long, &c_shortest);
+ | ^^^^^^^^^^ borrowed value does not live long enough
+...
+LL | }
+ | - `c_shortest` dropped here while still borrowed
+ |
+ = note: values in a scope are dropped in the opposite order they are created
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
-// Copyright 2016 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.
+// The behavior of AST-borrowck and NLL explcitly differ here due to
+// NLL's increased precision; so we use revisions and do not worry
+// about the --compare-mode=nll on this test.
+
+// revisions: ast nll
+//[ast]compile-flags: -Z borrowck=ast
+//[nll]compile-flags: -Z borrowck=migrate -Z two-phase-borrows
+
+// ignore-compare-mode-nll
// aux-build:dropck_eyepatch_extern_crate.rs
// Error: destructor order imprecisely modelled
dt = Dt("dt", &c);
- //~^ ERROR `c` does not live long enough
+ //[ast]~^ ERROR `c` does not live long enough
dr = Dr("dr", &c);
- //~^ ERROR `c` does not live long enough
+ //[ast]~^ ERROR `c` does not live long enough
// Error: `c_shortest` dies too soon for the references in dtors to be valid.
dt = Dt("dt", &c_shortest);
- //~^ ERROR `c_shortest` does not live long enough
+ //[ast]~^ ERROR `c_shortest` does not live long enough
+ //[nll]~^^ ERROR `c_shortest` does not live long enough
dr = Dr("dr", &c_shortest);
- //~^ ERROR `c_shortest` does not live long enough
-
+ //[ast]~^ ERROR `c_shortest` does not live long enough
// No error: Drop impl asserts .1 (A and &'a _) are not accessed
pt = Pt("pt", &c_shortest, &c_long);
pr = Pr("pr", &c_shortest, &c_long);
// Error: Drop impl's assertion does not apply to `B` nor `&'b _`
pt = Pt("pt", &c_long, &c_shortest);
- //~^ ERROR `c_shortest` does not live long enough
+ //[ast]~^ ERROR `c_shortest` does not live long enough
pr = Pr("pr", &c_long, &c_shortest);
- //~^ ERROR `c_shortest` does not live long enough
+ //[ast]~^ ERROR `c_shortest` does not live long enough
// No error: St and Sr have no destructor.
st = St("st", &c_shortest);
sr = Sr("sr", &c_shortest);
println!("{:?}", (dt.0, dr.0, pt.0, pr.0, st.0, sr.0));
+ use_imm(sr.1); use_imm(st.1); use_imm(pr.1); use_imm(pt.1); use_imm(dr.1); use_imm(dt.1);
}
+
+fn use_imm<T>(_: &T) { }
+++ /dev/null
-error[E0597]: `c` does not live long enough
- --> $DIR/dropck-eyepatch-extern-crate.rs:41:20
- |
-LL | dt = Dt("dt", &c);
- | ^ borrowed value does not live long enough
-...
-LL | }
- | - `c` dropped here while still borrowed
- |
- = note: values in a scope are dropped in the opposite order they are created
-
-error[E0597]: `c` does not live long enough
- --> $DIR/dropck-eyepatch-extern-crate.rs:43:20
- |
-LL | dr = Dr("dr", &c);
- | ^ borrowed value does not live long enough
-...
-LL | }
- | - `c` dropped here while still borrowed
- |
- = note: values in a scope are dropped in the opposite order they are created
-
-error[E0597]: `c_shortest` does not live long enough
- --> $DIR/dropck-eyepatch-extern-crate.rs:47:20
- |
-LL | dt = Dt("dt", &c_shortest);
- | ^^^^^^^^^^ borrowed value does not live long enough
-...
-LL | }
- | - `c_shortest` dropped here while still borrowed
- |
- = note: values in a scope are dropped in the opposite order they are created
-
-error[E0597]: `c_shortest` does not live long enough
- --> $DIR/dropck-eyepatch-extern-crate.rs:49:20
- |
-LL | dr = Dr("dr", &c_shortest);
- | ^^^^^^^^^^ borrowed value does not live long enough
-...
-LL | }
- | - `c_shortest` dropped here while still borrowed
- |
- = note: values in a scope are dropped in the opposite order they are created
-
-error[E0597]: `c_shortest` does not live long enough
- --> $DIR/dropck-eyepatch-extern-crate.rs:57:29
- |
-LL | pt = Pt("pt", &c_long, &c_shortest);
- | ^^^^^^^^^^ borrowed value does not live long enough
-...
-LL | }
- | - `c_shortest` dropped here while still borrowed
- |
- = note: values in a scope are dropped in the opposite order they are created
-
-error[E0597]: `c_shortest` does not live long enough
- --> $DIR/dropck-eyepatch-extern-crate.rs:59:29
- |
-LL | pr = Pr("pr", &c_long, &c_shortest);
- | ^^^^^^^^^^ borrowed value does not live long enough
-...
-LL | }
- | - `c_shortest` dropped here while still borrowed
- |
- = note: values in a scope are dropped in the opposite order they are created
-
-error: aborting due to 6 previous errors
-
-For more information about this error, try `rustc --explain E0597`.
--- /dev/null
+error[E0597]: `c` does not live long enough
+ --> $DIR/dropck-eyepatch-reorder.rs:58:20
+ |
+LL | dt = Dt("dt", &c);
+ | ^ borrowed value does not live long enough
+...
+LL | }
+ | - `c` dropped here while still borrowed
+ |
+ = note: values in a scope are dropped in the opposite order they are created
+
+error[E0597]: `c` does not live long enough
+ --> $DIR/dropck-eyepatch-reorder.rs:60:20
+ |
+LL | dr = Dr("dr", &c);
+ | ^ borrowed value does not live long enough
+...
+LL | }
+ | - `c` dropped here while still borrowed
+ |
+ = note: values in a scope are dropped in the opposite order they are created
+
+error[E0597]: `c_shortest` does not live long enough
+ --> $DIR/dropck-eyepatch-reorder.rs:64:20
+ |
+LL | dt = Dt("dt", &c_shortest);
+ | ^^^^^^^^^^ borrowed value does not live long enough
+...
+LL | }
+ | - `c_shortest` dropped here while still borrowed
+ |
+ = note: values in a scope are dropped in the opposite order they are created
+
+error[E0597]: `c_shortest` does not live long enough
+ --> $DIR/dropck-eyepatch-reorder.rs:67:20
+ |
+LL | dr = Dr("dr", &c_shortest);
+ | ^^^^^^^^^^ borrowed value does not live long enough
+...
+LL | }
+ | - `c_shortest` dropped here while still borrowed
+ |
+ = note: values in a scope are dropped in the opposite order they are created
+
+error[E0597]: `c_shortest` does not live long enough
+ --> $DIR/dropck-eyepatch-reorder.rs:74:29
+ |
+LL | pt = Pt("pt", &c_long, &c_shortest);
+ | ^^^^^^^^^^ borrowed value does not live long enough
+...
+LL | }
+ | - `c_shortest` dropped here while still borrowed
+ |
+ = note: values in a scope are dropped in the opposite order they are created
+
+error[E0597]: `c_shortest` does not live long enough
+ --> $DIR/dropck-eyepatch-reorder.rs:76:29
+ |
+LL | pr = Pr("pr", &c_long, &c_shortest);
+ | ^^^^^^^^^^ borrowed value does not live long enough
+...
+LL | }
+ | - `c_shortest` dropped here while still borrowed
+ |
+ = note: values in a scope are dropped in the opposite order they are created
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
-// Copyright 2016 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.
+// The behavior of AST-borrowck and NLL explcitly differ here due to
+// NLL's increased precision; so we use revisions and do not worry
+// about the --compare-mode=nll on this test.
+
+// revisions: ast nll
+//[ast]compile-flags: -Z borrowck=ast
+//[nll]compile-flags: -Z borrowck=migrate -Z two-phase-borrows
+
+// ignore-compare-mode-nll
#![feature(dropck_eyepatch, rustc_attrs)]
// Error: destructor order imprecisely modelled
dt = Dt("dt", &c);
- //~^ ERROR `c` does not live long enough
+ //[ast]~^ ERROR `c` does not live long enough
dr = Dr("dr", &c);
- //~^ ERROR `c` does not live long enough
+ //[ast]~^ ERROR `c` does not live long enough
// Error: `c_shortest` dies too soon for the references in dtors to be valid.
dt = Dt("dt", &c_shortest);
- //~^ ERROR `c_shortest` does not live long enough
+ //[ast]~^ ERROR `c_shortest` does not live long enough
+ //[nll]~^^ ERROR `c_shortest` does not live long enough
dr = Dr("dr", &c_shortest);
- //~^ ERROR `c_shortest` does not live long enough
-
+ //[ast]~^ ERROR `c_shortest` does not live long enough
// No error: Drop impl asserts .1 (A and &'a _) are not accessed
pt = Pt("pt", &c_shortest, &c_long);
pr = Pr("pr", &c_shortest, &c_long);
// Error: Drop impl's assertion does not apply to `B` nor `&'b _`
pt = Pt("pt", &c_long, &c_shortest);
- //~^ ERROR `c_shortest` does not live long enough
+ //[ast]~^ ERROR `c_shortest` does not live long enough
pr = Pr("pr", &c_long, &c_shortest);
- //~^ ERROR `c_shortest` does not live long enough
+ //[ast]~^ ERROR `c_shortest` does not live long enough
// No error: St and Sr have no destructor.
st = St("st", &c_shortest);
sr = Sr("sr", &c_shortest);
println!("{:?}", (dt.0, dr.0, pt.0, pr.0, st.0, sr.0));
+ use_imm(sr.1); use_imm(st.1); use_imm(pr.1); use_imm(pt.1); use_imm(dr.1); use_imm(dt.1);
}
+
+fn use_imm<T>(_: &T) { }
+++ /dev/null
-error[E0597]: `c` does not live long enough
- --> $DIR/dropck-eyepatch-reorder.rs:58:20
- |
-LL | dt = Dt("dt", &c);
- | ^ borrowed value does not live long enough
-...
-LL | }
- | - `c` dropped here while still borrowed
- |
- = note: values in a scope are dropped in the opposite order they are created
-
-error[E0597]: `c` does not live long enough
- --> $DIR/dropck-eyepatch-reorder.rs:60:20
- |
-LL | dr = Dr("dr", &c);
- | ^ borrowed value does not live long enough
-...
-LL | }
- | - `c` dropped here while still borrowed
- |
- = note: values in a scope are dropped in the opposite order they are created
-
-error[E0597]: `c_shortest` does not live long enough
- --> $DIR/dropck-eyepatch-reorder.rs:64:20
- |
-LL | dt = Dt("dt", &c_shortest);
- | ^^^^^^^^^^ borrowed value does not live long enough
-...
-LL | }
- | - `c_shortest` dropped here while still borrowed
- |
- = note: values in a scope are dropped in the opposite order they are created
-
-error[E0597]: `c_shortest` does not live long enough
- --> $DIR/dropck-eyepatch-reorder.rs:66:20
- |
-LL | dr = Dr("dr", &c_shortest);
- | ^^^^^^^^^^ borrowed value does not live long enough
-...
-LL | }
- | - `c_shortest` dropped here while still borrowed
- |
- = note: values in a scope are dropped in the opposite order they are created
-
-error[E0597]: `c_shortest` does not live long enough
- --> $DIR/dropck-eyepatch-reorder.rs:74:29
- |
-LL | pt = Pt("pt", &c_long, &c_shortest);
- | ^^^^^^^^^^ borrowed value does not live long enough
-...
-LL | }
- | - `c_shortest` dropped here while still borrowed
- |
- = note: values in a scope are dropped in the opposite order they are created
-
-error[E0597]: `c_shortest` does not live long enough
- --> $DIR/dropck-eyepatch-reorder.rs:76:29
- |
-LL | pr = Pr("pr", &c_long, &c_shortest);
- | ^^^^^^^^^^ borrowed value does not live long enough
-...
-LL | }
- | - `c_shortest` dropped here while still borrowed
- |
- = note: values in a scope are dropped in the opposite order they are created
-
-error: aborting due to 6 previous errors
-
-For more information about this error, try `rustc --explain E0597`.
--- /dev/null
+error[E0597]: `c` does not live long enough
+ --> $DIR/dropck-eyepatch.rs:81:20
+ |
+LL | dt = Dt("dt", &c);
+ | ^ borrowed value does not live long enough
+...
+LL | }
+ | - `c` dropped here while still borrowed
+ |
+ = note: values in a scope are dropped in the opposite order they are created
+
+error[E0597]: `c` does not live long enough
+ --> $DIR/dropck-eyepatch.rs:83:20
+ |
+LL | dr = Dr("dr", &c);
+ | ^ borrowed value does not live long enough
+...
+LL | }
+ | - `c` dropped here while still borrowed
+ |
+ = note: values in a scope are dropped in the opposite order they are created
+
+error[E0597]: `c_shortest` does not live long enough
+ --> $DIR/dropck-eyepatch.rs:87:20
+ |
+LL | dt = Dt("dt", &c_shortest);
+ | ^^^^^^^^^^ borrowed value does not live long enough
+...
+LL | }
+ | - `c_shortest` dropped here while still borrowed
+ |
+ = note: values in a scope are dropped in the opposite order they are created
+
+error[E0597]: `c_shortest` does not live long enough
+ --> $DIR/dropck-eyepatch.rs:90:20
+ |
+LL | dr = Dr("dr", &c_shortest);
+ | ^^^^^^^^^^ borrowed value does not live long enough
+...
+LL | }
+ | - `c_shortest` dropped here while still borrowed
+ |
+ = note: values in a scope are dropped in the opposite order they are created
+
+error[E0597]: `c_shortest` does not live long enough
+ --> $DIR/dropck-eyepatch.rs:98:29
+ |
+LL | pt = Pt("pt", &c_long, &c_shortest);
+ | ^^^^^^^^^^ borrowed value does not live long enough
+...
+LL | }
+ | - `c_shortest` dropped here while still borrowed
+ |
+ = note: values in a scope are dropped in the opposite order they are created
+
+error[E0597]: `c_shortest` does not live long enough
+ --> $DIR/dropck-eyepatch.rs:100:29
+ |
+LL | pr = Pr("pr", &c_long, &c_shortest);
+ | ^^^^^^^^^^ borrowed value does not live long enough
+...
+LL | }
+ | - `c_shortest` dropped here while still borrowed
+ |
+ = note: values in a scope are dropped in the opposite order they are created
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
-// Copyright 2016 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.
+// The behavior of AST-borrowck and NLL explcitly differ here due to
+// NLL's increased precision; so we use revisions and do not worry
+// about the --compare-mode=nll on this test.
+
+// revisions: ast nll
+//[ast]compile-flags: -Z borrowck=ast
+//[nll]compile-flags: -Z borrowck=migrate -Z two-phase-borrows
+
+// ignore-compare-mode-nll
#![feature(dropck_eyepatch, rustc_attrs)]
// Error: destructor order imprecisely modelled
dt = Dt("dt", &c);
- //~^ ERROR `c` does not live long enough
+ //[ast]~^ ERROR `c` does not live long enough
dr = Dr("dr", &c);
- //~^ ERROR `c` does not live long enough
+ //[ast]~^ ERROR `c` does not live long enough
// Error: `c_shortest` dies too soon for the references in dtors to be valid.
dt = Dt("dt", &c_shortest);
- //~^ ERROR `c_shortest` does not live long enough
+ //[ast]~^ ERROR `c_shortest` does not live long enough
+ //[nll]~^^ ERROR `c_shortest` does not live long enough
dr = Dr("dr", &c_shortest);
- //~^ ERROR `c_shortest` does not live long enough
-
+ //[ast]~^ ERROR `c_shortest` does not live long enough
// No error: Drop impl asserts .1 (A and &'a _) are not accessed
pt = Pt("pt", &c_shortest, &c_long);
// Error: Drop impl's assertion does not apply to `B` nor `&'b _`
pt = Pt("pt", &c_long, &c_shortest);
- //~^ ERROR `c_shortest` does not live long enough
+ //[ast]~^ ERROR `c_shortest` does not live long enough
pr = Pr("pr", &c_long, &c_shortest);
- //~^ ERROR `c_shortest` does not live long enough
+ //[ast]~^ ERROR `c_shortest` does not live long enough
// No error: St and Sr have no destructor.
st = St("st", &c_shortest);
sr = Sr("sr", &c_shortest);
println!("{:?}", (dt.0, dr.0, pt.0, pr.0, st.0, sr.0));
+ use_imm(sr.1); use_imm(st.1); use_imm(pr.1); use_imm(pt.1); use_imm(dr.1); use_imm(dt.1);
}
+
+fn use_imm<T>(_: &T) { }
+++ /dev/null
-error[E0597]: `c` does not live long enough
- --> $DIR/dropck-eyepatch.rs:81:20
- |
-LL | dt = Dt("dt", &c);
- | ^ borrowed value does not live long enough
-...
-LL | }
- | - `c` dropped here while still borrowed
- |
- = note: values in a scope are dropped in the opposite order they are created
-
-error[E0597]: `c` does not live long enough
- --> $DIR/dropck-eyepatch.rs:83:20
- |
-LL | dr = Dr("dr", &c);
- | ^ borrowed value does not live long enough
-...
-LL | }
- | - `c` dropped here while still borrowed
- |
- = note: values in a scope are dropped in the opposite order they are created
-
-error[E0597]: `c_shortest` does not live long enough
- --> $DIR/dropck-eyepatch.rs:87:20
- |
-LL | dt = Dt("dt", &c_shortest);
- | ^^^^^^^^^^ borrowed value does not live long enough
-...
-LL | }
- | - `c_shortest` dropped here while still borrowed
- |
- = note: values in a scope are dropped in the opposite order they are created
-
-error[E0597]: `c_shortest` does not live long enough
- --> $DIR/dropck-eyepatch.rs:89:20
- |
-LL | dr = Dr("dr", &c_shortest);
- | ^^^^^^^^^^ borrowed value does not live long enough
-...
-LL | }
- | - `c_shortest` dropped here while still borrowed
- |
- = note: values in a scope are dropped in the opposite order they are created
-
-error[E0597]: `c_shortest` does not live long enough
- --> $DIR/dropck-eyepatch.rs:98:29
- |
-LL | pt = Pt("pt", &c_long, &c_shortest);
- | ^^^^^^^^^^ borrowed value does not live long enough
-...
-LL | }
- | - `c_shortest` dropped here while still borrowed
- |
- = note: values in a scope are dropped in the opposite order they are created
-
-error[E0597]: `c_shortest` does not live long enough
- --> $DIR/dropck-eyepatch.rs:100:29
- |
-LL | pr = Pr("pr", &c_long, &c_shortest);
- | ^^^^^^^^^^ borrowed value does not live long enough
-...
-LL | }
- | - `c_shortest` dropped here while still borrowed
- |
- = note: values in a scope are dropped in the opposite order they are created
-
-error: aborting due to 6 previous errors
-
-For more information about this error, try `rustc --explain E0597`.
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
-error: compilation successful
- --> $DIR/feature-gate-nll.rs:13:1
- |
-LL | / fn main() { #![rustc_error] // rust-lang/rust#49855
-LL | | let mut x = 33;
-LL | |
-LL | | let p = &x;
-LL | | x = 22; //~ ERROR cannot assign to `x` because it is borrowed [E0506]
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
-// Copyright 2015 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(rustc_attrs)]
+// This is a test checking that if you do not opt into NLL then you
+// should not get the effects of NLL applied to the test.
+
+// Don't use 2018 edition, since that turns on NLL (migration mode).
+// edition:2015
+
+// Don't use compare-mode=nll, since that turns on NLL.
+// ignore-compare-mode-nll
+
+
#![allow(dead_code)]
-fn main() { #![rustc_error] // rust-lang/rust#49855
+fn main() {
let mut x = 33;
let p = &x;
+++ /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`.
#[repr(simd)] //~ error: SIMD types are experimental
struct Foo(u64, u64);
+#[repr(C)]
+#[repr(simd)] //~ error: SIMD types are experimental
+struct Bar(u64, u64);
+
fn main() {}
|
= help: add #![feature(repr_simd)] to the crate attributes to enable
-error: aborting due to previous error
+error[E0658]: SIMD types are experimental and possibly buggy (see issue #27731)
+ --> $DIR/feature-gate-repr-simd.rs:15:1
+ |
+LL | #[repr(simd)] //~ error: SIMD types are experimental
+ | ^^^^^^^^^^^^^
+ |
+ = help: add #![feature(repr_simd)] to the crate attributes to enable
+
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.
#[repr(packed(1))] //~ error: the `#[repr(packed(n))]` attribute is experimental
struct Foo(u64);
+#[repr(C)]
+#[repr(packed(1))] //~ error: the `#[repr(packed(n))]` attribute is experimental
+struct Bar(u64);
+
fn main() {}
|
= help: add #![feature(repr_packed)] to the crate attributes to enable
-error: aborting due to previous error
+error[E0658]: the `#[repr(packed(n))]` attribute is experimental (see issue #33158)
+ --> $DIR/feature-gate-repr_packed.rs:15:1
+ |
+LL | #[repr(packed(1))] //~ error: the `#[repr(packed(n))]` attribute is experimental
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = help: add #![feature(repr_packed)] to the crate attributes to enable
+
+error: aborting due to 2 previous errors
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`.
+++ /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.
-
-use std::rc::Rc;
-use std::sync::Arc;
-
-struct Foo(Arc<Bar>);
-
-enum Bar {
- A(Rc<Foo>),
- B(Option<Foo>),
-}
-
-fn f<T: Send>(_: T) {}
-
-fn main() {
- f(Foo(Arc::new(Bar::B(None))));
- //~^ ERROR E0277
- //~| ERROR E0277
-}
+++ /dev/null
-error[E0277]: `std::rc::Rc<Foo>` cannot be sent between threads safely
- --> $DIR/issue-40827.rs:24:5
- |
-LL | f(Foo(Arc::new(Bar::B(None))));
- | ^ `std::rc::Rc<Foo>` cannot be sent between threads safely
- |
- = help: within `Bar`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<Foo>`
- = note: required because it appears within the type `Bar`
- = note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<Bar>`
- = note: required because it appears within the type `Foo`
-note: required by `f`
- --> $DIR/issue-40827.rs:21:1
- |
-LL | fn f<T: Send>(_: T) {}
- | ^^^^^^^^^^^^^^^^^^^
-
-error[E0277]: `std::rc::Rc<Foo>` cannot be shared between threads safely
- --> $DIR/issue-40827.rs:24:5
- |
-LL | f(Foo(Arc::new(Bar::B(None))));
- | ^ `std::rc::Rc<Foo>` cannot be shared between threads safely
- |
- = help: within `Bar`, the trait `std::marker::Sync` is not implemented for `std::rc::Rc<Foo>`
- = note: required because it appears within the type `Bar`
- = note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<Bar>`
- = note: required because it appears within the type `Foo`
-note: required by `f`
- --> $DIR/issue-40827.rs:21:1
- |
-LL | fn f<T: Send>(_: T) {}
- | ^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
+++ /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-pass
-fn iter<'a>(data: &'a [usize]) -> impl Iterator<Item = usize> + 'a {
- data.iter()
- .map(
- |x| x // fn(&'a usize) -> &'(ReScope) usize
- )
- .map(
- |x| *x // fn(&'(ReScope) usize) -> usize
- )
-}
-
-fn main() {
-}
+++ /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.
-
-fn main(){
- if i in 1..10 {
- break;
- }
-}
+++ /dev/null
-error: expected `{`, found keyword `in`
- --> $DIR/issue-51602.rs:12:10
- |
-LL | if i in 1..10 {
- | -- ^^ expected `{`
- | |
- | this `if` statement has a condition, but no block
-
-error: aborting due to previous error
-
--- /dev/null
+// compile-pass
+
+#![crate_type = "lib"]
+#![feature(linkage)]
+
+// MergeFunctions will merge these via an anonymous internal
+// backing function, which must be named if ThinLTO buffers are used
+
+#[linkage = "weak"]
+pub fn fn1(a: u32, b: u32, c: u32) -> u32 {
+ a + b + c
+}
+
+#[linkage = "weak"]
+pub fn fn2(a: u32, b: u32, c: u32) -> u32 {
+ a + b + c
+}
+++ /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.
-enum A {
- A {
- foo: usize,
- }
-}
-
-fn main() {
- let x = A::A { foo: 3 };
- match x {
- A::A { fob } => { println!("{}", fob); }
- }
-}
+++ /dev/null
-error[E0026]: variant `A::A` does not have a field named `fob`
- --> $DIR/issue-52717.rs:19:12
- |
-LL | A::A { fob } => { println!("{}", fob); }
- | ^^^
- | |
- | variant `A::A` does not have this field
- | help: did you mean: `foo`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0026`.
+++ /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.
-
-// Regression test for an NLL-related ICE (#52992) -- computing
-// implied bounds was causing outlives relations that were not
-// properly handled.
-//
-// compile-pass
-
-#![feature(nll)]
-
-fn main() {}
-
-fn fail<'a>() -> Struct<'a, Generic<()>> {
- Struct(&Generic(()))
-}
-
-struct Struct<'a, T>(&'a T) where
- T: Trait + 'a,
- T::AT: 'a; // only fails with this bound
-
-struct Generic<T>(T);
-
-trait Trait {
- type AT;
-}
-
-impl<T> Trait for Generic<T> {
- type AT = T; // only fails with a generic AT
-}
+++ /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.
-
-struct S;
-
-impl S {
- fn f() {}
-}
-
-macro_rules! impl_add {
- ($($n:ident)*) => {
- $(
- fn $n() {
- S::f::<i64>();
- //~^ ERROR wrong number of type arguments
- }
- )*
- }
-}
-
-impl_add!(a b);
-
-fn main() {}
+++ /dev/null
-error[E0107]: wrong number of type arguments: expected 0, found 1
- --> $DIR/issue-53251.rs:21:24
- |
-LL | S::f::<i64>();
- | ^^^ unexpected type argument
-...
-LL | impl_add!(a b);
- | --------------- in this macro invocation
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0107`.
+++ /dev/null
-// Copyright 2012-2014 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.
-
-// issue 53300
-
-pub trait A {
- fn add(&self, b: i32) -> i32;
-}
-
-fn addition() -> Wrapper<impl A> {}
-//~^ ERROR cannot find type `Wrapper` in this scope [E0412]
-
-fn main() {
- let res = addition();
-}
+++ /dev/null
-error[E0412]: cannot find type `Wrapper` in this scope
- --> $DIR/issue-53300.rs:17:18
- |
-LL | fn addition() -> Wrapper<impl A> {}
- | ^^^^^^^ not found in this scope
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0412`.
+++ /dev/null
-// Copyright 2012 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-pass
-
-struct Foo {
- bar: for<'r> Fn(usize, &'r FnMut())
-}
-
-fn main() {
-}
-
+++ /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.
-use std::time::{foo, bar, buzz};
-use std::time::{abc, def};
-fn main(){
- println!("Hello World!");
-}
+++ /dev/null
-error[E0432]: unresolved imports `std::time::foo`, `std::time::bar`, `std::time::buzz`
- --> $DIR/issue-53565.rs:10:17
- |
-LL | use std::time::{foo, bar, buzz};
- | ^^^ ^^^ ^^^^ no `buzz` in `time`
- | | |
- | | no `bar` in `time`
- | no `foo` in `time`
-
-error[E0432]: unresolved imports `std::time::abc`, `std::time::def`
- --> $DIR/issue-53565.rs:11:17
- |
-LL | use std::time::{abc, def};
- | ^^^ ^^^ no `def` in `time`
- | |
- | no `abc` in `time`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0432`.
+++ /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.
-
-// Regression test for an NLL-related ICE (#53568) -- we failed to
-// resolve inference variables in "custom type-ops".
-//
-// compile-pass
-
-#![feature(nll)]
-#![allow(dead_code)]
-
-trait Future {
- type Item;
-}
-
-impl<F, T> Future for F
-where F: Fn() -> T
-{
- type Item = T;
-}
-
-trait Connect {}
-
-struct Connector<H> {
- handler: H,
-}
-
-impl<H, T> Connect for Connector<H>
-where
- T: 'static,
- H: Future<Item = T>
-{
-}
-
-struct Client<C> {
- connector: C,
-}
-
-fn build<C>(_connector: C) -> Client<C> {
- unimplemented!()
-}
-
-fn client<H>(handler: H) -> Client<impl Connect>
-where H: Fn() + Copy
-{
- let connector = Connector {
- handler,
- };
- let client = build(connector);
- client
-}
-
-fn main() { }
-
+++ /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.
-fn main() {
- let items = vec![1, 2, 3];
- let ref_items: &[i32] = &items;
- let items_clone: Vec<i32> = ref_items.clone();
-
- // in that case no suggestion will be triggered
- let items_clone_2:Vec<i32> = items.clone();
-
- let s = "hi";
- let string: String = s.clone();
-
- // in that case no suggestion will be triggered
- let s2 = "hi";
- let string_2: String = s2.to_string();
-}
+++ /dev/null
-error[E0308]: mismatched types
- --> $DIR/issue-53692.rs:13:37
- |
-LL | let items_clone: Vec<i32> = ref_items.clone();
- | ^^^^^^^^^^^^^^^^^
- | |
- | expected struct `std::vec::Vec`, found &[i32]
- | help: try using a conversion method: `ref_items.to_vec()`
- |
- = note: expected type `std::vec::Vec<i32>`
- found type `&[i32]`
-
-error[E0308]: mismatched types
- --> $DIR/issue-53692.rs:19:30
- |
-LL | let string: String = s.clone();
- | ^^^^^^^^^
- | |
- | expected struct `std::string::String`, found &str
- | help: try using a conversion method: `s.to_string()`
- |
- = note: expected type `std::string::String`
- found type `&str`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0308`.
+++ /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.
-enum E {
- Foo(String, String, String),
-}
-
-struct Bar {
- a: String,
- b: String,
-}
-
-fn main() {
- let bar = Bar { a: "1".to_string(), b: "2".to_string() };
- match E::Foo("".into(), "".into(), "".into()) {
- E::Foo(a, b, ref c) => {}
- }
- match bar {
- Bar {a, ref b} => {}
- }
-}
+++ /dev/null
-error[E0009]: cannot bind by-move and by-ref in the same pattern
- --> $DIR/issue-53840.rs:22:16
- |
-LL | E::Foo(a, b, ref c) => {}
- | ^ ^ ----- both by-ref and by-move used
- | | |
- | | by-move pattern here
- | by-move pattern here
-
-error[E0009]: cannot bind by-move and by-ref in the same pattern
- --> $DIR/issue-53840.rs:25:14
- |
-LL | Bar {a, ref b} => {}
- | ^ ----- both by-ref and by-move used
- | |
- | by-move pattern here
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0009`.
+++ /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.
-
-trait Mirror {
- type Image;
- fn coerce(self) -> Self::Image;
-}
-
-impl<T> Mirror for T {
- type Image = T;
- fn coerce(self) -> Self { self }
-}
-
-trait Foo<'x, T> {
- fn foo(self) -> &'x T;
-}
-
-impl<'s, 'x, T: 'x> Foo<'x, T> for &'s T where &'s T: Foo2<'x, T> {
- fn foo(self) -> &'x T { self.foo2() }
-}
-
-trait Foo2<'x, T> {
- fn foo2(self) -> &'x T;
-}
-
-// example 1 - fails leak check
-impl<'x> Foo2<'x, u32> for &'x u32
-{
- fn foo2(self) -> &'x u32 { self }
-}
-
-// example 2 - OK with this issue
-impl<'x, 'a: 'x> Foo2<'x, i32> for &'a i32
-{
- fn foo2(self) -> &'x i32 { self }
-}
-
-// example 3 - fails due to issue #XYZ + Leak-check
-impl<'x, T> Foo2<'x, u64> for T
- where T: Mirror<Image=&'x u64>
-{
- fn foo2(self) -> &'x u64 { self.coerce() }
-}
-
-// example 4 - fails due to issue #XYZ
-impl<'x, 'a: 'x, T> Foo2<'x, i64> for T
- where T: Mirror<Image=&'a i64>
-{
- fn foo2(self) -> &'x i64 { self.coerce() }
-}
-
-
-trait RefFoo<T> {
- fn ref_foo(&self) -> &'static T;
-}
-
-impl<T> RefFoo<T> for T where for<'a> &'a T: Foo<'static, T> {
- fn ref_foo(&self) -> &'static T {
- self.foo()
- }
-}
-
-
-fn coerce_lifetime1(a: &u32) -> &'static u32
-{
- <u32 as RefFoo<u32>>::ref_foo(a)
- //~^ ERROR the trait bound `for<'a> &'a u32: Foo2<'_, u32>` is not satisfied
-}
-
-fn coerce_lifetime2(a: &i32) -> &'static i32
-{
- <i32 as RefFoo<i32>>::ref_foo(a)
- //~^ ERROR the requirement `for<'a> 'a : ` is not satisfied
-}
-
-fn coerce_lifetime3(a: &u64) -> &'static u64
-{
- <u64 as RefFoo<u64>>::ref_foo(a)
- //~^ ERROR type mismatch resolving `for<'a> <&'a u64 as Mirror>::Image == &u64`
-}
-
-fn coerce_lifetime4(a: &i64) -> &'static i64
-{
- <i64 as RefFoo<i64>>::ref_foo(a)
- //~^ ERROR type mismatch resolving `for<'a> <&'a i64 as Mirror>::Image == &i64`
-}
-
-fn main() {}
+++ /dev/null
-error[E0277]: the trait bound `for<'a> &'a u32: Foo2<'_, u32>` is not satisfied
- --> $DIR/issue-54302-cases.rs:73:5
- |
-LL | <u32 as RefFoo<u32>>::ref_foo(a)
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Foo2<'_, u32>` is not implemented for `&'a u32`
- |
- = help: the following implementations were found:
- <&'x u32 as Foo2<'x, u32>>
- = note: required because of the requirements on the impl of `for<'a> Foo<'static, u32>` for `&'a u32`
- = note: required because of the requirements on the impl of `RefFoo<u32>` for `u32`
-note: required by `RefFoo::ref_foo`
- --> $DIR/issue-54302-cases.rs:61:5
- |
-LL | fn ref_foo(&self) -> &'static T;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0279]: the requirement `for<'a> 'a : ` is not satisfied (`expected bound lifetime parameter 'a, found concrete lifetime`)
- --> $DIR/issue-54302-cases.rs:79:5
- |
-LL | <i32 as RefFoo<i32>>::ref_foo(a)
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: required because of the requirements on the impl of `for<'a> Foo2<'_, i32>` for `&'a i32`
- = note: required because of the requirements on the impl of `for<'a> Foo<'static, i32>` for `&'a i32`
- = note: required because of the requirements on the impl of `RefFoo<i32>` for `i32`
-note: required by `RefFoo::ref_foo`
- --> $DIR/issue-54302-cases.rs:61:5
- |
-LL | fn ref_foo(&self) -> &'static T;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0271]: type mismatch resolving `for<'a> <&'a u64 as Mirror>::Image == &u64`
- --> $DIR/issue-54302-cases.rs:85:5
- |
-LL | <u64 as RefFoo<u64>>::ref_foo(a)
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'a, found concrete lifetime
- |
- = note: required because of the requirements on the impl of `for<'a> Foo2<'_, u64>` for `&'a u64`
- = note: required because of the requirements on the impl of `for<'a> Foo<'static, u64>` for `&'a u64`
- = note: required because of the requirements on the impl of `RefFoo<u64>` for `u64`
-note: required by `RefFoo::ref_foo`
- --> $DIR/issue-54302-cases.rs:61:5
- |
-LL | fn ref_foo(&self) -> &'static T;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0271]: type mismatch resolving `for<'a> <&'a i64 as Mirror>::Image == &i64`
- --> $DIR/issue-54302-cases.rs:91:5
- |
-LL | <i64 as RefFoo<i64>>::ref_foo(a)
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'a, found concrete lifetime
- |
- = note: required because of the requirements on the impl of `for<'a> Foo2<'_, i64>` for `&'a i64`
- = note: required because of the requirements on the impl of `for<'a> Foo<'static, i64>` for `&'a i64`
- = note: required because of the requirements on the impl of `RefFoo<i64>` for `i64`
-note: required by `RefFoo::ref_foo`
- --> $DIR/issue-54302-cases.rs:61:5
- |
-LL | fn ref_foo(&self) -> &'static T;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 4 previous errors
-
-Some errors occurred: E0271, E0277, E0279.
-For more information about an error, try `rustc --explain E0271`.
+++ /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.
-
-trait Deserialize<'de> {}
-
-trait DeserializeOwned: for<'de> Deserialize<'de> {}
-impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
-
-// Based on this impl, `&'static str` only implements Deserialize<'static>.
-// It does not implement for<'de> Deserialize<'de>.
-impl<'de: 'a, 'a> Deserialize<'de> for &'a str {}
-
-fn main() {
- // Then why does it implement DeserializeOwned? This compiles.
- fn assert_deserialize_owned<T: DeserializeOwned>() {}
- assert_deserialize_owned::<&'static str>();
- //~^ ERROR the requirement `for<'de> 'de : ` is not satisfied
-
- // It correctly does not implement for<'de> Deserialize<'de>.
- //fn assert_hrtb<T: for<'de> Deserialize<'de>>() {}
- //assert_hrtb::<&'static str>();
-}
+++ /dev/null
-error[E0279]: the requirement `for<'de> 'de : ` is not satisfied (`expected bound lifetime parameter 'de, found concrete lifetime`)
- --> $DIR/issue-54302.rs:23:5
- |
-LL | assert_deserialize_owned::<&'static str>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: required because of the requirements on the impl of `for<'de> Deserialize<'de>` for `&'static str`
- = note: required because of the requirements on the impl of `DeserializeOwned` for `&'static str`
-note: required by `main::assert_deserialize_owned`
- --> $DIR/issue-54302.rs:22:5
- |
-LL | fn assert_deserialize_owned<T: DeserializeOwned>() {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0279`.
--- /dev/null
+// Copyright 2014 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.
+
+enum Foo {
+ Bar(isize)
+}
+
+pub mod test {
+ enum Foo {
+ Bar(isize)
+ }
+}
--- /dev/null
+// Copyright 2014 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.
+
+extern {
+ fn bar();
+}
--- /dev/null
+// Copyright 2014 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.
+
+pub use foo::FOO2;
+
+pub const FOO: usize = 3;
+const BAR: usize = 3;
+
+mod foo {
+ pub const FOO2: usize = 3;
+}
--- /dev/null
+// Copyright 2017 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.
+
+// Just exporting some type to test for correct diagnostics when this
+// crate is pulled in at a non-root location in client crate.
+
+pub struct S;
--- /dev/null
+// Copyright 2015 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.
+
+pub mod A {
+ pub struct Foo;
+ impl Foo {
+ fn foo(&self) { }
+ }
+}
--- /dev/null
+// Copyright 2015 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.
+
+use std::marker::PhantomData;
+
+pub struct Directed;
+pub struct Undirected;
+
+pub struct Graph<N, E, Ty = Directed> {
+ nodes: Vec<PhantomData<N>>,
+ edges: Vec<PhantomData<E>>,
+ ty: PhantomData<Ty>,
+}
+
+
+impl<N, E> Graph<N, E, Directed> {
+ pub fn new() -> Self {
+ Graph{nodes: Vec::new(), edges: Vec::new(), ty: PhantomData}
+ }
+}
+
+impl<N, E> Graph<N, E, Undirected> {
+ pub fn new_undirected() -> Self {
+ Graph{nodes: Vec::new(), edges: Vec::new(), ty: PhantomData}
+ }
+}
--- /dev/null
+// Copyright 2017 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.
+
+
+pub trait Trait {
+ const CONST: u32;
+}
--- /dev/null
+// Copyright 2013 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.
+
+extern "C" {
+ pub fn rand() -> u32;
+}
+++ /dev/null
-// Copyright 2014 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.
-
-enum Foo {
- Bar(isize)
-}
-
-pub mod test {
- enum Foo {
- Bar(isize)
- }
-}
+++ /dev/null
-// Copyright 2014 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.
-
-extern {
- fn bar();
-}
+++ /dev/null
-// Copyright 2014 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.
-
-pub use foo::FOO2;
-
-pub const FOO: usize = 3;
-const BAR: usize = 3;
-
-mod foo {
- pub const FOO2: usize = 3;
-}
+++ /dev/null
-// Copyright 2017 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.
-
-// Just exporting some type to test for correct diagnostics when this
-// crate is pulled in at a non-root location in client crate.
-
-pub struct S;
+++ /dev/null
-// Copyright 2015 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.
-
-pub mod A {
- pub struct Foo;
- impl Foo {
- fn foo(&self) { }
- }
-}
+++ /dev/null
-// Copyright 2015 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.
-
-use std::marker::PhantomData;
-
-pub struct Directed;
-pub struct Undirected;
-
-pub struct Graph<N, E, Ty = Directed> {
- nodes: Vec<PhantomData<N>>,
- edges: Vec<PhantomData<E>>,
- ty: PhantomData<Ty>,
-}
-
-
-impl<N, E> Graph<N, E, Directed> {
- pub fn new() -> Self {
- Graph{nodes: Vec::new(), edges: Vec::new(), ty: PhantomData}
- }
-}
-
-impl<N, E> Graph<N, E, Undirected> {
- pub fn new_undirected() -> Self {
- Graph{nodes: Vec::new(), edges: Vec::new(), ty: PhantomData}
- }
-}
+++ /dev/null
-// Copyright 2017 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.
-
-
-pub trait Trait {
- const CONST: u32;
-}
+++ /dev/null
-// Copyright 2013 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.
-
-extern "C" {
- pub fn rand() -> u32;
-}
--- /dev/null
+// Copyright 2013 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.
+
+#![crate_name="lint_stability"]
+#![crate_type = "lib"]
+#![feature(staged_api)]
+#![feature(associated_type_defaults)]
+#![stable(feature = "lint_stability", since = "1.0.0")]
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[rustc_deprecated(since = "1.0.0", reason = "text")]
+pub fn deprecated() {}
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[rustc_deprecated(since = "1.0.0", reason = "text")]
+pub fn deprecated_text() {}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[rustc_deprecated(since = "99.99.99", reason = "text")]
+pub fn deprecated_future() {}
+
+#[unstable(feature = "unstable_test_feature", issue = "0")]
+#[rustc_deprecated(since = "1.0.0", reason = "text")]
+pub fn deprecated_unstable() {}
+#[unstable(feature = "unstable_test_feature", issue = "0")]
+#[rustc_deprecated(since = "1.0.0", reason = "text")]
+pub fn deprecated_unstable_text() {}
+
+#[unstable(feature = "unstable_test_feature", issue = "0")]
+pub fn unstable() {}
+#[unstable(feature = "unstable_test_feature", reason = "text", issue = "0")]
+pub fn unstable_text() {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn stable() {}
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn stable_text() {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct MethodTester;
+
+impl MethodTester {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")]
+ #[rustc_deprecated(since = "1.0.0", reason = "text")]
+ pub fn method_deprecated(&self) {}
+ #[stable(feature = "stable_test_feature", since = "1.0.0")]
+ #[rustc_deprecated(since = "1.0.0", reason = "text")]
+ pub fn method_deprecated_text(&self) {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "0")]
+ #[rustc_deprecated(since = "1.0.0", reason = "text")]
+ pub fn method_deprecated_unstable(&self) {}
+ #[unstable(feature = "unstable_test_feature", issue = "0")]
+ #[rustc_deprecated(since = "1.0.0", reason = "text")]
+ pub fn method_deprecated_unstable_text(&self) {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "0")]
+ pub fn method_unstable(&self) {}
+ #[unstable(feature = "unstable_test_feature", reason = "text", issue = "0")]
+ pub fn method_unstable_text(&self) {}
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn method_stable(&self) {}
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn method_stable_text(&self) {}
+}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+pub trait Trait {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")]
+ #[rustc_deprecated(since = "1.0.0", reason = "text")]
+ fn trait_deprecated(&self) {}
+ #[stable(feature = "stable_test_feature", since = "1.0.0")]
+ #[rustc_deprecated(since = "1.0.0", reason = "text")]
+ fn trait_deprecated_text(&self) {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "0")]
+ #[rustc_deprecated(since = "1.0.0", reason = "text")]
+ fn trait_deprecated_unstable(&self) {}
+ #[unstable(feature = "unstable_test_feature", issue = "0")]
+ #[rustc_deprecated(since = "1.0.0", reason = "text")]
+ fn trait_deprecated_unstable_text(&self) {}
+
+ #[unstable(feature = "unstable_test_feature", issue = "0")]
+ fn trait_unstable(&self) {}
+ #[unstable(feature = "unstable_test_feature", reason = "text", issue = "0")]
+ fn trait_unstable_text(&self) {}
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn trait_stable(&self) {}
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn trait_stable_text(&self) {}
+}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+pub trait TraitWithAssociatedTypes {
+ #[unstable(feature = "unstable_test_feature", issue = "0")]
+ type TypeUnstable = u8;
+ #[stable(feature = "stable_test_feature", since = "1.0.0")]
+ #[rustc_deprecated(since = "1.0.0", reason = "text")]
+ type TypeDeprecated = u8;
+}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+impl Trait for MethodTester {}
+
+#[unstable(feature = "unstable_test_feature", issue = "0")]
+pub trait UnstableTrait { fn dummy(&self) { } }
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[rustc_deprecated(since = "1.0.0", reason = "text")]
+pub trait DeprecatedTrait {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")] fn dummy(&self) { }
+}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[rustc_deprecated(since = "1.0.0", reason = "text")]
+pub struct DeprecatedStruct {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize
+}
+#[unstable(feature = "unstable_test_feature", issue = "0")]
+#[rustc_deprecated(since = "1.0.0", reason = "text")]
+pub struct DeprecatedUnstableStruct {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize
+}
+#[unstable(feature = "unstable_test_feature", issue = "0")]
+pub struct UnstableStruct {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct StableStruct {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize
+}
+#[unstable(feature = "unstable_test_feature", issue = "0")]
+pub enum UnstableEnum {}
+#[stable(feature = "rust1", since = "1.0.0")]
+pub enum StableEnum {}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[rustc_deprecated(since = "1.0.0", reason = "text")]
+pub struct DeprecatedUnitStruct;
+#[unstable(feature = "unstable_test_feature", issue = "0")]
+#[rustc_deprecated(since = "1.0.0", reason = "text")]
+pub struct DeprecatedUnstableUnitStruct;
+#[unstable(feature = "unstable_test_feature", issue = "0")]
+pub struct UnstableUnitStruct;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct StableUnitStruct;
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+pub enum Enum {
+ #[stable(feature = "stable_test_feature", since = "1.0.0")]
+ #[rustc_deprecated(since = "1.0.0", reason = "text")]
+ DeprecatedVariant,
+ #[unstable(feature = "unstable_test_feature", issue = "0")]
+ #[rustc_deprecated(since = "1.0.0", reason = "text")]
+ DeprecatedUnstableVariant,
+ #[unstable(feature = "unstable_test_feature", issue = "0")]
+ UnstableVariant,
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ StableVariant,
+}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[rustc_deprecated(since = "1.0.0", reason = "text")]
+pub struct DeprecatedTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
+#[unstable(feature = "unstable_test_feature", issue = "0")]
+#[rustc_deprecated(since = "1.0.0", reason = "text")]
+pub struct DeprecatedUnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
+#[unstable(feature = "unstable_test_feature", issue = "0")]
+pub struct UnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct StableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[macro_export]
+macro_rules! macro_test {
+ () => (deprecated());
+}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[macro_export]
+macro_rules! macro_test_arg {
+ ($func:expr) => ($func);
+}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[macro_export]
+macro_rules! macro_test_arg_nested {
+ ($func:ident) => (macro_test_arg!($func()));
+}
+++ /dev/null
-// Copyright 2013 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.
-
-#![crate_name="lint_stability"]
-#![crate_type = "lib"]
-#![feature(staged_api)]
-#![feature(associated_type_defaults)]
-#![stable(feature = "lint_stability", since = "1.0.0")]
-
-#[stable(feature = "stable_test_feature", since = "1.0.0")]
-#[rustc_deprecated(since = "1.0.0", reason = "text")]
-pub fn deprecated() {}
-#[stable(feature = "stable_test_feature", since = "1.0.0")]
-#[rustc_deprecated(since = "1.0.0", reason = "text")]
-pub fn deprecated_text() {}
-
-#[stable(feature = "stable_test_feature", since = "1.0.0")]
-#[rustc_deprecated(since = "99.99.99", reason = "text")]
-pub fn deprecated_future() {}
-
-#[unstable(feature = "unstable_test_feature", issue = "0")]
-#[rustc_deprecated(since = "1.0.0", reason = "text")]
-pub fn deprecated_unstable() {}
-#[unstable(feature = "unstable_test_feature", issue = "0")]
-#[rustc_deprecated(since = "1.0.0", reason = "text")]
-pub fn deprecated_unstable_text() {}
-
-#[unstable(feature = "unstable_test_feature", issue = "0")]
-pub fn unstable() {}
-#[unstable(feature = "unstable_test_feature", reason = "text", issue = "0")]
-pub fn unstable_text() {}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-pub fn stable() {}
-#[stable(feature = "rust1", since = "1.0.0")]
-pub fn stable_text() {}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct MethodTester;
-
-impl MethodTester {
- #[stable(feature = "stable_test_feature", since = "1.0.0")]
- #[rustc_deprecated(since = "1.0.0", reason = "text")]
- pub fn method_deprecated(&self) {}
- #[stable(feature = "stable_test_feature", since = "1.0.0")]
- #[rustc_deprecated(since = "1.0.0", reason = "text")]
- pub fn method_deprecated_text(&self) {}
-
- #[unstable(feature = "unstable_test_feature", issue = "0")]
- #[rustc_deprecated(since = "1.0.0", reason = "text")]
- pub fn method_deprecated_unstable(&self) {}
- #[unstable(feature = "unstable_test_feature", issue = "0")]
- #[rustc_deprecated(since = "1.0.0", reason = "text")]
- pub fn method_deprecated_unstable_text(&self) {}
-
- #[unstable(feature = "unstable_test_feature", issue = "0")]
- pub fn method_unstable(&self) {}
- #[unstable(feature = "unstable_test_feature", reason = "text", issue = "0")]
- pub fn method_unstable_text(&self) {}
-
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn method_stable(&self) {}
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn method_stable_text(&self) {}
-}
-
-#[stable(feature = "stable_test_feature", since = "1.0.0")]
-pub trait Trait {
- #[stable(feature = "stable_test_feature", since = "1.0.0")]
- #[rustc_deprecated(since = "1.0.0", reason = "text")]
- fn trait_deprecated(&self) {}
- #[stable(feature = "stable_test_feature", since = "1.0.0")]
- #[rustc_deprecated(since = "1.0.0", reason = "text")]
- fn trait_deprecated_text(&self) {}
-
- #[unstable(feature = "unstable_test_feature", issue = "0")]
- #[rustc_deprecated(since = "1.0.0", reason = "text")]
- fn trait_deprecated_unstable(&self) {}
- #[unstable(feature = "unstable_test_feature", issue = "0")]
- #[rustc_deprecated(since = "1.0.0", reason = "text")]
- fn trait_deprecated_unstable_text(&self) {}
-
- #[unstable(feature = "unstable_test_feature", issue = "0")]
- fn trait_unstable(&self) {}
- #[unstable(feature = "unstable_test_feature", reason = "text", issue = "0")]
- fn trait_unstable_text(&self) {}
-
- #[stable(feature = "rust1", since = "1.0.0")]
- fn trait_stable(&self) {}
- #[stable(feature = "rust1", since = "1.0.0")]
- fn trait_stable_text(&self) {}
-}
-
-#[stable(feature = "stable_test_feature", since = "1.0.0")]
-pub trait TraitWithAssociatedTypes {
- #[unstable(feature = "unstable_test_feature", issue = "0")]
- type TypeUnstable = u8;
- #[stable(feature = "stable_test_feature", since = "1.0.0")]
- #[rustc_deprecated(since = "1.0.0", reason = "text")]
- type TypeDeprecated = u8;
-}
-
-#[stable(feature = "stable_test_feature", since = "1.0.0")]
-impl Trait for MethodTester {}
-
-#[unstable(feature = "unstable_test_feature", issue = "0")]
-pub trait UnstableTrait { fn dummy(&self) { } }
-
-#[stable(feature = "stable_test_feature", since = "1.0.0")]
-#[rustc_deprecated(since = "1.0.0", reason = "text")]
-pub trait DeprecatedTrait {
- #[stable(feature = "stable_test_feature", since = "1.0.0")] fn dummy(&self) { }
-}
-
-#[stable(feature = "stable_test_feature", since = "1.0.0")]
-#[rustc_deprecated(since = "1.0.0", reason = "text")]
-pub struct DeprecatedStruct {
- #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize
-}
-#[unstable(feature = "unstable_test_feature", issue = "0")]
-#[rustc_deprecated(since = "1.0.0", reason = "text")]
-pub struct DeprecatedUnstableStruct {
- #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize
-}
-#[unstable(feature = "unstable_test_feature", issue = "0")]
-pub struct UnstableStruct {
- #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct StableStruct {
- #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize
-}
-#[unstable(feature = "unstable_test_feature", issue = "0")]
-pub enum UnstableEnum {}
-#[stable(feature = "rust1", since = "1.0.0")]
-pub enum StableEnum {}
-
-#[stable(feature = "stable_test_feature", since = "1.0.0")]
-#[rustc_deprecated(since = "1.0.0", reason = "text")]
-pub struct DeprecatedUnitStruct;
-#[unstable(feature = "unstable_test_feature", issue = "0")]
-#[rustc_deprecated(since = "1.0.0", reason = "text")]
-pub struct DeprecatedUnstableUnitStruct;
-#[unstable(feature = "unstable_test_feature", issue = "0")]
-pub struct UnstableUnitStruct;
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct StableUnitStruct;
-
-#[stable(feature = "stable_test_feature", since = "1.0.0")]
-pub enum Enum {
- #[stable(feature = "stable_test_feature", since = "1.0.0")]
- #[rustc_deprecated(since = "1.0.0", reason = "text")]
- DeprecatedVariant,
- #[unstable(feature = "unstable_test_feature", issue = "0")]
- #[rustc_deprecated(since = "1.0.0", reason = "text")]
- DeprecatedUnstableVariant,
- #[unstable(feature = "unstable_test_feature", issue = "0")]
- UnstableVariant,
-
- #[stable(feature = "rust1", since = "1.0.0")]
- StableVariant,
-}
-
-#[stable(feature = "stable_test_feature", since = "1.0.0")]
-#[rustc_deprecated(since = "1.0.0", reason = "text")]
-pub struct DeprecatedTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
-#[unstable(feature = "unstable_test_feature", issue = "0")]
-#[rustc_deprecated(since = "1.0.0", reason = "text")]
-pub struct DeprecatedUnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
-#[unstable(feature = "unstable_test_feature", issue = "0")]
-pub struct UnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct StableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
-
-#[stable(feature = "stable_test_feature", since = "1.0.0")]
-#[macro_export]
-macro_rules! macro_test {
- () => (deprecated());
-}
-
-#[stable(feature = "stable_test_feature", since = "1.0.0")]
-#[macro_export]
-macro_rules! macro_test_arg {
- ($func:expr) => ($func);
-}
-
-#[stable(feature = "stable_test_feature", since = "1.0.0")]
-#[macro_export]
-macro_rules! macro_test_arg_nested {
- ($func:ident) => (macro_test_arg!($func()));
-}
--- /dev/null
+// Copyright 2014 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.
+
+trait Foo {}
+++ /dev/null
-// Copyright 2014 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.
-
-trait Foo {}
--- /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.
+
+#![crate_type="lib"]
+
+
+pub trait A {
+ fn a(&self) {}
+}
+impl A for () {}
--- /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.
+
+#![crate_type="lib"]
+
+pub extern crate xcrate_issue_43189_a;
--- /dev/null
+// Copyright 2017 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.
+
+#![crate_type="lib"]
+
+pub extern crate core;
+++ /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.
-
-#![crate_type="lib"]
-
-
-pub trait A {
- fn a(&self) {}
-}
-impl A for () {}
+++ /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.
-
-#![crate_type="lib"]
-
-pub extern crate xcrate_issue_43189_a;
+++ /dev/null
-// Copyright 2017 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.
-
-#![crate_type="lib"]
-
-pub extern crate core;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// aux-build:private_trait_xc.rs
+// aux-build:private-trait-xc.rs
extern crate private_trait_xc;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// aux-build:issue_11680.rs
+// aux-build:issue-11680.rs
extern crate issue_11680 as other;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// aux-build:issue_16725.rs
+// aux-build:issue-16725.rs
extern crate issue_16725 as foo;
--- /dev/null
+error[E0499]: cannot borrow `x` (via `x.b`) as mutable more than once at a time
+ --> $DIR/issue-17263.rs:17:34
+ |
+LL | let (a, b) = (&mut x.a, &mut x.b);
+ | --- ^^^ second mutable borrow occurs here (via `x.b`)
+ | |
+ | first mutable borrow occurs here (via `x.a`)
+...
+LL | }
+ | - first borrow ends here
+
+error[E0502]: cannot borrow `foo` (via `foo.b`) as immutable because `foo` is also borrowed as mutable (via `foo.a`)
+ --> $DIR/issue-17263.rs:21:32
+ |
+LL | let (c, d) = (&mut foo.a, &foo.b);
+ | ----- ^^^^^ immutable borrow occurs here (via `foo.b`)
+ | |
+ | mutable borrow occurs here (via `foo.a`)
+...
+LL | }
+ | - mutable borrow ends here
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0499, E0502.
+For more information about an error, try `rustc --explain E0499`.
error: compilation successful
--> $DIR/issue-17263.rs:15:1
|
-LL | / fn main() { #![rustc_error] // rust-lang/rust#49855
+LL | / fn main() { //[nll]~ ERROR compilation successful
LL | | let mut x: Box<_> = box Foo { a: 1, b: 2 };
LL | | let (a, b) = (&mut x.a, &mut x.b);
-LL | | //~^ ERROR cannot borrow `x` (via `x.b`) as mutable more than once at a time
+LL | | //[ast]~^ ERROR cannot borrow `x` (via `x.b`) as mutable more than once at a time
... |
-LL | | //~^ ERROR cannot borrow `foo` (via `foo.b`) as immutable
+LL | | use_mut(a);
LL | | }
| |_^
-// Copyright 2014 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.
+// This checks diagnostic quality for cases where AST-borrowck treated
+// `Box<T>` as other types (see rust-lang/rfcs#130). NLL again treats
+// `Box<T>` specially. We capture the differences via revisions.
+// revisions: ast nll
+//[ast]compile-flags: -Z borrowck=ast
+//[nll]compile-flags: -Z borrowck=migrate -Z two-phase-borrows
+
+// don't worry about the --compare-mode=nll on this test.
+// ignore-compare-mode-nll
#![feature(box_syntax, rustc_attrs)]
struct Foo { a: isize, b: isize }
-
-fn main() { #![rustc_error] // rust-lang/rust#49855
+#[rustc_error] // rust-lang/rust#49855
+fn main() { //[nll]~ ERROR compilation successful
let mut x: Box<_> = box Foo { a: 1, b: 2 };
let (a, b) = (&mut x.a, &mut x.b);
- //~^ ERROR cannot borrow `x` (via `x.b`) as mutable more than once at a time
+ //[ast]~^ ERROR cannot borrow `x` (via `x.b`) as mutable more than once at a time
let mut foo: Box<_> = box Foo { a: 1, b: 2 };
let (c, d) = (&mut foo.a, &foo.b);
- //~^ ERROR cannot borrow `foo` (via `foo.b`) as immutable
+ //[ast]~^ ERROR cannot borrow `foo` (via `foo.b`) as immutable
+
+ // We explicitly use the references created above to illustrate
+ // that NLL is accepting this code *not* because of artificially
+ // short lifetimes, but rather because it understands that all the
+ // references are of disjoint parts of memory.
+ use_imm(d);
+ use_mut(c);
+ use_mut(b);
+ use_mut(a);
}
+
+fn use_mut<T>(_: &mut T) { }
+fn use_imm<T>(_: &T) { }
+++ /dev/null
-error[E0499]: cannot borrow `x` (via `x.b`) as mutable more than once at a time
- --> $DIR/issue-17263.rs:17:34
- |
-LL | let (a, b) = (&mut x.a, &mut x.b);
- | --- ^^^ second mutable borrow occurs here (via `x.b`)
- | |
- | first mutable borrow occurs here (via `x.a`)
-...
-LL | }
- | - first borrow ends here
-
-error[E0502]: cannot borrow `foo` (via `foo.b`) as immutable because `foo` is also borrowed as mutable (via `foo.a`)
- --> $DIR/issue-17263.rs:21:32
- |
-LL | let (c, d) = (&mut foo.a, &foo.b);
- | ----- ^^^^^ immutable borrow occurs here (via `foo.b`)
- | |
- | mutable borrow occurs here (via `foo.a`)
-LL | //~^ ERROR cannot borrow `foo` (via `foo.b`) as immutable
-LL | }
- | - mutable borrow ends here
-
-error: aborting due to 2 previous errors
-
-Some errors occurred: E0499, E0502.
-For more information about an error, try `rustc --explain E0499`.
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// aux-build:issue_17718_const_privacy.rs
+// aux-build:issue-17718-const-privacy.rs
extern crate issue_17718_const_privacy as other;
//! Test that absolute path names are correct when a crate is not linked into the root namespace
-// aux-build:issue_1920.rs
+// aux-build:issue-1920.rs
mod foo {
pub extern crate issue_1920;
//! Test that when a crate is linked under another name that name is used in global paths
-// aux-build:issue_1920.rs
+// aux-build:issue-1920.rs
extern crate issue_1920 as bar;
//! Test that when a crate is linked multiple times that the shortest absolute path name is used
-// aux-build:issue_1920.rs
+// aux-build:issue-1920.rs
mod foo {
pub extern crate issue_1920;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// aux-build:issue_21202.rs
+// aux-build:issue-21202.rs
extern crate issue_21202 as crate1;
// Unstable entities should be caught in import lists
-// aux-build:lint_stability.rs
+// aux-build:lint-stability.rs
#![allow(warnings)]
// Prefix in imports with empty braces should be resolved and checked privacy, stability, etc.
-// aux-build:lint_stability.rs
+// aux-build:lint-stability.rs
extern crate lint_stability;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// aux-build:issue_30123_aux.rs
+// aux-build:issue-30123-aux.rs
extern crate issue_30123_aux;
use issue_30123_aux::*;
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`.
--- /dev/null
+// Copyright 2016 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.
+
+// ignore-tidy-linelength
+
+#![feature(const_fn)]
+
+const bad : u32 = {
+ {
+ 5;
+ //~^ ERROR statements in constants are unstable
+ 0
+ }
+};
+
+const bad_two : u32 = {
+ {
+ invalid();
+ //~^ ERROR statements in constants are unstable
+ //~^^ ERROR: calls in constants are limited to constant functions, tuple structs and tuple variants
+ 0
+ }
+};
+
+const bad_three : u32 = {
+ {
+ valid();
+ //~^ ERROR statements in constants are unstable
+ 0
+ }
+};
+
+static bad_four : u32 = {
+ {
+ 5;
+ //~^ ERROR statements in statics are unstable
+ 0
+ }
+};
+
+static bad_five : u32 = {
+ {
+ invalid();
+ //~^ ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants
+ //~| ERROR statements in statics are unstable
+ 0
+ }
+};
+
+static bad_six : u32 = {
+ {
+ valid();
+ //~^ ERROR statements in statics are unstable
+ 0
+ }
+};
+
+static mut bad_seven : u32 = {
+ {
+ 5;
+ //~^ ERROR statements in statics are unstable
+ 0
+ }
+};
+
+static mut bad_eight : u32 = {
+ {
+ invalid();
+ //~^ ERROR statements in statics are unstable
+ //~| ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants
+ 0
+ }
+};
+
+static mut bad_nine : u32 = {
+ {
+ valid();
+ //~^ ERROR statements in statics are unstable
+ 0
+ }
+};
+
+
+fn invalid() {}
+const fn valid() {}
+
+fn main() {}
--- /dev/null
+error[E0658]: statements in constants are unstable (see issue #48821)
+ --> $DIR/issue-32829-2.rs:17:9
+ |
+LL | 5;
+ | ^
+ |
+ = help: add #![feature(const_let)] to the crate attributes to enable
+
+error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
+ --> $DIR/issue-32829-2.rs:25:9
+ |
+LL | invalid();
+ | ^^^^^^^^^
+
+error[E0658]: statements in constants are unstable (see issue #48821)
+ --> $DIR/issue-32829-2.rs:25:9
+ |
+LL | invalid();
+ | ^^^^^^^^^
+ |
+ = help: add #![feature(const_let)] to the crate attributes to enable
+
+error[E0658]: statements in constants are unstable (see issue #48821)
+ --> $DIR/issue-32829-2.rs:34:9
+ |
+LL | valid();
+ | ^^^^^^^
+ |
+ = help: add #![feature(const_let)] to the crate attributes to enable
+
+error[E0658]: statements in statics are unstable (see issue #48821)
+ --> $DIR/issue-32829-2.rs:42:9
+ |
+LL | 5;
+ | ^
+ |
+ = help: add #![feature(const_let)] to the crate attributes to enable
+
+error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
+ --> $DIR/issue-32829-2.rs:50:9
+ |
+LL | invalid();
+ | ^^^^^^^^^
+
+error[E0658]: statements in statics are unstable (see issue #48821)
+ --> $DIR/issue-32829-2.rs:50:9
+ |
+LL | invalid();
+ | ^^^^^^^^^
+ |
+ = help: add #![feature(const_let)] to the crate attributes to enable
+
+error[E0658]: statements in statics are unstable (see issue #48821)
+ --> $DIR/issue-32829-2.rs:59:9
+ |
+LL | valid();
+ | ^^^^^^^
+ |
+ = help: add #![feature(const_let)] to the crate attributes to enable
+
+error[E0658]: statements in statics are unstable (see issue #48821)
+ --> $DIR/issue-32829-2.rs:67:9
+ |
+LL | 5;
+ | ^
+ |
+ = help: add #![feature(const_let)] to the crate attributes to enable
+
+error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
+ --> $DIR/issue-32829-2.rs:75:9
+ |
+LL | invalid();
+ | ^^^^^^^^^
+
+error[E0658]: statements in statics are unstable (see issue #48821)
+ --> $DIR/issue-32829-2.rs:75:9
+ |
+LL | invalid();
+ | ^^^^^^^^^
+ |
+ = help: add #![feature(const_let)] to the crate attributes to enable
+
+error[E0658]: statements in statics are unstable (see issue #48821)
+ --> $DIR/issue-32829-2.rs:84:9
+ |
+LL | valid();
+ | ^^^^^^^
+ |
+ = help: add #![feature(const_let)] to the crate attributes to enable
+
+error: aborting due to 12 previous errors
+
+Some errors occurred: E0015, E0658.
+For more information about an error, try `rustc --explain E0015`.
--- /dev/null
+// Copyright 2017 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.
+
+pub const FOO: usize = *&0;
+++ /dev/null
-// Copyright 2017 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.
-
-pub const FOO: usize = *&0;
--- /dev/null
+// Copyright 2017 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.
+
+// aux-build:issue-38875-b.rs
+// compile-pass
+
+extern crate issue_38875_b;
+
+fn main() {
+ let test_x = [0; issue_38875_b::FOO];
+}
+++ /dev/null
-// Copyright 2017 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.
-
-// aux-build:issue_38875_b.rs
-// compile-pass
-
-extern crate issue_38875_b;
-
-fn main() {
- let test_x = [0; issue_38875_b::FOO];
-}
--- /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.
+
+use std::rc::Rc;
+use std::sync::Arc;
+
+struct Foo(Arc<Bar>);
+
+enum Bar {
+ A(Rc<Foo>),
+ B(Option<Foo>),
+}
+
+fn f<T: Send>(_: T) {}
+
+fn main() {
+ f(Foo(Arc::new(Bar::B(None))));
+ //~^ ERROR E0277
+ //~| ERROR E0277
+}
--- /dev/null
+error[E0277]: `std::rc::Rc<Foo>` cannot be sent between threads safely
+ --> $DIR/issue-40827.rs:24:5
+ |
+LL | f(Foo(Arc::new(Bar::B(None))));
+ | ^ `std::rc::Rc<Foo>` cannot be sent between threads safely
+ |
+ = help: within `Bar`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<Foo>`
+ = note: required because it appears within the type `Bar`
+ = note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<Bar>`
+ = note: required because it appears within the type `Foo`
+note: required by `f`
+ --> $DIR/issue-40827.rs:21:1
+ |
+LL | fn f<T: Send>(_: T) {}
+ | ^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: `std::rc::Rc<Foo>` cannot be shared between threads safely
+ --> $DIR/issue-40827.rs:24:5
+ |
+LL | f(Foo(Arc::new(Bar::B(None))));
+ | ^ `std::rc::Rc<Foo>` cannot be shared between threads safely
+ |
+ = help: within `Bar`, the trait `std::marker::Sync` is not implemented for `std::rc::Rc<Foo>`
+ = note: required because it appears within the type `Bar`
+ = note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<Bar>`
+ = note: required because it appears within the type `Foo`
+note: required by `f`
+ --> $DIR/issue-40827.rs:21:1
+ |
+LL | fn f<T: Send>(_: T) {}
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// aux-build:issue_41549.rs
+// aux-build:issue-41549.rs
extern crate issue_41549;
--- /dev/null
+// Copyright 2017 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.
+
+pub trait Tr {
+ // Note: The function needs to be declared over multiple lines to reproduce
+ // the crash. DO NOT reformat.
+ fn f()
+ where Self: Sized;
+}
+++ /dev/null
-// Copyright 2017 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.
-
-pub trait Tr {
- // Note: The function needs to be declared over multiple lines to reproduce
- // the crash. DO NOT reformat.
- fn f()
- where Self: Sized;
-}
--- /dev/null
+// Copyright 2017 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.
+
+// aux-build:issue-41652-b.rs
+
+extern crate issue_41652_b;
+
+struct S;
+
+impl issue_41652_b::Tr for S {
+ fn f() {
+ 3.f()
+ //~^ ERROR can't call method `f` on ambiguous numeric type `{integer}`
+ }
+}
+
+fn main() {}
--- /dev/null
+error[E0689]: can't call method `f` on ambiguous numeric type `{integer}`
+ --> $DIR/issue-41652.rs:19:11
+ |
+LL | 3.f()
+ | ^
+help: you must specify a concrete type for this numeric value, like `i32`
+ |
+LL | 3_i32.f()
+ | ^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0689`.
+++ /dev/null
-// Copyright 2017 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.
-
-// aux-build:issue_41652_b.rs
-
-extern crate issue_41652_b;
-
-struct S;
-
-impl issue_41652_b::Tr for S {
- fn f() {
- 3.f()
- //~^ ERROR can't call method `f` on ambiguous numeric type `{integer}`
- }
-}
-
-fn main() {}
+++ /dev/null
-error[E0689]: can't call method `f` on ambiguous numeric type `{integer}`
- --> $DIR/issue_41652.rs:19:11
- |
-LL | 3.f()
- | ^
-help: you must specify a concrete type for this numeric value, like `i32`
- |
-LL | 3_i32.f()
- | ^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0689`.
// paths rooted from `std` to be misrendered in the diagnostic output.
// ignore-windows
-// aux-build:xcrate_issue_43189_a.rs
-// aux-build:xcrate_issue_43189_b.rs
+// aux-build:xcrate-issue-43189-a.rs
+// aux-build:xcrate-issue-43189-b.rs
extern crate xcrate_issue_43189_b;
fn main() {
--- /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.
+
+pub const FOO: usize = *&0;
--- /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.
+
+pub const FOO: usize = *&0;
+++ /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.
-
-pub const FOO: usize = *&0;
+++ /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.
-
-pub const FOO: usize = *&0;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// aux-build:issue_45829_b.rs
+// aux-build:issue-45829-b.rs
mod foo {
pub mod bar {}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// aux-build:issue_45829_a.rs
-// aux-build:issue_45829_b.rs
+// aux-build:issue-45829-a.rs
+// aux-build:issue-45829-b.rs
extern crate issue_45829_a;
extern crate issue_45829_b as issue_45829_a;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// aux-build:issue_45829_a.rs
-// aux-build:issue_45829_b.rs
+// aux-build:issue-45829-a.rs
+// aux-build:issue-45829-b.rs
extern crate issue_45829_a;
extern crate issue_45829_b as issue_45829_a;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// aux-build:issue_45829_b.rs
+// aux-build:issue-45829-b.rs
extern crate issue_45829_b;
use std as issue_45829_b;
// paths rooted from `std` to be misrendered in the diagnostic output.
// ignore-windows
-// aux-build:xcrate_issue_46112_rexport_core.rs
+// aux-build:xcrate-issue-46112-rexport-core.rs
extern crate xcrate_issue_46112_rexport_core;
fn test(r: Result<Option<()>, &'static str>) { }
--- /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-pass
+fn iter<'a>(data: &'a [usize]) -> impl Iterator<Item = usize> + 'a {
+ data.iter()
+ .map(
+ |x| x // fn(&'a usize) -> &'(ReScope) usize
+ )
+ .map(
+ |x| *x // fn(&'(ReScope) usize) -> usize
+ )
+}
+
+fn main() {
+}
--- /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(inner_deref)]
+
+fn main() {
+ let _result = &Some(42).deref();
+//~^ ERROR no method named `deref` found for type `std::option::Option<{integer}>`
+}
--- /dev/null
+error[E0599]: no method named `deref` found for type `std::option::Option<{integer}>` in the current scope
+ --> $DIR/option-deref.rs:14:29
+ |
+LL | let _result = &Some(42).deref();
+ | ^^^^^
+ |
+ = note: the method `deref` exists but the following trait bounds were not satisfied:
+ `{integer} : std::ops::Deref`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
+++ /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(inner_deref)]
-
-fn main() {
- let _result = &Some(42).deref();
-//~^ ERROR no method named `deref` found for type `std::option::Option<{integer}>`
-}
+++ /dev/null
-error[E0599]: no method named `deref` found for type `std::option::Option<{integer}>` in the current scope
- --> $DIR/option_deref.rs:14:29
- |
-LL | let _result = &Some(42).deref();
- | ^^^^^
- |
- = note: the method `deref` exists but the following trait bounds were not satisfied:
- `{integer} : std::ops::Deref`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0599`.
--- /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(inner_deref)]
+
+fn main() {
+ let _result = &Err(41).deref_err();
+//~^ ERROR no method named `deref_err` found
+}
--- /dev/null
+error[E0599]: no method named `deref_err` found for type `std::result::Result<_, {integer}>` in the current scope
+ --> $DIR/result-deref-err.rs:14:28
+ |
+LL | let _result = &Err(41).deref_err();
+ | ^^^^^^^^^
+ |
+ = note: the method `deref_err` exists but the following trait bounds were not satisfied:
+ `{integer} : std::ops::Deref`
+ = help: did you mean `deref_ok`?
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
--- /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(inner_deref)]
+
+fn main() {
+ let _result = &Ok(42).deref_ok();
+//~^ ERROR no method named `deref_ok` found
+}
--- /dev/null
+error[E0599]: no method named `deref_ok` found for type `std::result::Result<{integer}, _>` in the current scope
+ --> $DIR/result-deref-ok.rs:14:27
+ |
+LL | let _result = &Ok(42).deref_ok();
+ | ^^^^^^^^
+ |
+ = note: the method `deref_ok` exists but the following trait bounds were not satisfied:
+ `{integer} : std::ops::Deref`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
--- /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(inner_deref)]
+
+fn main() {
+ let _result = &Ok(42).deref();
+//~^ ERROR no method named `deref` found
+}
--- /dev/null
+error[E0599]: no method named `deref` found for type `std::result::Result<{integer}, _>` in the current scope
+ --> $DIR/result-deref.rs:14:27
+ |
+LL | let _result = &Ok(42).deref();
+ | ^^^^^
+ |
+ = note: the method `deref` exists but the following trait bounds were not satisfied:
+ `{integer} : std::ops::Deref`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
+++ /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(inner_deref)]
-
-fn main() {
- let _result = &Ok(42).deref();
-//~^ ERROR no method named `deref` found
-}
+++ /dev/null
-error[E0599]: no method named `deref` found for type `std::result::Result<{integer}, _>` in the current scope
- --> $DIR/result_deref.rs:14:27
- |
-LL | let _result = &Ok(42).deref();
- | ^^^^^
- |
- = note: the method `deref` exists but the following trait bounds were not satisfied:
- `{integer} : std::ops::Deref`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0599`.
+++ /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(inner_deref)]
-
-fn main() {
- let _result = &Err(41).deref_err();
-//~^ ERROR no method named `deref_err` found
-}
+++ /dev/null
-error[E0599]: no method named `deref_err` found for type `std::result::Result<_, {integer}>` in the current scope
- --> $DIR/result_deref_err.rs:14:28
- |
-LL | let _result = &Err(41).deref_err();
- | ^^^^^^^^^
- |
- = note: the method `deref_err` exists but the following trait bounds were not satisfied:
- `{integer} : std::ops::Deref`
- = help: did you mean `deref_ok`?
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0599`.
+++ /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(inner_deref)]
-
-fn main() {
- let _result = &Ok(42).deref_ok();
-//~^ ERROR no method named `deref_ok` found
-}
+++ /dev/null
-error[E0599]: no method named `deref_ok` found for type `std::result::Result<{integer}, _>` in the current scope
- --> $DIR/result_deref_ok.rs:14:27
- |
-LL | let _result = &Ok(42).deref_ok();
- | ^^^^^^^^
- |
- = note: the method `deref_ok` exists but the following trait bounds were not satisfied:
- `{integer} : std::ops::Deref`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0599`.
--- /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.
+
+fn main(){
+ if i in 1..10 {
+ break;
+ }
+}
--- /dev/null
+error: expected `{`, found keyword `in`
+ --> $DIR/issue-51602.rs:12:10
+ |
+LL | if i in 1..10 {
+ | -- ^^ expected `{`
+ | |
+ | this `if` statement has a condition, but no block
+
+error: aborting due to previous error
+
|
LL | let v: Vec<&str> = line.split_whitespace().collect();
| ^^^^ borrowed value does not live long enough
-LL | //~^ ERROR `line` does not live long enough
-LL | println!("accumulator before add_assign {:?}", acc.map);
- | ------- borrow used here, in later iteration of loop
+...
+LL | acc += cnt2;
+ | --- borrow used here, in later iteration of loop
...
LL | }
| - `line` dropped here while still borrowed
for line in vec!["123456789".to_string(), "12345678".to_string()] {
let v: Vec<&str> = line.split_whitespace().collect();
//~^ ERROR `line` does not live long enough
- println!("accumulator before add_assign {:?}", acc.map);
+ // println!("accumulator before add_assign {:?}", acc.map);
let mut map = HashMap::new();
for str_ref in v {
let e = map.entry(str_ref);
}
let cnt2 = Counter{map};
acc += cnt2;
- println!("accumulator after add_assign {:?}", acc.map);
+ // println!("accumulator after add_assign {:?}", acc.map);
// line gets dropped here but references are kept in acc.map
}
}
--- /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.
+enum A {
+ A {
+ foo: usize,
+ }
+}
+
+fn main() {
+ let x = A::A { foo: 3 };
+ match x {
+ A::A { fob } => { println!("{}", fob); }
+ }
+}
--- /dev/null
+error[E0026]: variant `A::A` does not have a field named `fob`
+ --> $DIR/issue-52717.rs:19:12
+ |
+LL | A::A { fob } => { println!("{}", fob); }
+ | ^^^
+ | |
+ | variant `A::A` does not have this field
+ | help: did you mean: `foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0026`.
--- /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.
+
+// Regression test for an NLL-related ICE (#52992) -- computing
+// implied bounds was causing outlives relations that were not
+// properly handled.
+//
+// compile-pass
+
+#![feature(nll)]
+
+fn main() {}
+
+fn fail<'a>() -> Struct<'a, Generic<()>> {
+ Struct(&Generic(()))
+}
+
+struct Struct<'a, T>(&'a T) where
+ T: Trait + 'a,
+ T::AT: 'a; // only fails with this bound
+
+struct Generic<T>(T);
+
+trait Trait {
+ type AT;
+}
+
+impl<T> Trait for Generic<T> {
+ type AT = T; // only fails with a generic AT
+}
--- /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.
+
+struct S;
+
+impl S {
+ fn f() {}
+}
+
+macro_rules! impl_add {
+ ($($n:ident)*) => {
+ $(
+ fn $n() {
+ S::f::<i64>();
+ //~^ ERROR wrong number of type arguments
+ }
+ )*
+ }
+}
+
+impl_add!(a b);
+
+fn main() {}
--- /dev/null
+error[E0107]: wrong number of type arguments: expected 0, found 1
+ --> $DIR/issue-53251.rs:21:24
+ |
+LL | S::f::<i64>();
+ | ^^^ unexpected type argument
+...
+LL | impl_add!(a b);
+ | --------------- in this macro invocation
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
--- /dev/null
+// Copyright 2012-2014 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.
+
+// issue 53300
+
+pub trait A {
+ fn add(&self, b: i32) -> i32;
+}
+
+fn addition() -> Wrapper<impl A> {}
+//~^ ERROR cannot find type `Wrapper` in this scope [E0412]
+
+fn main() {
+ let res = addition();
+}
--- /dev/null
+error[E0412]: cannot find type `Wrapper` in this scope
+ --> $DIR/issue-53300.rs:17:18
+ |
+LL | fn addition() -> Wrapper<impl A> {}
+ | ^^^^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
--- /dev/null
+// Copyright 2012 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-pass
+
+struct Foo {
+ bar: for<'r> Fn(usize, &'r FnMut())
+}
+
+fn main() {
+}
+
--- /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.
+use std::time::{foo, bar, buzz};
+use std::time::{abc, def};
+fn main(){
+ println!("Hello World!");
+}
--- /dev/null
+error[E0432]: unresolved imports `std::time::foo`, `std::time::bar`, `std::time::buzz`
+ --> $DIR/issue-53565.rs:10:17
+ |
+LL | use std::time::{foo, bar, buzz};
+ | ^^^ ^^^ ^^^^ no `buzz` in `time`
+ | | |
+ | | no `bar` in `time`
+ | no `foo` in `time`
+
+error[E0432]: unresolved imports `std::time::abc`, `std::time::def`
+ --> $DIR/issue-53565.rs:11:17
+ |
+LL | use std::time::{abc, def};
+ | ^^^ ^^^ no `def` in `time`
+ | |
+ | no `abc` in `time`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0432`.
--- /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.
+
+// Regression test for an NLL-related ICE (#53568) -- we failed to
+// resolve inference variables in "custom type-ops".
+//
+// compile-pass
+
+#![feature(nll)]
+#![allow(dead_code)]
+
+trait Future {
+ type Item;
+}
+
+impl<F, T> Future for F
+where F: Fn() -> T
+{
+ type Item = T;
+}
+
+trait Connect {}
+
+struct Connector<H> {
+ handler: H,
+}
+
+impl<H, T> Connect for Connector<H>
+where
+ T: 'static,
+ H: Future<Item = T>
+{
+}
+
+struct Client<C> {
+ connector: C,
+}
+
+fn build<C>(_connector: C) -> Client<C> {
+ unimplemented!()
+}
+
+fn client<H>(handler: H) -> Client<impl Connect>
+where H: Fn() + Copy
+{
+ let connector = Connector {
+ handler,
+ };
+ let client = build(connector);
+ client
+}
+
+fn main() { }
+
--- /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.
+fn main() {
+ let items = vec![1, 2, 3];
+ let ref_items: &[i32] = &items;
+ let items_clone: Vec<i32> = ref_items.clone();
+
+ // in that case no suggestion will be triggered
+ let items_clone_2:Vec<i32> = items.clone();
+
+ let s = "hi";
+ let string: String = s.clone();
+
+ // in that case no suggestion will be triggered
+ let s2 = "hi";
+ let string_2: String = s2.to_string();
+}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/issue-53692.rs:13:37
+ |
+LL | let items_clone: Vec<i32> = ref_items.clone();
+ | ^^^^^^^^^^^^^^^^^
+ | |
+ | expected struct `std::vec::Vec`, found &[i32]
+ | help: try using a conversion method: `ref_items.to_vec()`
+ |
+ = note: expected type `std::vec::Vec<i32>`
+ found type `&[i32]`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-53692.rs:19:30
+ |
+LL | let string: String = s.clone();
+ | ^^^^^^^^^
+ | |
+ | expected struct `std::string::String`, found &str
+ | help: try using a conversion method: `s.to_string()`
+ |
+ = note: expected type `std::string::String`
+ found type `&str`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
--- /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.
+enum E {
+ Foo(String, String, String),
+}
+
+struct Bar {
+ a: String,
+ b: String,
+}
+
+fn main() {
+ let bar = Bar { a: "1".to_string(), b: "2".to_string() };
+ match E::Foo("".into(), "".into(), "".into()) {
+ E::Foo(a, b, ref c) => {}
+ }
+ match bar {
+ Bar {a, ref b} => {}
+ }
+}
--- /dev/null
+error[E0009]: cannot bind by-move and by-ref in the same pattern
+ --> $DIR/issue-53840.rs:22:16
+ |
+LL | E::Foo(a, b, ref c) => {}
+ | ^ ^ ----- both by-ref and by-move used
+ | | |
+ | | by-move pattern here
+ | by-move pattern here
+
+error[E0009]: cannot bind by-move and by-ref in the same pattern
+ --> $DIR/issue-53840.rs:25:14
+ |
+LL | Bar {a, ref b} => {}
+ | ^ ----- both by-ref and by-move used
+ | |
+ | by-move pattern here
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0009`.
--- /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.
+
+trait Mirror {
+ type Image;
+ fn coerce(self) -> Self::Image;
+}
+
+impl<T> Mirror for T {
+ type Image = T;
+ fn coerce(self) -> Self { self }
+}
+
+trait Foo<'x, T> {
+ fn foo(self) -> &'x T;
+}
+
+impl<'s, 'x, T: 'x> Foo<'x, T> for &'s T where &'s T: Foo2<'x, T> {
+ fn foo(self) -> &'x T { self.foo2() }
+}
+
+trait Foo2<'x, T> {
+ fn foo2(self) -> &'x T;
+}
+
+// example 1 - fails leak check
+impl<'x> Foo2<'x, u32> for &'x u32
+{
+ fn foo2(self) -> &'x u32 { self }
+}
+
+// example 2 - OK with this issue
+impl<'x, 'a: 'x> Foo2<'x, i32> for &'a i32
+{
+ fn foo2(self) -> &'x i32 { self }
+}
+
+// example 3 - fails due to issue #XYZ + Leak-check
+impl<'x, T> Foo2<'x, u64> for T
+ where T: Mirror<Image=&'x u64>
+{
+ fn foo2(self) -> &'x u64 { self.coerce() }
+}
+
+// example 4 - fails due to issue #XYZ
+impl<'x, 'a: 'x, T> Foo2<'x, i64> for T
+ where T: Mirror<Image=&'a i64>
+{
+ fn foo2(self) -> &'x i64 { self.coerce() }
+}
+
+
+trait RefFoo<T> {
+ fn ref_foo(&self) -> &'static T;
+}
+
+impl<T> RefFoo<T> for T where for<'a> &'a T: Foo<'static, T> {
+ fn ref_foo(&self) -> &'static T {
+ self.foo()
+ }
+}
+
+
+fn coerce_lifetime1(a: &u32) -> &'static u32
+{
+ <u32 as RefFoo<u32>>::ref_foo(a)
+ //~^ ERROR the trait bound `for<'a> &'a u32: Foo2<'_, u32>` is not satisfied
+}
+
+fn coerce_lifetime2(a: &i32) -> &'static i32
+{
+ <i32 as RefFoo<i32>>::ref_foo(a)
+ //~^ ERROR the requirement `for<'a> 'a : ` is not satisfied
+}
+
+fn coerce_lifetime3(a: &u64) -> &'static u64
+{
+ <u64 as RefFoo<u64>>::ref_foo(a)
+ //~^ ERROR type mismatch resolving `for<'a> <&'a u64 as Mirror>::Image == &u64`
+}
+
+fn coerce_lifetime4(a: &i64) -> &'static i64
+{
+ <i64 as RefFoo<i64>>::ref_foo(a)
+ //~^ ERROR type mismatch resolving `for<'a> <&'a i64 as Mirror>::Image == &i64`
+}
+
+fn main() {}
--- /dev/null
+error[E0277]: the trait bound `for<'a> &'a u32: Foo2<'_, u32>` is not satisfied
+ --> $DIR/issue-54302-cases.rs:73:5
+ |
+LL | <u32 as RefFoo<u32>>::ref_foo(a)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Foo2<'_, u32>` is not implemented for `&'a u32`
+ |
+ = help: the following implementations were found:
+ <&'x u32 as Foo2<'x, u32>>
+ = note: required because of the requirements on the impl of `for<'a> Foo<'static, u32>` for `&'a u32`
+ = note: required because of the requirements on the impl of `RefFoo<u32>` for `u32`
+note: required by `RefFoo::ref_foo`
+ --> $DIR/issue-54302-cases.rs:61:5
+ |
+LL | fn ref_foo(&self) -> &'static T;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0279]: the requirement `for<'a> 'a : ` is not satisfied (`expected bound lifetime parameter 'a, found concrete lifetime`)
+ --> $DIR/issue-54302-cases.rs:79:5
+ |
+LL | <i32 as RefFoo<i32>>::ref_foo(a)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: required because of the requirements on the impl of `for<'a> Foo2<'_, i32>` for `&'a i32`
+ = note: required because of the requirements on the impl of `for<'a> Foo<'static, i32>` for `&'a i32`
+ = note: required because of the requirements on the impl of `RefFoo<i32>` for `i32`
+note: required by `RefFoo::ref_foo`
+ --> $DIR/issue-54302-cases.rs:61:5
+ |
+LL | fn ref_foo(&self) -> &'static T;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0271]: type mismatch resolving `for<'a> <&'a u64 as Mirror>::Image == &u64`
+ --> $DIR/issue-54302-cases.rs:85:5
+ |
+LL | <u64 as RefFoo<u64>>::ref_foo(a)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'a, found concrete lifetime
+ |
+ = note: required because of the requirements on the impl of `for<'a> Foo2<'_, u64>` for `&'a u64`
+ = note: required because of the requirements on the impl of `for<'a> Foo<'static, u64>` for `&'a u64`
+ = note: required because of the requirements on the impl of `RefFoo<u64>` for `u64`
+note: required by `RefFoo::ref_foo`
+ --> $DIR/issue-54302-cases.rs:61:5
+ |
+LL | fn ref_foo(&self) -> &'static T;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0271]: type mismatch resolving `for<'a> <&'a i64 as Mirror>::Image == &i64`
+ --> $DIR/issue-54302-cases.rs:91:5
+ |
+LL | <i64 as RefFoo<i64>>::ref_foo(a)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'a, found concrete lifetime
+ |
+ = note: required because of the requirements on the impl of `for<'a> Foo2<'_, i64>` for `&'a i64`
+ = note: required because of the requirements on the impl of `for<'a> Foo<'static, i64>` for `&'a i64`
+ = note: required because of the requirements on the impl of `RefFoo<i64>` for `i64`
+note: required by `RefFoo::ref_foo`
+ --> $DIR/issue-54302-cases.rs:61:5
+ |
+LL | fn ref_foo(&self) -> &'static T;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
+Some errors occurred: E0271, E0277, E0279.
+For more information about an error, try `rustc --explain E0271`.
--- /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.
+
+trait Deserialize<'de> {}
+
+trait DeserializeOwned: for<'de> Deserialize<'de> {}
+impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
+
+// Based on this impl, `&'static str` only implements Deserialize<'static>.
+// It does not implement for<'de> Deserialize<'de>.
+impl<'de: 'a, 'a> Deserialize<'de> for &'a str {}
+
+fn main() {
+ // Then why does it implement DeserializeOwned? This compiles.
+ fn assert_deserialize_owned<T: DeserializeOwned>() {}
+ assert_deserialize_owned::<&'static str>();
+ //~^ ERROR the requirement `for<'de> 'de : ` is not satisfied
+
+ // It correctly does not implement for<'de> Deserialize<'de>.
+ //fn assert_hrtb<T: for<'de> Deserialize<'de>>() {}
+ //assert_hrtb::<&'static str>();
+}
--- /dev/null
+error[E0279]: the requirement `for<'de> 'de : ` is not satisfied (`expected bound lifetime parameter 'de, found concrete lifetime`)
+ --> $DIR/issue-54302.rs:23:5
+ |
+LL | assert_deserialize_owned::<&'static str>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: required because of the requirements on the impl of `for<'de> Deserialize<'de>` for `&'static str`
+ = note: required because of the requirements on the impl of `DeserializeOwned` for `&'static str`
+note: required by `main::assert_deserialize_owned`
+ --> $DIR/issue-54302.rs:22:5
+ |
+LL | fn assert_deserialize_owned<T: DeserializeOwned>() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0279`.
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-//aux-build:issue_5844_aux.rs
+//aux-build:issue-5844-aux.rs
extern crate issue_5844_aux;
+++ /dev/null
-// Copyright 2016 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.
-
-// ignore-tidy-linelength
-
-#![feature(const_fn)]
-
-const bad : u32 = {
- {
- 5;
- //~^ ERROR statements in constants are unstable
- 0
- }
-};
-
-const bad_two : u32 = {
- {
- invalid();
- //~^ ERROR statements in constants are unstable
- //~^^ ERROR: calls in constants are limited to constant functions, tuple structs and tuple variants
- 0
- }
-};
-
-const bad_three : u32 = {
- {
- valid();
- //~^ ERROR statements in constants are unstable
- 0
- }
-};
-
-static bad_four : u32 = {
- {
- 5;
- //~^ ERROR statements in statics are unstable
- 0
- }
-};
-
-static bad_five : u32 = {
- {
- invalid();
- //~^ ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants
- //~| ERROR statements in statics are unstable
- 0
- }
-};
-
-static bad_six : u32 = {
- {
- valid();
- //~^ ERROR statements in statics are unstable
- 0
- }
-};
-
-static mut bad_seven : u32 = {
- {
- 5;
- //~^ ERROR statements in statics are unstable
- 0
- }
-};
-
-static mut bad_eight : u32 = {
- {
- invalid();
- //~^ ERROR statements in statics are unstable
- //~| ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants
- 0
- }
-};
-
-static mut bad_nine : u32 = {
- {
- valid();
- //~^ ERROR statements in statics are unstable
- 0
- }
-};
-
-
-fn invalid() {}
-const fn valid() {}
-
-fn main() {}
+++ /dev/null
-error[E0658]: statements in constants are unstable (see issue #48821)
- --> $DIR/issue32829.rs:17:9
- |
-LL | 5;
- | ^
- |
- = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
- --> $DIR/issue32829.rs:25:9
- |
-LL | invalid();
- | ^^^^^^^^^
-
-error[E0658]: statements in constants are unstable (see issue #48821)
- --> $DIR/issue32829.rs:25:9
- |
-LL | invalid();
- | ^^^^^^^^^
- |
- = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in constants are unstable (see issue #48821)
- --> $DIR/issue32829.rs:34:9
- |
-LL | valid();
- | ^^^^^^^
- |
- = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in statics are unstable (see issue #48821)
- --> $DIR/issue32829.rs:42:9
- |
-LL | 5;
- | ^
- |
- = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
- --> $DIR/issue32829.rs:50:9
- |
-LL | invalid();
- | ^^^^^^^^^
-
-error[E0658]: statements in statics are unstable (see issue #48821)
- --> $DIR/issue32829.rs:50:9
- |
-LL | invalid();
- | ^^^^^^^^^
- |
- = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in statics are unstable (see issue #48821)
- --> $DIR/issue32829.rs:59:9
- |
-LL | valid();
- | ^^^^^^^
- |
- = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in statics are unstable (see issue #48821)
- --> $DIR/issue32829.rs:67:9
- |
-LL | 5;
- | ^
- |
- = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
- --> $DIR/issue32829.rs:75:9
- |
-LL | invalid();
- | ^^^^^^^^^
-
-error[E0658]: statements in statics are unstable (see issue #48821)
- --> $DIR/issue32829.rs:75:9
- |
-LL | invalid();
- | ^^^^^^^^^
- |
- = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in statics are unstable (see issue #48821)
- --> $DIR/issue32829.rs:84:9
- |
-LL | valid();
- | ^^^^^^^
- |
- = help: add #![feature(const_let)] to the crate attributes to enable
-
-error: aborting due to 12 previous errors
-
-Some errors occurred: E0015, E0658.
-For more information about an error, try `rustc --explain E0015`.
--> $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-pass
+// compile-flags: -Wunused
+
+// make sure write!() can't hide its unused Result
+
+fn main() {
+ use std::fmt::Write;
+ let mut example = String::new();
+ write!(&mut example, "{}", 42); //~WARN must be used
+}
+
--- /dev/null
+warning: unused `std::result::Result` that must be used
+ --> $DIR/must-use-in-macro-55516.rs:19:5
+ |
+LL | write!(&mut example, "{}", 42); //~WARN must be used
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `-W unused-must-use` implied by `-W unused`
+ = note: this `Result` may be an `Err` variant, which should be handled
+ = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+++ /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
#![crate_name="foo"]
#![allow(dead_code)]
-// compile-flags: -Z print-fuel=foo
+// (#55495: The --error-format is to sidestep an issue in our test harness)
+// compile-flags: --error-format human -Z print-fuel=foo
// compile-pass
struct S1(u8, u16, u8);
--- /dev/null
+Fuel used by foo: 3
+++ /dev/null
-Fuel used by foo: 3
LL | &mut x.y //~ ERROR cannot borrow
| ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+error[E0499]: cannot borrow `*x` as mutable more than once at a time
+ --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:88:19
+ |
+LL | let _x = &mut x.x;
+ | - first mutable borrow occurs here
+LL | let _y = &mut x.y; //~ ERROR cannot borrow
+ | ^ second mutable borrow occurs here
+LL | use_mut(_x);
+ | -- first borrow later used here
+
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:98:5
|
LL | x.y = 3; //~ ERROR cannot borrow
| ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+error[E0499]: cannot borrow `*x` as mutable more than once at a time
+ --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:111:5
+ |
+LL | let _p: &mut Point = &mut **x;
+ | -- first mutable borrow occurs here
+LL | x.y = 3; //~ ERROR cannot borrow
+ | ^ second mutable borrow occurs here
+LL | use_mut(_p);
+ | -- first borrow later used here
+
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:119:5
|
LL | *x.y_mut() = 3; //~ ERROR cannot borrow
| ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
-error: aborting due to 8 previous errors
+error: aborting due to 10 previous errors
-For more information about this error, try `rustc --explain E0596`.
+Some errors occurred: E0499, E0596.
+For more information about an error, try `rustc --explain E0499`.
let _x = &mut x.x;
let _y = &mut x.y; //~ ERROR cannot borrow
+ use_mut(_x);
}
-
fn deref_extend_mut_field4<'a>(x: &'a mut Own<Point>) {
let p = &mut **x;
let _x = &mut p.x;
fn assign_field4<'a>(x: &'a mut Own<Point>) {
let _p: &mut Point = &mut **x;
x.y = 3; //~ ERROR cannot borrow
+ use_mut(_p);
}
-
fn deref_imm_method(x: Own<Point>) {
let __isize = x.get();
}
}
pub fn main() {}
+
+fn use_mut<T>(_: &mut T) {}
| - first mutable borrow occurs here
LL | let _y = &mut x.y; //~ ERROR cannot borrow
| ^ second mutable borrow occurs here
+LL | use_mut(_x);
LL | }
| - first borrow ends here
| -- first mutable borrow occurs here
LL | x.y = 3; //~ ERROR cannot borrow
| ^ second mutable borrow occurs here
+LL | use_mut(_p);
LL | }
| - first borrow ends here
--> $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
|
= note: move occurs because `x` has type `T`, which does not implement the `Copy` trait
+error[E0505]: cannot move out of `x` because it is borrowed
+ --> $DIR/unop-move-semantics.rs:25:6
+ |
+LL | let m = &x;
+ | -- borrow of `x` occurs here
+...
+LL | !x; //~ ERROR: cannot move out of `x` because it is borrowed
+ | ^ move out of `x` occurs here
+...
+LL | use_mut(n); use_imm(m);
+ | - borrow later used here
+
+error[E0505]: cannot move out of `y` because it is borrowed
+ --> $DIR/unop-move-semantics.rs:27:6
+ |
+LL | let n = &mut y;
+ | ------ borrow of `y` occurs here
+...
+LL | !y; //~ ERROR: cannot move out of `y` because it is borrowed
+ | ^ move out of `y` occurs here
+LL | use_mut(n); use_imm(m);
+ | - borrow later used here
+
error[E0507]: cannot move out of borrowed content
--> $DIR/unop-move-semantics.rs:34:6
|
LL | !*n; //~ ERROR: cannot move out of borrowed content
| ^^ cannot move out of borrowed content
-error: aborting due to 3 previous errors
+error: aborting due to 5 previous errors
-Some errors occurred: E0382, E0507.
+Some errors occurred: E0382, E0505, E0507.
For more information about an error, try `rustc --explain E0382`.
!x; //~ ERROR: cannot move out of `x` because it is borrowed
!y; //~ ERROR: cannot move out of `y` because it is borrowed
+ use_mut(n); use_imm(m);
}
-
fn illegal_dereference<T: Not<Output=T>>(mut x: T, y: T) {
let m = &mut x;
let n = &y;
!*m; //~ ERROR: cannot move out of borrowed content
!*n; //~ ERROR: cannot move out of borrowed content
+ use_imm(n); use_mut(m);
}
-
fn main() {}
+
+fn use_mut<T>(_: &mut T) { }
+fn use_imm<T>(_: &T) { }
"aarch64-apple-ios",
"aarch64-fuchsia",
"aarch64-linux-android",
+ "aarch64-pc-windows-msvc",
"aarch64-unknown-cloudabi",
"aarch64-unknown-linux-gnu",
"aarch64-unknown-linux-musl",
-Subproject commit 71ec4ff636b9315cfaadd30e45338a077ed98a9b
+Subproject commit d8b426901a75b1eb975f52b4537f2736f2b94436
-Subproject commit 29bf48582812212450f4caf7da1af3f18c52bfef
+Subproject commit fdea743be550ed8d7b61b2c908944cdd1290a6ad