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")
--- /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
# except according to those terms.
import gdb
-import re
import sys
import debugger_pretty_printers_common as rustpp
#![feature(const_vec_new)]
#![feature(slice_partition_dedup)]
#![feature(maybe_uninit)]
+#![feature(alloc_layout_extra)]
// Allow testing this library
#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error> {
match str::from_utf8(&vec) {
- Ok(..) => Ok(String { vec: vec }),
+ Ok(..) => Ok(String { vec }),
Err(e) => {
Err(FromUtf8Error {
bytes: vec,
/// alignment. In other words, if `K` has size 16, `K.align_to(32)`
/// will *still* have size 16.
///
- /// # Panics
- ///
- /// Panics if the combination of `self.size()` and the given `align`
- /// violates the conditions listed in
+ /// Returns an error if the combination of `self.size()` and the given
+ /// `align` violates the conditions listed in
/// [`Layout::from_size_align`](#method.from_size_align).
- #[unstable(feature = "allocator_api", issue = "32838")]
+ #[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[inline]
- pub fn align_to(&self, align: usize) -> Self {
- Layout::from_size_align(self.size(), cmp::max(self.align(), align)).unwrap()
+ pub fn align_to(&self, align: usize) -> Result<Self, LayoutErr> {
+ Layout::from_size_align(self.size(), cmp::max(self.align(), align))
}
/// Returns the amount of padding we must insert after `self`
/// to be less than or equal to the alignment of the starting
/// address for the whole allocated block of memory. One way to
/// satisfy this constraint is to ensure `align <= self.align()`.
- #[unstable(feature = "allocator_api", issue = "32838")]
+ #[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[inline]
pub fn padding_needed_for(&self, align: usize) -> usize {
let len = self.size();
/// of each element in the array.
///
/// On arithmetic overflow, returns `LayoutErr`.
- #[unstable(feature = "allocator_api", issue = "32838")]
+ #[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[inline]
pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutErr> {
let padded_size = self.size().checked_add(self.padding_needed_for(self.align()))
/// will be properly aligned. Note that the result layout will
/// satisfy the alignment properties of both `self` and `next`.
///
+ /// The resulting layout will be the same as that of a C struct containing
+ /// two fields with the layouts of `self` and `next`, in that order.
+ ///
/// Returns `Some((k, offset))`, where `k` is layout of the concatenated
/// record and `offset` is the relative location, in bytes, of the
/// start of the `next` embedded within the concatenated record
/// (assuming that the record itself starts at offset 0).
///
/// On arithmetic overflow, returns `LayoutErr`.
- #[unstable(feature = "allocator_api", issue = "32838")]
+ #[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[inline]
pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutErr> {
let new_align = cmp::max(self.align(), next.align());
/// aligned.
///
/// On arithmetic overflow, returns `LayoutErr`.
- #[unstable(feature = "allocator_api", issue = "32838")]
+ #[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[inline]
pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutErr> {
let size = self.size().checked_mul(n).ok_or(LayoutErr { private: () })?;
/// padding is inserted, the alignment of `next` is irrelevant,
/// and is not incorporated *at all* into the resulting layout.
///
- /// Returns `(k, offset)`, where `k` is layout of the concatenated
- /// record and `offset` is the relative location, in bytes, of the
- /// start of the `next` embedded within the concatenated record
- /// (assuming that the record itself starts at offset 0).
- ///
- /// (The `offset` is always the same as `self.size()`; we use this
- /// signature out of convenience in matching the signature of
- /// `extend`.)
- ///
/// On arithmetic overflow, returns `LayoutErr`.
- #[unstable(feature = "allocator_api", issue = "32838")]
+ #[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[inline]
- pub fn extend_packed(&self, next: Self) -> Result<(Self, usize), LayoutErr> {
+ pub fn extend_packed(&self, next: Self) -> Result<Self, LayoutErr> {
let new_size = self.size().checked_add(next.size())
.ok_or(LayoutErr { private: () })?;
let layout = Layout::from_size_align(new_size, self.align())?;
- Ok((layout, self.size()))
+ Ok(layout)
}
/// Creates a layout describing the record for a `[T; n]`.
///
/// On arithmetic overflow, returns `LayoutErr`.
- #[unstable(feature = "allocator_api", issue = "32838")]
+ #[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[inline]
pub fn array<T>(n: usize) -> Result<Self, LayoutErr> {
Layout::new::<T>()
///
/// # 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);
/// ```
impl DwarfReader {
pub fn new(ptr: *const u8) -> DwarfReader {
- DwarfReader { ptr: ptr }
+ DwarfReader { ptr }
}
// DWARF streams are packed, so e.g. a u32 would not necessarily be aligned
}
pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
- let panic_ctx = Box::new(PanicData { data: data });
+ let panic_ctx = Box::new(PanicData { data });
let params = [Box::into_raw(panic_ctx) as c::ULONG_PTR];
c::RaiseException(RUST_PANIC,
c::EXCEPTION_NONCONTINUABLE,
self.msg_span_from_early_bound_and_free_regions(region)
}
ty::ReStatic => ("the static lifetime".to_owned(), None),
+ ty::ReEmpty => ("an empty lifetime".to_owned(), None),
_ => bug!("{:?}", region),
}
}
impl<'a, 'gcx, 'tcx> OpportunisticTypeResolver<'a, 'gcx, 'tcx> {
pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self {
- OpportunisticTypeResolver { infcx: infcx }
+ OpportunisticTypeResolver { infcx }
}
}
impl<'a, 'gcx, 'tcx> OpportunisticTypeAndRegionResolver<'a, 'gcx, 'tcx> {
pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self {
- OpportunisticTypeAndRegionResolver { infcx: infcx }
+ OpportunisticTypeAndRegionResolver { infcx }
}
}
// Hack: we only need this so that `types_escaping_snapshot`
// can see what has been unified; see the Delegate impl for
// more details.
- self.values.record(Instantiate { vid: vid });
+ self.values.record(Instantiate { vid });
}
/// Creates a new type variable.
value2.min_vid
};
- Ok(RegionVidKey { min_vid: min_vid })
+ Ok(RegionVidKey { min_vid })
}
}
return true;
}
- // (To be) stable attribute for #[lang = "panic_impl"]
- if attr::contains_name(attrs, "panic_implementation") ||
- attr::contains_name(attrs, "panic_handler")
- {
+ // Stable attribute for #[lang = "panic_impl"]
+ if attr::contains_name(attrs, "panic_handler") {
return true;
}
if let Some(value) = attribute.value_str() {
return Some((value, attribute.span));
}
- } else if attribute.check_name("panic_implementation") ||
- attribute.check_name("panic_handler")
- {
+ } else if attribute.check_name("panic_handler") {
return Some((Symbol::intern("panic_impl"), attribute.span))
} else if attribute.check_name("alloc_error_handler") {
return Some((Symbol::intern("oom"), attribute.span))
/// Cross-references the feature names of unstable APIs with enabled
/// features and possibly prints errors.
pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
- let mut checker = Checker { tcx: tcx };
+ let mut checker = Checker { tcx };
tcx.hir.krate().visit_all_item_likes(&mut checker.as_deep_visitor());
}
use ty::layout::{Size, Align, LayoutError};
use rustc_target::spec::abi::Abi;
-use super::Pointer;
+use super::{Pointer, Scalar};
use backtrace::Backtrace;
InvalidMemoryAccess,
InvalidFunctionPointer,
InvalidBool,
- InvalidDiscriminant(u128),
+ InvalidDiscriminant(Scalar),
PointerOutOfBounds {
ptr: Pointer,
access: bool,
}
//// Trunace the given value to the pointer size; also return whether there was an overflow
+ #[inline]
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) {
- // FIXME: is it possible to over/underflow here?
- if i < 0 {
- // trickery to ensure that i64::min_value() works fine
- // this formula only works for true negative values, it panics for zero!
- let n = u64::max_value() - (i as u64) + 1;
- val.overflowing_sub(n)
- } else {
- self.overflowing_offset(val, i as u64)
- }
+ #[inline]
+ 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) }
}
+ #[inline]
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);
+ let (res, over2) = self.truncate_to_ptr(u128::from(res));
(res, over1 || over2)
}
+ #[inline]
fn signed_offset<'tcx>(&self, val: u64, i: i64) -> EvalResult<'tcx, u64> {
- let (res, over) = self.overflowing_signed_offset(val, i as i128);
+ let (res, over) = self.overflowing_signed_offset(val, i128::from(i));
if over { err!(Overflow(mir::BinOp::Add)) } else { Ok(res) }
}
- 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 {
- self.overflowing_signed_offset(val, i as i128).0
+ // Overflow checking only works properly on the range from -u64 to +u64.
+ #[inline]
+ 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
+ // this formula only works for true negative values, it panics for zero!
+ let n = u64::max_value() - (i as u64) + 1;
+ val.overflowing_sub(n)
+ } else {
+ self.overflowing_offset(val, i as u64)
+ }
}
}
Pointer { alloc_id, offset, tag }
}
- pub fn wrapping_signed_offset(self, i: i64, cx: &impl HasDataLayout) -> Self {
- Pointer::new_with_tag(
+ #[inline]
+ 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().wrapping_signed_offset(self.offset.bytes(), i)),
- self.tag,
- )
+ Size::from_bytes(cx.data_layout().offset(self.offset.bytes(), i.bytes())?),
+ self.tag
+ ))
}
- 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);
+ #[inline]
+ 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)
}
+ #[inline(always)]
+ pub fn wrapping_offset(self, i: Size, cx: &impl HasDataLayout) -> Self {
+ self.overflowing_offset(i, cx).0
+ }
+
+ #[inline]
pub fn signed_offset(self, i: i64, cx: &impl HasDataLayout) -> EvalResult<'tcx, Self> {
Ok(Pointer::new_with_tag(
self.alloc_id,
))
}
- 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());
+ #[inline]
+ 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 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())?),
- self.tag
- ))
+ #[inline(always)]
+ pub fn wrapping_signed_offset(self, i: i64, cx: &impl HasDataLayout) -> Self {
+ self.overflowing_signed_offset(i128::from(i), cx).0
}
- #[inline]
+ #[inline(always)]
pub fn erase_tag(self) -> Pointer {
Pointer { alloc_id: self.alloc_id, offset: self.offset, tag: () }
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_lints)]
+use std::fmt;
use ty::layout::{HasDataLayout, Size};
use ty::subst::Substs;
Ptr(Pointer<Tag, Id>),
}
+impl<Tag> fmt::Display for Scalar<Tag> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Scalar::Ptr(_) => write!(f, "a pointer"),
+ Scalar::Bits { bits, .. } => write!(f, "{}", bits),
+ }
+ }
+}
+
impl<'tcx> Scalar<()> {
#[inline]
pub fn with_default_tag<Tag>(self) -> Scalar<Tag>
}
#[inline]
- pub fn ptr_signed_offset(self, i: i64, cx: &impl HasDataLayout) -> EvalResult<'tcx, Self> {
+ 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, dl.pointer_size.bytes());
Ok(Scalar::Bits {
- bits: dl.signed_offset(bits as u64, i)? as u128,
+ bits: dl.offset(bits as u64, i.bytes())? as u128,
size,
})
}
- Scalar::Ptr(ptr) => ptr.signed_offset(i, dl).map(Scalar::Ptr),
+ Scalar::Ptr(ptr) => ptr.offset(i, dl).map(Scalar::Ptr),
}
}
#[inline]
- pub fn ptr_offset(self, i: Size, cx: &impl HasDataLayout) -> EvalResult<'tcx, Self> {
+ pub fn ptr_wrapping_offset(self, i: Size, cx: &impl HasDataLayout) -> Self {
let dl = cx.data_layout();
match self {
Scalar::Bits { bits, size } => {
assert_eq!(size as u64, dl.pointer_size.bytes());
+ Scalar::Bits {
+ bits: dl.overflowing_offset(bits as u64, i.bytes()).0 as u128,
+ size,
+ }
+ }
+ Scalar::Ptr(ptr) => Scalar::Ptr(ptr.wrapping_offset(i, dl)),
+ }
+ }
+
+ #[inline]
+ 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, dl.pointer_size().bytes());
Ok(Scalar::Bits {
- bits: dl.offset(bits as u64, i.bytes())? as u128,
+ bits: dl.signed_offset(bits as u64, i)? as u128,
size,
})
}
- Scalar::Ptr(ptr) => ptr.offset(i, dl).map(Scalar::Ptr),
+ Scalar::Ptr(ptr) => ptr.signed_offset(i, dl).map(Scalar::Ptr),
}
}
Scalar::Bits { bits, size } => {
assert_eq!(size as u64, dl.pointer_size.bytes());
Scalar::Bits {
- bits: dl.wrapping_signed_offset(bits as u64, i) as u128,
+ bits: dl.overflowing_signed_offset(bits as u64, i128::from(i)).0 as u128,
size,
}
}
}
}
+ /// Returns this pointers offset from the allocation base, or from NULL (for
+ /// integer pointers).
+ #[inline]
+ pub fn get_ptr_offset(self, cx: &impl HasDataLayout) -> Size {
+ match self {
+ Scalar::Bits { bits, size } => {
+ assert_eq!(size as u64, cx.pointer_size().bytes());
+ Size::from_bytes(bits as u64)
+ }
+ Scalar::Ptr(ptr) => ptr.offset,
+ }
+ }
+
#[inline]
pub fn is_null_ptr(self, cx: &impl HasDataLayout) -> bool {
match self {
/// 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
use mir::TerminatorKind::*;
let kind = match self.kind {
- Goto { target } => Goto { target: target },
+ Goto { target } => Goto { target },
SwitchInt {
ref discr,
switch_ty,
impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> {
pub fn from_ty(ty: Ty<'tcx>) -> PlaceTy<'tcx> {
- PlaceTy::Ty { ty: ty }
+ PlaceTy::Ty { ty }
}
pub fn to_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
error_format,
&format!(
"optimization level needs to be \
- between 0-3 (instead was `{}`)",
+ between 0-3, s or z (instead was `{}`)",
arg
),
);
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
- }
+ },
_ => {}
}
}
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
},
Err(err) => {
debug!("project_and_unify_type: equating types encountered error {:?}", err);
- Err(MismatchedProjectionTypes { err: err })
+ Err(MismatchedProjectionTypes { err })
}
}
}
_ => bug!(),
};
- Ok(VtableBuiltinData { nested: nested })
+ Ok(VtableBuiltinData { nested })
}
///////////////////////////////////////////////////////////////////////////
if !substs.is_noop() {
types_without_default_bounds.extend(substs.types());
w.push('<');
- w.push_str(&substs.iter().map(|k| k.to_string()).collect::<Vec<_>>().join(", "));
+ w.push_str(&substs.iter()
+ .map(|k| k.to_string())
+ .filter(|k| &k[..] != "'_")
+ .collect::<Vec<_>>().join(", "));
w.push('>');
}
impl<'a, 'gcx, 'tcx> Match<'a, 'gcx, 'tcx> {
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Match<'a, 'gcx, 'tcx> {
- Match { tcx: tcx }
+ Match { tcx }
}
}
}
fn has_type_flags(&self, flags: TypeFlags) -> bool {
- self.visit_with(&mut HasTypeFlagsVisitor { flags: flags })
+ self.visit_with(&mut HasTypeFlagsVisitor { flags })
}
fn has_projections(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_PROJECTION)
.map(|&(cnum, ..)| cnum)
.max()
.unwrap_or(0) + 1;
- let mut map = IndexVec::new();
- map.resize(map_size as usize, None);
+ let mut map = IndexVec::from_elem_n(None, map_size as usize);
for &(prev_cnum, ref crate_name, crate_disambiguator) in prev_cnums {
let key = (crate_name.clone(), crate_disambiguator);
// ...and then memcpy it to the intended destination.
base::call_memcpy(bx,
bx.pointercast(dst.llval, Type::i8p(cx)),
+ self.layout.align,
bx.pointercast(llscratch, Type::i8p(cx)),
+ scratch_align,
C_usize(cx, self.layout.size.bytes()),
- self.layout.align.min(scratch_align),
MemFlags::empty());
bx.lifetime_end(llscratch, scratch_size);
}
});
+ // 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());
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 = 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);
use attributes;
use builder::{Builder, MemFlags};
use callee;
-use common::{C_bool, C_bytes_in_context, C_i32, C_usize};
+use common::{C_bool, C_bytes_in_context, C_usize};
use rustc_mir::monomorphize::item::DefPathBasedNames;
use common::{C_struct_in_context, C_array, val_ty};
use consts;
use std::any::Any;
use std::cmp;
use std::ffi::CString;
-use std::i32;
use std::ops::{Deref, DerefMut};
use std::sync::mpsc;
use std::time::{Instant, Duration};
}
if src_f.layout.ty == dst_f.layout.ty {
- memcpy_ty(bx, dst_f.llval, src_f.llval, src_f.layout,
- src_f.align.min(dst_f.align), MemFlags::empty());
+ memcpy_ty(bx, dst_f.llval, dst_f.align, src_f.llval, src_f.align,
+ src_f.layout, MemFlags::empty());
} else {
coerce_unsized_into(bx, src_f, dst_f);
}
pub fn call_memcpy(
bx: &Builder<'_, 'll, '_>,
dst: &'ll Value,
+ dst_align: Align,
src: &'ll Value,
+ src_align: Align,
n_bytes: &'ll Value,
- align: Align,
flags: MemFlags,
) {
if flags.contains(MemFlags::NONTEMPORAL) {
// HACK(nox): This is inefficient but there is no nontemporal memcpy.
- let val = bx.load(src, align);
+ let val = bx.load(src, src_align);
let ptr = bx.pointercast(dst, val_ty(val).ptr_to());
- bx.store_with_flags(val, ptr, align, flags);
+ bx.store_with_flags(val, ptr, dst_align, flags);
return;
}
let cx = bx.cx;
- let ptr_width = &cx.sess().target.target.target_pointer_width;
- let key = format!("llvm.memcpy.p0i8.p0i8.i{}", ptr_width);
- let memcpy = cx.get_intrinsic(&key);
let src_ptr = bx.pointercast(src, Type::i8p(cx));
let dst_ptr = bx.pointercast(dst, Type::i8p(cx));
let size = bx.intcast(n_bytes, cx.isize_ty, false);
- let align = C_i32(cx, align.abi() as i32);
- let volatile = C_bool(cx, flags.contains(MemFlags::VOLATILE));
- bx.call(memcpy, &[dst_ptr, src_ptr, size, align, volatile], None);
+ let volatile = flags.contains(MemFlags::VOLATILE);
+ bx.memcpy(dst_ptr, dst_align.abi(), src_ptr, src_align.abi(), size, volatile);
}
pub fn memcpy_ty(
bx: &Builder<'_, 'll, 'tcx>,
dst: &'ll Value,
+ dst_align: Align,
src: &'ll Value,
+ src_align: Align,
layout: TyLayout<'tcx>,
- align: Align,
flags: MemFlags,
) {
let size = layout.size.bytes();
return;
}
- call_memcpy(bx, dst, src, C_usize(bx.cx, size), align, flags);
+ call_memcpy(bx, dst, dst_align, src, src_align, C_usize(bx.cx, size), flags);
}
pub fn call_memset(
}
}
+ pub fn memcpy(&self, dst: &'ll Value, dst_align: u64,
+ src: &'ll Value, src_align: u64,
+ size: &'ll Value, is_volatile: bool) -> &'ll Value {
+ unsafe {
+ llvm::LLVMRustBuildMemCpy(self.llbuilder, dst, dst_align as c_uint,
+ src, src_align as c_uint, size, is_volatile)
+ }
+ }
+
+ pub fn memmove(&self, dst: &'ll Value, dst_align: u64,
+ src: &'ll Value, src_align: u64,
+ size: &'ll Value, is_volatile: bool) -> &'ll Value {
+ unsafe {
+ llvm::LLVMRustBuildMemMove(self.llbuilder, dst, dst_align as c_uint,
+ src, src_align as c_uint, size, is_volatile)
+ }
+ }
+
pub fn minnum(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("minnum");
unsafe {
let t_v4f64 = Type::vector(t_f64, 4);
let t_v8f64 = Type::vector(t_f64, 8);
- ifn!("llvm.memcpy.p0i8.p0i8.i16", fn(i8p, i8p, t_i16, t_i32, i1) -> void);
- ifn!("llvm.memcpy.p0i8.p0i8.i32", fn(i8p, i8p, t_i32, t_i32, i1) -> void);
- ifn!("llvm.memcpy.p0i8.p0i8.i64", fn(i8p, i8p, t_i64, t_i32, i1) -> void);
- ifn!("llvm.memmove.p0i8.p0i8.i16", fn(i8p, i8p, t_i16, t_i32, i1) -> void);
- ifn!("llvm.memmove.p0i8.p0i8.i32", fn(i8p, i8p, t_i32, t_i32, i1) -> void);
- ifn!("llvm.memmove.p0i8.p0i8.i64", fn(i8p, i8p, t_i64, t_i32, i1) -> void);
ifn!("llvm.memset.p0i8.i16", fn(i8p, t_i8, t_i16, t_i32, i1) -> void);
ifn!("llvm.memset.p0i8.i32", fn(i8p, t_i8, t_i32, t_i32, i1) -> void);
ifn!("llvm.memset.p0i8.i64", fn(i8p, t_i8, t_i64, t_i32, i1) -> void);
use type_::Type;
use type_of::LayoutLlvmExt;
use rustc::ty::{self, Ty};
-use rustc::ty::layout::{HasDataLayout, LayoutOf};
+use rustc::ty::layout::LayoutOf;
use rustc::hir;
use syntax::ast;
use syntax::symbol::Symbol;
let cx = bx.cx;
let (size, align) = cx.size_and_align_of(ty);
let size = C_usize(cx, size.bytes());
- let align = C_i32(cx, align.abi() as i32);
-
- let operation = if allow_overlap {
- "memmove"
- } else {
- "memcpy"
- };
-
- let name = format!("llvm.{}.p0i8.p0i8.i{}", operation,
- cx.data_layout().pointer_size.bits());
-
+ let align = align.abi();
let dst_ptr = bx.pointercast(dst, Type::i8p(cx));
let src_ptr = bx.pointercast(src, Type::i8p(cx));
- let llfn = cx.get_intrinsic(&name);
-
- bx.call(llfn,
- &[dst_ptr,
- src_ptr,
- bx.mul(size, count),
- align,
- C_bool(cx, volatile)],
- None)
+ if allow_overlap {
+ bx.memmove(dst_ptr, align, src_ptr, align, bx.mul(size, count), volatile)
+ } else {
+ bx.memcpy(dst_ptr, align, src_ptr, align, bx.mul(size, count), volatile)
+ }
}
fn memset_intrinsic(
Bundle: Option<&OperandBundleDef<'a>>,
Name: *const c_char)
-> &'a Value;
+ pub fn LLVMRustBuildMemCpy(B: &Builder<'a>,
+ Dst: &'a Value,
+ DstAlign: c_uint,
+ Src: &'a Value,
+ SrcAlign: c_uint,
+ Size: &'a Value,
+ IsVolatile: bool)
+ -> &'a Value;
+ pub fn LLVMRustBuildMemMove(B: &Builder<'a>,
+ Dst: &'a Value,
+ DstAlign: c_uint,
+ Src: &'a Value,
+ SrcAlign: c_uint,
+ Size: &'a Value,
+ IsVolatile: bool)
+ -> &'a Value;
pub fn LLVMBuildSelect(B: &Builder<'a>,
If: &'a Value,
Then: &'a Value,
pub fn new(llmb: &'static mut MemoryBuffer) -> Option<ObjectFile> {
unsafe {
let llof = LLVMCreateObjectFile(llmb)?;
- Some(ObjectFile { llof: llof })
+ Some(ObjectFile { llof })
}
}
}
funclet, succ, kind);
match kind {
CleanupKind::NotCleanup => {
- result[succ] = CleanupKind::Internal { funclet: funclet };
+ result[succ] = CleanupKind::Internal { funclet };
}
CleanupKind::Funclet => {
if funclet != succ {
// have scary latent bugs around.
let scratch = PlaceRef::alloca(bx, arg.layout, "arg");
- base::memcpy_ty(bx, scratch.llval, llval, op.layout, align, MemFlags::empty());
+ base::memcpy_ty(bx, scratch.llval, scratch.align, llval, align,
+ op.layout, MemFlags::empty());
(scratch.llval, scratch.align, true)
} else {
(llval, align, true)
}
match self {
OperandValue::Ref(r, None, source_align) => {
- base::memcpy_ty(bx, dest.llval, r, dest.layout,
- source_align.min(dest.align), flags)
+ base::memcpy_ty(bx, dest.llval, dest.align, r, source_align,
+ dest.layout, flags)
}
OperandValue::Ref(_, Some(_), _) => {
bug!("cannot directly store unsized values");
// Allocate an appropriate region on the stack, and copy the value into it
let (llsize, _) = glue::size_and_align_of_dst(&bx, unsized_ty, Some(llextra));
let lldst = bx.array_alloca(Type::i8(bx.cx), llsize, "unsized_tmp", max_align);
- base::call_memcpy(&bx, lldst, llptr, llsize, min_align, flags);
+ base::call_memcpy(&bx, lldst, max_align, llptr, min_align, llsize, flags);
// Store the allocated region and the extra to the indirect place.
let indirect_operand = OperandValue::Pair(lldst, llextra);
}
tcx.dep_graph.with_ignore(|| {
- let mut visitor = SymbolNamesTest { tcx: tcx };
+ let mut visitor = SymbolNamesTest { tcx };
tcx.hir.krate().visit_all_item_likes(&mut visitor);
})
}
unsafe { libc::close(fd); }
Err(err)
} else {
- Ok(Lock { fd: fd })
+ Ok(Lock { fd })
}
}
}
#[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"]
/// compute the SVH from some HIR, you want the `calculate_svh`
/// function found in `librustc_incremental`.
pub fn new(hash: u64) -> Svh {
- Svh { hash: hash }
+ Svh { hash }
}
pub fn as_u64(&self) -> u64 {
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());
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
fn check_foreign_item(&mut self, cx: &LateContext, it: &hir::ForeignItem) {
- let mut vis = ImproperCTypesVisitor { cx: cx };
+ let mut vis = ImproperCTypesVisitor { cx };
let abi = cx.tcx.hir.get_foreign_abi(it.id);
if abi != Abi::RustIntrinsic && abi != Abi::PlatformIntrinsic {
match it.node {
index.record(DefId::local(CRATE_DEF_INDEX),
IsolatedEncoder::encode_info_for_mod,
FromId(CRATE_NODE_ID, (&krate.module, &krate.attrs, &vis)));
- let mut visitor = EncodeVisitor { index: index };
+ let mut visitor = EncodeVisitor { index };
krate.visit_all_item_likes(&mut visitor.as_deep_visitor());
for macro_def in &krate.exported_macros {
visitor.visit_macro_def(macro_def);
use rustc_data_structures::indexed_vec::IndexVec;
use rustc_data_structures::bit_set::BitSet;
use std::fmt;
-use std::hash::Hash;
use std::ops::Index;
crate struct BorrowSet<'tcx> {
self.insert_as_pending_if_two_phase(location, &assigned_place, region, kind, idx);
- insert(&mut self.region_map, ®ion, idx);
+ self.region_map.entry(region).or_default().insert(idx);
if let Some(local) = borrowed_place.root_local() {
- insert(&mut self.local_map, &local, idx);
+ self.local_map.entry(local).or_default().insert(idx);
}
}
- return self.super_assign(block, assigned_place, rvalue, location);
-
- fn insert<'a, K, V>(map: &'a mut FxHashMap<K, FxHashSet<V>>, k: &K, v: V)
- where
- K: Clone + Eq + Hash,
- V: Eq + Hash,
- {
- map.entry(k.clone()).or_default().insert(v);
- }
+ self.super_assign(block, assigned_place, rvalue, location)
}
fn visit_place(
}
let scope = &self.scopes[len - scope_count];
self.cfg.terminate(block, scope.source_info(span),
- TerminatorKind::Goto { target: target });
+ TerminatorKind::Goto { target });
}
/// Creates a path that performs all required cleanup for dropping a generator.
} else {
let block = cfg.start_new_cleanup_block();
cfg.push_end_region(tcx, block, source_info(span), scope.region_scope);
- cfg.terminate(block, source_info(span), TerminatorKind::Goto { target: target });
+ cfg.terminate(block, source_info(span), TerminatorKind::Goto { target });
*cached_block = Some(block);
block
}
let val = (|| {
let op = ecx.const_to_op(constant)?;
let mut ref_tracking = RefTracking::new(op);
- while let Some((op, mut path)) = ref_tracking.todo.pop() {
+ while let Some((op, path)) = ref_tracking.todo.pop() {
ecx.validate_operand(
op,
- &mut path,
+ path,
Some(&mut ref_tracking),
/* const_mode */ true,
)?;
impl<'a, 'tcx: 'a> HaveBeenBorrowedLocals<'a, 'tcx> {
pub fn new(mir: &'a Mir<'tcx>)
-> Self {
- HaveBeenBorrowedLocals { mir: mir }
+ HaveBeenBorrowedLocals { mir }
}
pub fn mir(&self) -> &Mir<'tcx> {
impl<'a, 'tcx: 'a> MaybeStorageLive<'a, 'tcx> {
pub fn new(mir: &'a Mir<'tcx>)
-> Self {
- MaybeStorageLive { mir: mir }
+ MaybeStorageLive { mir }
}
pub fn mir(&self) -> &Mir<'tcx> {
}
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
- tcx.hir.krate().visit_all_item_likes(&mut OuterVisitor { tcx: tcx }.as_deep_visitor());
+ tcx.hir.krate().visit_all_item_likes(&mut OuterVisitor { tcx }.as_deep_visitor());
tcx.sess.abort_if_errors();
}
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
})
.collect();
- PatternKind::Leaf { subpatterns: subpatterns }
+ PatternKind::Leaf { subpatterns }
}
ty::Error => { // Avoid ICE (#50577)
return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) };
subpatterns,
}
} else {
- PatternKind::Leaf { subpatterns: subpatterns }
+ PatternKind::Leaf { subpatterns }
}
}
Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) |
Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) | Def::SelfCtor(..) => {
- PatternKind::Leaf { subpatterns: subpatterns }
+ PatternKind::Leaf { subpatterns }
}
_ => {
// return place is always a local and then this cannot happen.
self.validate_operand(
self.place_to_op(return_place)?,
- &mut vec![],
+ vec![],
None,
/*const_mode*/false,
)?;
"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)?;
use rustc::hir::{self, def_id::DefId};
use rustc::mir;
-use rustc::ty::{self, Ty, layout::{Size, TyLayout}, query::TyCtxtAt};
+use rustc::ty::{self, layout::{Size, TyLayout}, query::TyCtxtAt};
use super::{
Allocation, AllocId, EvalResult, Scalar,
- EvalContext, PlaceTy, OpTy, Pointer, MemPlace, MemoryKind,
+ EvalContext, PlaceTy, MPlaceTy, OpTy, Pointer, MemoryKind,
};
/// Whether this kind of memory is allowed to leak
#[inline]
fn tag_reference(
_ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
- place: MemPlace<Self::PointerTag>,
- _ty: Ty<'tcx>,
- _size: Size,
+ place: MPlaceTy<'tcx, Self::PointerTag>,
_mutability: Option<hir::Mutability>,
- ) -> EvalResult<'tcx, MemPlace<Self::PointerTag>> {
- Ok(place)
+ ) -> EvalResult<'tcx, Scalar<Self::PointerTag>> {
+ Ok(place.ptr)
}
/// Executed when evaluating the `*` operator: Following a reference.
- /// This has the change to adjust the tag. It should not change anything else!
+ /// This has the chance to adjust the tag. It should not change anything else!
/// `mutability` can be `None` in case a raw ptr is being dereferenced.
#[inline]
fn tag_dereference(
_ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
- place: MemPlace<Self::PointerTag>,
- _ty: Ty<'tcx>,
- _size: Size,
+ place: MPlaceTy<'tcx, Self::PointerTag>,
_mutability: Option<hir::Mutability>,
- ) -> EvalResult<'tcx, MemPlace<Self::PointerTag>> {
- Ok(place)
+ ) -> EvalResult<'tcx, Scalar<Self::PointerTag>> {
+ Ok(place.ptr)
}
/// Execute a validation operation
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(())
mod traits;
mod validity;
mod intrinsics;
+mod visitor;
pub use rustc::mir::interpret::*; // have all the `interpret` symbols in one place: here
pub use self::operand::{ScalarMaybeUndef, Immediate, ImmTy, Operand, OpTy};
+pub use self::visitor::ValueVisitor;
+
pub use self::validity::RefTracking;
//! All high-level functions to read from memory work on operands as sources.
use std::convert::TryInto;
+use std::fmt;
use rustc::{mir, ty};
use rustc::ty::layout::{self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt};
}
}
+impl<Tag> fmt::Display for ScalarMaybeUndef<Tag> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ ScalarMaybeUndef::Undef => write!(f, "uninitialized bytes"),
+ ScalarMaybeUndef::Scalar(s) => write!(f, "{}", s),
+ }
+ }
+}
+
impl<'tcx> ScalarMaybeUndef<()> {
#[inline]
pub fn with_default_tag<Tag>(self) -> ScalarMaybeUndef<Tag>
Ok(match rval.layout.variants {
layout::Variants::Single { .. } => bug!(),
layout::Variants::Tagged { .. } => {
+ let bits_discr = match raw_discr.to_bits(discr_val.layout.size) {
+ Ok(raw_discr) => raw_discr,
+ Err(_) => return err!(InvalidDiscriminant(raw_discr.erase_tag())),
+ };
let real_discr = if discr_val.layout.ty.is_signed() {
- let i = raw_discr.to_bits(discr_val.layout.size)? as i128;
+ let i = bits_discr as i128;
// going from layout tag type to typeck discriminant type
// requires first sign extending with the layout discriminant
let shift = 128 - discr_val.layout.size.bits();
let truncatee = sexted as u128;
(truncatee << shift) >> shift
} else {
- raw_discr.to_bits(discr_val.layout.size)?
+ bits_discr
};
// Make sure we catch invalid discriminants
let index = rval.layout.ty
.expect("tagged layout for non adt")
.discriminants(self.tcx.tcx)
.position(|var| var.val == real_discr)
- .ok_or_else(|| EvalErrorKind::InvalidDiscriminant(real_discr))?;
+ .ok_or_else(|| EvalErrorKind::InvalidDiscriminant(raw_discr.erase_tag()))?;
(real_discr, index)
},
layout::Variants::NicheFilling {
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>,
let meta = val.to_meta()?;
let ptr = val.to_scalar_ptr()?;
let mplace = MemPlace { ptr, align, meta };
+ let mut mplace = MPlaceTy { mplace, layout };
// Pointer tag tracking might want to adjust the tag.
- let mplace = if M::ENABLE_PTR_TRACKING_HOOKS {
- let (size, _) = self.size_and_align_of(meta, layout)?
- // for extern types, just cover what we can
- .unwrap_or_else(|| layout.size_and_align());
+ if M::ENABLE_PTR_TRACKING_HOOKS {
let mutbl = match val.layout.ty.sty {
// `builtin_deref` considers boxes immutable, that's useless for our purposes
ty::Ref(_, _, mutbl) => Some(mutbl),
ty::RawPtr(_) => None,
_ => bug!("Unexpected pointer type {}", val.layout.ty.sty),
};
- M::tag_dereference(self, mplace, pointee_type, size, mutbl)?
- } else {
- mplace
- };
- Ok(MPlaceTy { mplace, layout })
+ mplace.mplace.ptr = M::tag_dereference(self, mplace, mutbl)?;
+ }
+ // Done
+ Ok(mplace)
}
/// Turn a mplace into a (thin or fat) pointer, as a reference, pointing to the same space.
/// `mutbl` indicates whether we are create a shared or mutable ref, or a raw pointer (`None`).
pub fn create_ref(
&mut self,
- place: MPlaceTy<'tcx, M::PointerTag>,
+ mut place: MPlaceTy<'tcx, M::PointerTag>,
mutbl: Option<hir::Mutability>,
) -> EvalResult<'tcx, Immediate<M::PointerTag>> {
// Pointer tag tracking might want to adjust the tag
- let place = if M::ENABLE_PTR_TRACKING_HOOKS {
- let (size, _) = self.size_and_align_of_mplace(place)?
- // for extern types, just cover what we can
- .unwrap_or_else(|| place.layout.size_and_align());
- M::tag_reference(self, *place, place.layout.ty, size, mutbl)?
- } else {
- *place
- };
+ if M::ENABLE_PTR_TRACKING_HOOKS {
+ place.mplace.ptr = M::tag_reference(self, place, mutbl)?
+ }
Ok(match place.meta {
None => Immediate::Scalar(place.ptr.into()),
Some(meta) => Immediate::ScalarPair(place.ptr.into(), meta.into()),
/// Get the place of a field inside the place, and also the field's type.
/// Just a convenience function, but used quite a bit.
+ /// This is the only projection that might have a side-effect: We cannot project
+ /// into the field of a local `ScalarPair`, we have to first allocate it.
pub fn place_field(
&mut self,
base: PlaceTy<'tcx, M::PointerTag>,
}
pub fn place_downcast(
- &mut self,
+ &self,
base: PlaceTy<'tcx, M::PointerTag>,
variant: usize,
) -> EvalResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
if M::enforce_validity(self) {
// Data got changed, better make sure it matches the type!
- self.validate_operand(self.place_to_op(dest)?, &mut vec![], None, /*const_mode*/false)?;
+ self.validate_operand(self.place_to_op(dest)?, vec![], None, /*const_mode*/false)?;
}
Ok(())
if M::enforce_validity(self) {
// Data got changed, better make sure it matches the type!
- self.validate_operand(self.place_to_op(dest)?, &mut vec![], None, /*const_mode*/false)?;
+ self.validate_operand(self.place_to_op(dest)?, vec![], None, /*const_mode*/false)?;
}
Ok(())
if M::enforce_validity(self) {
// Data got changed, better make sure it matches the type!
- self.validate_operand(dest.into(), &mut vec![], None, /*const_mode*/false)?;
+ self.validate_operand(dest.into(), vec![], None, /*const_mode*/false)?;
}
Ok(())
use std::fmt::Write;
use std::hash::Hash;
+use std::ops::RangeInclusive;
use syntax_pos::symbol::Symbol;
use rustc::ty::layout::{self, Size, Align, TyLayout, LayoutOf};
};
use super::{
- ImmTy, OpTy, MPlaceTy, Machine, EvalContext, ScalarMaybeUndef
+ OpTy, MPlaceTy, ImmTy, Machine, EvalContext, ValueVisitor
};
macro_rules! validation_failure {
($what:expr, $where:expr, $details:expr) => {{
- let where_ = path_format($where);
+ let where_ = path_format(&$where);
let where_ = if where_.is_empty() {
String::new()
} else {
)))
}};
($what:expr, $where:expr) => {{
- let where_ = path_format($where);
+ let where_ = path_format(&$where);
let where_ = if where_.is_empty() {
String::new()
} else {
TupleElem(usize),
Deref,
Tag,
+ DynDowncast,
}
/// State for tracking recursive validation of references
}
}
-// Adding a Deref and making a copy of the path to be put into the queue
-// always go together. This one does it with only new allocation.
-fn path_clone_and_deref(path: &Vec<PathElem>) -> Vec<PathElem> {
- let mut new_path = Vec::with_capacity(path.len()+1);
- new_path.clone_from(path);
- new_path.push(PathElem::Deref);
- new_path
-}
-
/// Format a path
fn path_format(path: &Vec<PathElem>) -> String {
use self::PathElem::*;
let mut out = String::new();
for elem in path.iter() {
match elem {
- Field(name) => write!(out, ".{}", name).unwrap(),
- ClosureVar(name) => write!(out, ".<closure-var({})>", name).unwrap(),
- TupleElem(idx) => write!(out, ".{}", idx).unwrap(),
- ArrayElem(idx) => write!(out, "[{}]", idx).unwrap(),
+ Field(name) => write!(out, ".{}", name),
+ ClosureVar(name) => write!(out, ".<closure-var({})>", name),
+ TupleElem(idx) => write!(out, ".{}", idx),
+ ArrayElem(idx) => write!(out, "[{}]", idx),
Deref =>
// This does not match Rust syntax, but it is more readable for long paths -- and
// some of the other items here also are not Rust syntax. Actually we can't
// even use the usual syntax because we are just showing the projections,
// not the root.
- write!(out, ".<deref>").unwrap(),
- Tag => write!(out, ".<enum-tag>").unwrap(),
- }
+ write!(out, ".<deref>"),
+ Tag => write!(out, ".<enum-tag>"),
+ DynDowncast => write!(out, ".<dyn-downcast>"),
+ }.unwrap()
}
out
}
-fn scalar_format<Tag>(value: ScalarMaybeUndef<Tag>) -> String {
- match value {
- ScalarMaybeUndef::Undef =>
- "uninitialized bytes".to_owned(),
- ScalarMaybeUndef::Scalar(Scalar::Ptr(_)) =>
- "a pointer".to_owned(),
- ScalarMaybeUndef::Scalar(Scalar::Bits { bits, .. }) =>
- bits.to_string(),
+// Test if a range that wraps at overflow contains `test`
+fn wrapping_range_contains(r: &RangeInclusive<u128>, test: u128) -> bool {
+ let (lo, hi) = r.clone().into_inner();
+ if lo > hi {
+ // Wrapped
+ (..=hi).contains(&test) || (lo..).contains(&test)
+ } else {
+ // Normal
+ r.contains(&test)
}
}
-impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
- /// Make sure that `value` is valid for `ty`, *assuming* `ty` is a primitive type.
- fn validate_primitive_type(
- &self,
- value: ImmTy<'tcx, M::PointerTag>,
- path: &Vec<PathElem>,
- ref_tracking: Option<&mut RefTracking<'tcx, M::PointerTag>>,
- const_mode: bool,
+// Formats such that a sentence like "expected something {}" to mean
+// "expected something <in the given range>" makes sense.
+fn wrapping_range_format(r: &RangeInclusive<u128>, max_hi: u128) -> String {
+ let (lo, hi) = r.clone().into_inner();
+ debug_assert!(hi <= max_hi);
+ if lo > hi {
+ format!("less or equal to {}, or greater or equal to {}", hi, lo)
+ } else {
+ if lo == 0 {
+ debug_assert!(hi < max_hi, "should not be printing if the range covers everything");
+ format!("less or equal to {}", hi)
+ } else if hi == max_hi {
+ format!("greater or equal to {}", lo)
+ } else {
+ format!("in the range {:?}", r)
+ }
+ }
+}
+
+struct ValidityVisitor<'rt, 'a: 'rt, 'mir: 'rt, 'tcx: 'a+'rt+'mir, M: Machine<'a, 'mir, 'tcx>+'rt> {
+ /// The `path` may be pushed to, but the part that is present when a function
+ /// starts must not be changed! `visit_fields` and `visit_array` rely on
+ /// this stack discipline.
+ path: Vec<PathElem>,
+ ref_tracking: Option<&'rt mut RefTracking<'tcx, M::PointerTag>>,
+ const_mode: bool,
+ ecx: &'rt EvalContext<'a, 'mir, 'tcx, M>,
+}
+
+impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> ValidityVisitor<'rt, 'a, 'mir, 'tcx, M> {
+ fn push_aggregate_field_path_elem(
+ &mut self,
+ layout: TyLayout<'tcx>,
+ field: usize,
+ ) {
+ let elem = match layout.ty.sty {
+ // generators and closures.
+ ty::Closure(def_id, _) | ty::Generator(def_id, _, _) => {
+ if let Some(upvar) = self.ecx.tcx.optimized_mir(def_id).upvar_decls.get(field) {
+ PathElem::ClosureVar(upvar.debug_name)
+ } else {
+ // Sometimes the index is beyond the number of freevars (seen
+ // for a generator).
+ PathElem::ClosureVar(Symbol::intern(&field.to_string()))
+ }
+ }
+
+ // tuples
+ ty::Tuple(_) => PathElem::TupleElem(field),
+
+ // enums
+ ty::Adt(def, ..) if def.is_enum() => {
+ // we might be projecting *to* a variant, or to a field *in*a variant.
+ match layout.variants {
+ layout::Variants::Single { index } =>
+ // Inside a variant
+ PathElem::Field(def.variants[index].fields[field].ident.name),
+ _ =>
+ // To a variant
+ PathElem::Field(def.variants[field].name)
+ }
+ }
+
+ // other ADTs
+ ty::Adt(def, _) => PathElem::Field(def.non_enum_variant().fields[field].ident.name),
+
+ // arrays/slices
+ ty::Array(..) | ty::Slice(..) => PathElem::ArrayElem(field),
+
+ // dyn traits
+ ty::Dynamic(..) => PathElem::DynDowncast,
+
+ // nothing else has an aggregate layout
+ _ => bug!("aggregate_field_path_elem: got non-aggregate type {:?}", layout.ty),
+ };
+ self.path.push(elem);
+ }
+}
+
+impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>
+ ValueVisitor<'a, 'mir, 'tcx, M> for ValidityVisitor<'rt, 'a, 'mir, 'tcx, M>
+{
+ type V = OpTy<'tcx, M::PointerTag>;
+
+ #[inline(always)]
+ fn ecx(&self) -> &EvalContext<'a, 'mir, 'tcx, M> {
+ &self.ecx
+ }
+
+ #[inline]
+ fn visit_field(
+ &mut self,
+ old_op: OpTy<'tcx, M::PointerTag>,
+ field: usize,
+ new_op: OpTy<'tcx, M::PointerTag>
) -> EvalResult<'tcx> {
+ // Remember the old state
+ let path_len = self.path.len();
+ // Perform operation
+ self.push_aggregate_field_path_elem(old_op.layout, field);
+ self.visit_value(new_op)?;
+ // Undo changes
+ self.path.truncate(path_len);
+ Ok(())
+ }
+
+ #[inline]
+ fn visit_value(&mut self, op: OpTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
+ {
+ trace!("visit_value: {:?}, {:?}", *op, op.layout);
+ // Translate some possible errors to something nicer.
+ match self.walk_value(op) {
+ Ok(()) => Ok(()),
+ Err(err) => match err.kind {
+ EvalErrorKind::InvalidDiscriminant(val) =>
+ validation_failure!(
+ val, self.path, "a valid enum discriminant"
+ ),
+ EvalErrorKind::ReadPointerAsBytes =>
+ validation_failure!(
+ "a pointer", self.path, "plain bytes"
+ ),
+ _ => Err(err),
+ }
+ }
+ }
+
+ fn visit_primitive(&mut self, value: ImmTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
+ {
// Go over all the primitive types
let ty = value.layout.ty;
match ty.sty {
ty::Bool => {
let value = value.to_scalar_or_undef();
try_validation!(value.to_bool(),
- scalar_format(value), path, "a boolean");
+ value, self.path, "a boolean");
},
ty::Char => {
let value = value.to_scalar_or_undef();
try_validation!(value.to_char(),
- scalar_format(value), path, "a valid unicode codepoint");
+ value, self.path, "a valid unicode codepoint");
},
ty::Float(_) | ty::Int(_) | ty::Uint(_) => {
// NOTE: Keep this in sync with the array optimization for int/float
// types below!
let size = value.layout.size;
let value = value.to_scalar_or_undef();
- if const_mode {
+ if self.const_mode {
// Integers/floats in CTFE: Must be scalar bits, pointers are dangerous
try_validation!(value.to_bits(size),
- scalar_format(value), path, "initialized plain bits");
+ value, self.path, "initialized plain bits");
} else {
// At run-time, for now, we accept *anything* for these types, including
// undef. We should fix that, but let's start low.
// No undef allowed here. Eventually this should be consistent with
// the integer types.
let _ptr = try_validation!(value.to_scalar_ptr(),
- "undefined address in pointer", path);
+ "undefined address in pointer", self.path);
let _meta = try_validation!(value.to_meta(),
- "uninitialized data in fat pointer metadata", path);
+ "uninitialized data in fat pointer metadata", self.path);
}
_ if ty.is_box() || ty.is_region_ptr() => {
// Handle fat pointers.
// Check metadata early, for better diagnostics
let ptr = try_validation!(value.to_scalar_ptr(),
- "undefined address in pointer", path);
+ "undefined address in pointer", self.path);
let meta = try_validation!(value.to_meta(),
- "uninitialized data in fat pointer metadata", path);
- let layout = self.layout_of(value.layout.ty.builtin_deref(true).unwrap().ty)?;
+ "uninitialized data in fat pointer metadata", self.path);
+ let layout = self.ecx.layout_of(value.layout.ty.builtin_deref(true).unwrap().ty)?;
if layout.is_unsized() {
- let tail = self.tcx.struct_tail(layout.ty);
+ let tail = self.ecx.tcx.struct_tail(layout.ty);
match tail.sty {
ty::Dynamic(..) => {
let vtable = try_validation!(meta.unwrap().to_ptr(),
- "non-pointer vtable in fat pointer", path);
- try_validation!(self.read_drop_type_from_vtable(vtable),
- "invalid drop fn in vtable", path);
- try_validation!(self.read_size_and_align_from_vtable(vtable),
- "invalid size or align in vtable", path);
+ "non-pointer vtable in fat pointer", self.path);
+ try_validation!(self.ecx.read_drop_type_from_vtable(vtable),
+ "invalid drop fn in vtable", self.path);
+ try_validation!(self.ecx.read_size_and_align_from_vtable(vtable),
+ "invalid size or align in vtable", self.path);
// FIXME: More checks for the vtable.
}
ty::Slice(..) | ty::Str => {
- try_validation!(meta.unwrap().to_usize(self),
- "non-integer slice length in fat pointer", path);
+ try_validation!(meta.unwrap().to_usize(self.ecx),
+ "non-integer slice length in fat pointer", self.path);
}
ty::Foreign(..) => {
// Unsized, but not fat.
}
}
// Make sure this is non-NULL and aligned
- let (size, align) = self.size_and_align_of(meta, layout)?
+ let (size, align) = self.ecx.size_and_align_of(meta, layout)?
// for the purpose of validity, consider foreign types to have
// alignment and size determined by the layout (size will be 0,
// alignment should take attributes into account).
.unwrap_or_else(|| layout.size_and_align());
- match self.memory.check_align(ptr, align) {
+ match self.ecx.memory.check_align(ptr, align) {
Ok(_) => {},
Err(err) => {
error!("{:?} is not aligned to {:?}", ptr, align);
match err.kind {
EvalErrorKind::InvalidNullPointerUsage =>
- return validation_failure!("NULL reference", path),
+ return validation_failure!("NULL reference", self.path),
EvalErrorKind::AlignmentCheckFailed { .. } =>
- return validation_failure!("unaligned reference", path),
+ return validation_failure!("unaligned reference", self.path),
_ =>
return validation_failure!(
"dangling (out-of-bounds) reference (might be NULL at \
run-time)",
- path
+ self.path
),
}
}
// Turn ptr into place.
// `ref_to_mplace` also calls the machine hook for (re)activating the tag,
// which in turn will (in full miri) check if the pointer is dereferencable.
- let place = self.ref_to_mplace(value)?;
+ let place = self.ecx.ref_to_mplace(value)?;
// Recursive checking
- if let Some(ref_tracking) = ref_tracking {
- assert!(const_mode, "We should only do recursie checking in const mode");
+ if let Some(ref mut ref_tracking) = self.ref_tracking {
+ assert!(self.const_mode, "We should only do recursie checking in const mode");
if size != Size::ZERO {
// Non-ZST also have to be dereferencable
let ptr = try_validation!(place.ptr.to_ptr(),
- "integer pointer in non-ZST reference", path);
+ "integer pointer in non-ZST reference", self.path);
// Skip validation entirely for some external statics
- let alloc_kind = self.tcx.alloc_map.lock().get(ptr.alloc_id);
+ let alloc_kind = self.ecx.tcx.alloc_map.lock().get(ptr.alloc_id);
if let Some(AllocType::Static(did)) = alloc_kind {
// `extern static` cannot be validated as they have no body.
// FIXME: Statics from other crates are also skipped.
// They might be checked at a different type, but for now we
// want to avoid recursing too deeply. This is not sound!
- if !did.is_local() || self.tcx.is_foreign_item(did) {
+ if !did.is_local() || self.ecx.tcx.is_foreign_item(did) {
return Ok(());
}
}
// Maintain the invariant that the place we are checking is
// already verified to be in-bounds.
- try_validation!(self.memory.check_bounds(ptr, size, false),
- "dangling (not entirely in bounds) reference", path);
+ try_validation!(self.ecx.memory.check_bounds(ptr, size, false),
+ "dangling (not entirely in bounds) reference", self.path);
}
// Check if we have encountered this pointer+layout combination
// before. Proceed recursively even for integer pointers, no
let op = place.into();
if ref_tracking.seen.insert(op) {
trace!("Recursing below ptr {:#?}", *op);
- ref_tracking.todo.push((op, path_clone_and_deref(path)));
+ // We need to clone the path anyway, make sure it gets created
+ // with enough space for the additional `Deref`.
+ let mut new_path = Vec::with_capacity(self.path.len()+1);
+ new_path.clone_from(&self.path);
+ new_path.push(PathElem::Deref);
+ // Remember to come back to this later.
+ ref_tracking.todo.push((op, new_path));
}
}
}
ty::FnPtr(_sig) => {
let value = value.to_scalar_or_undef();
let ptr = try_validation!(value.to_ptr(),
- scalar_format(value), path, "a pointer");
- let _fn = try_validation!(self.memory.get_fn(ptr),
- scalar_format(value), path, "a function pointer");
+ value, self.path, "a pointer");
+ let _fn = try_validation!(self.ecx.memory.get_fn(ptr),
+ value, self.path, "a function pointer");
// FIXME: Check if the signature matches
}
// This should be all the primitive types
- ty::Never => bug!("Uninhabited type should have been caught earlier"),
_ => bug!("Unexpected primitive type {}", value.layout.ty)
}
Ok(())
}
- /// Make sure that `value` matches the
- fn validate_scalar_layout(
- &self,
- value: ScalarMaybeUndef<M::PointerTag>,
- size: Size,
- path: &Vec<PathElem>,
+ fn visit_uninhabited(&mut self) -> EvalResult<'tcx>
+ {
+ validation_failure!("a value of an uninhabited type", self.path)
+ }
+
+ fn visit_scalar(
+ &mut self,
+ op: OpTy<'tcx, M::PointerTag>,
layout: &layout::Scalar,
) -> EvalResult<'tcx> {
+ let value = self.ecx.read_scalar(op)?;
+ // Determine the allowed range
let (lo, hi) = layout.valid_range.clone().into_inner();
- let max_hi = u128::max_value() >> (128 - size.bits()); // as big as the size fits
+ // `max_hi` is as big as the size fits
+ let max_hi = u128::max_value() >> (128 - op.layout.size.bits());
assert!(hi <= max_hi);
// We could also write `(hi + 1) % (max_hi + 1) == lo` but `max_hi + 1` overflows for `u128`
if (lo == 0 && hi == max_hi) || (hi + 1 == lo) {
}
// At least one value is excluded. Get the bits.
let value = try_validation!(value.not_undef(),
- scalar_format(value), path, format!("something in the range {:?}", layout.valid_range));
+ value, self.path,
+ format!("something in the range {:?}", layout.valid_range));
let bits = match value {
Scalar::Ptr(ptr) => {
if lo == 1 && hi == max_hi {
// We can call `check_align` to check non-NULL-ness, but have to also look
// for function pointers.
let non_null =
- self.memory.check_align(
+ self.ecx.memory.check_align(
Scalar::Ptr(ptr), Align::from_bytes(1, 1).unwrap()
).is_ok() ||
- self.memory.get_fn(ptr).is_ok();
+ self.ecx.memory.get_fn(ptr).is_ok();
if !non_null {
// could be NULL
- return validation_failure!("a potentially NULL pointer", path);
+ return validation_failure!("a potentially NULL pointer", self.path);
}
return Ok(());
} else {
// value.
return validation_failure!(
"a pointer",
- path,
+ self.path,
format!(
- "something that cannot possibly be outside the (wrapping) range {:?}",
- layout.valid_range
+ "something that cannot possibly fail to be {}",
+ wrapping_range_format(&layout.valid_range, max_hi)
)
);
}
}
- Scalar::Bits { bits, size: value_size } => {
- assert_eq!(value_size as u64, size.bytes());
+ Scalar::Bits { bits, size } => {
+ assert_eq!(size as u64, op.layout.size.bytes());
bits
}
};
// Now compare. This is slightly subtle because this is a special "wrap-around" range.
- use std::ops::RangeInclusive;
- let in_range = |bound: RangeInclusive<u128>| bound.contains(&bits);
- if lo > hi {
- // wrapping around
- if in_range(0..=hi) || in_range(lo..=max_hi) {
- Ok(())
- } else {
- validation_failure!(
- bits,
- path,
- format!("something in the range {:?} or {:?}", 0..=hi, lo..=max_hi)
- )
- }
+ if wrapping_range_contains(&layout.valid_range, bits) {
+ Ok(())
} else {
- if in_range(layout.valid_range.clone()) {
- Ok(())
- } else {
- validation_failure!(
- bits,
- path,
- if hi == max_hi {
- format!("something greater or equal to {}", lo)
- } else {
- format!("something in the range {:?}", layout.valid_range)
- }
- )
- }
+ validation_failure!(
+ bits,
+ self.path,
+ format!("something {}", wrapping_range_format(&layout.valid_range, max_hi))
+ )
}
}
- /// This function checks the data at `op`. `op` is assumed to cover valid memory if it
- /// is an indirect operand.
- /// It will error if the bits at the destination do not match the ones described by the layout.
- /// The `path` may be pushed to, but the part that is present when the function
- /// starts must not be changed!
- ///
- /// `ref_tracking` can be None to avoid recursive checking below references.
- /// This also toggles between "run-time" (no recursion) and "compile-time" (with recursion)
- /// validation (e.g., pointer values are fine in integers at runtime).
- pub fn validate_operand(
- &self,
- dest: OpTy<'tcx, M::PointerTag>,
- path: &mut Vec<PathElem>,
- mut ref_tracking: Option<&mut RefTracking<'tcx, M::PointerTag>>,
- const_mode: bool,
+ fn visit_aggregate(
+ &mut self,
+ op: OpTy<'tcx, M::PointerTag>,
+ fields: impl Iterator<Item=EvalResult<'tcx, Self::V>>,
) -> EvalResult<'tcx> {
- trace!("validate_operand: {:?}, {:?}", *dest, dest.layout.ty);
-
- // If this is a multi-variant layout, we have find the right one and proceed with that.
- // (No good reasoning to make this recursion, but it is equivalent to that.)
- let dest = match dest.layout.variants {
- layout::Variants::NicheFilling { .. } |
- layout::Variants::Tagged { .. } => {
- let variant = match self.read_discriminant(dest) {
- Ok(res) => res.1,
- Err(err) => match err.kind {
- EvalErrorKind::InvalidDiscriminant(val) =>
- return validation_failure!(
- format!("invalid enum discriminant {}", val), path
- ),
- _ =>
- return validation_failure!(
- String::from("non-integer enum discriminant"), path
- ),
- }
- };
- // Put the variant projection onto the path, as a field
- path.push(PathElem::Field(dest.layout.ty
- .ty_adt_def()
- .unwrap()
- .variants[variant].name));
- // Proceed with this variant
- let dest = self.operand_downcast(dest, variant)?;
- trace!("variant layout: {:#?}", dest.layout);
- dest
- },
- layout::Variants::Single { .. } => dest,
- };
-
- // First thing, find the real type:
- // If it is a trait object, switch to the actual type that was used to create it.
- let dest = match dest.layout.ty.sty {
- ty::Dynamic(..) => {
- let dest = dest.to_mem_place(); // immediate trait objects are not a thing
- self.unpack_dyn_trait(dest)?.1.into()
- },
- _ => dest
- };
-
- // If this is a scalar, validate the scalar layout.
- // Things can be aggregates and have scalar layout at the same time, and that
- // is very relevant for `NonNull` and similar structs: We need to validate them
- // at their scalar layout *before* descending into their fields.
- // FIXME: We could avoid some redundant checks here. For newtypes wrapping
- // scalars, we do the same check on every "level" (e.g. first we check
- // MyNewtype and then the scalar in there).
- match dest.layout.abi {
- layout::Abi::Uninhabited =>
- return validation_failure!("a value of an uninhabited type", path),
- layout::Abi::Scalar(ref layout) => {
- let value = try_validation!(self.read_scalar(dest),
- "uninitialized or unrepresentable data", path);
- self.validate_scalar_layout(value, dest.layout.size, &path, layout)?;
+ match op.layout.ty.sty {
+ ty::Str => {
+ let mplace = op.to_mem_place(); // strings are never immediate
+ try_validation!(self.ecx.read_str(mplace),
+ "uninitialized or non-UTF-8 data in str", self.path);
}
- // FIXME: Should we do something for ScalarPair? Vector?
- _ => {}
- }
-
- // Check primitive types. We do this after checking the scalar layout,
- // just to have that done as well. Primitives can have varying layout,
- // so we check them separately and before aggregate handling.
- // It is CRITICAL that we get this check right, or we might be
- // validating the wrong thing!
- let primitive = match dest.layout.fields {
- // Primitives appear as Union with 0 fields -- except for fat pointers.
- layout::FieldPlacement::Union(0) => true,
- _ => dest.layout.ty.builtin_deref(true).is_some(),
- };
- if primitive {
- let value = try_validation!(self.read_immediate(dest),
- "uninitialized or unrepresentable data", path);
- return self.validate_primitive_type(
- value,
- &path,
- ref_tracking,
- const_mode,
- );
- }
-
- // Validate all fields of compound data structures
- let path_len = path.len(); // Remember the length, in case we need to truncate
- match dest.layout.fields {
- layout::FieldPlacement::Union(fields) => {
- // Empty unions are not accepted by rustc. That's great, it means we can
- // use that as an unambiguous signal for detecting primitives. Make sure
- // we did not miss any primitive.
- debug_assert!(fields > 0);
- // We can't check unions, their bits are allowed to be anything.
- // The fields don't need to correspond to any bit pattern of the union's fields.
- // See https://github.com/rust-lang/rust/issues/32836#issuecomment-406875389
- },
- layout::FieldPlacement::Arbitrary { ref offsets, .. } => {
- // Go look at all the fields
- for i in 0..offsets.len() {
- let field = self.operand_field(dest, i as u64)?;
- path.push(self.aggregate_field_path_elem(dest.layout, i));
- self.validate_operand(
- field,
- path,
- ref_tracking.as_mut().map(|r| &mut **r),
- const_mode,
- )?;
- path.truncate(path_len);
+ ty::Array(tys, ..) | ty::Slice(tys) if {
+ // This optimization applies only for integer and floating point types
+ // (i.e., types that can hold arbitrary bytes).
+ match tys.sty {
+ ty::Int(..) | ty::Uint(..) | ty::Float(..) => true,
+ _ => false,
}
- }
- layout::FieldPlacement::Array { stride, .. } => {
- let dest = if dest.layout.is_zst() {
+ } => {
+ let mplace = if op.layout.is_zst() {
// it's a ZST, the memory content cannot matter
- MPlaceTy::dangling(dest.layout, self)
+ MPlaceTy::dangling(op.layout, self.ecx)
} else {
// non-ZST array/slice/str cannot be immediate
- dest.to_mem_place()
+ op.to_mem_place()
};
- match dest.layout.ty.sty {
- // Special handling for strings to verify UTF-8
- ty::Str => {
- try_validation!(self.read_str(dest),
- "uninitialized or non-UTF-8 data in str", path);
- }
- // Special handling for arrays/slices of builtin integer types
- ty::Array(tys, ..) | ty::Slice(tys) if {
- // This optimization applies only for integer and floating point types
- // (i.e., types that can hold arbitrary bytes).
- match tys.sty {
- ty::Int(..) | ty::Uint(..) | ty::Float(..) => true,
- _ => false,
- }
- } => {
- // This is the length of the array/slice.
- let len = dest.len(self)?;
- // Since primitive types are naturally aligned and tightly packed in arrays,
- // we can use the stride to get the size of the integral type.
- let ty_size = stride.bytes();
- // This is the size in bytes of the whole array.
- let size = Size::from_bytes(ty_size * len);
-
- // NOTE: Keep this in sync with the handling of integer and float
- // types above, in `validate_primitive_type`.
- // In run-time mode, we accept pointers in here. This is actually more
- // permissive than a per-element check would be, e.g. we accept
- // an &[u8] that contains a pointer even though bytewise checking would
- // reject it. However, that's good: We don't inherently want
- // to reject those pointers, we just do not have the machinery to
- // talk about parts of a pointer.
- // We also accept undef, for consistency with the type-based checks.
- match self.memory.check_bytes(
- dest.ptr,
- size,
- /*allow_ptr_and_undef*/!const_mode,
- ) {
- // In the happy case, we needn't check anything else.
- Ok(()) => {},
- // Some error happened, try to provide a more detailed description.
- Err(err) => {
- // For some errors we might be able to provide extra information
- match err.kind {
- EvalErrorKind::ReadUndefBytes(offset) => {
- // Some byte was undefined, determine which
- // element that byte belongs to so we can
- // provide an index.
- let i = (offset.bytes() / ty_size) as usize;
- path.push(PathElem::ArrayElem(i));
-
- return validation_failure!(
- "undefined bytes", path
- )
- },
- // Other errors shouldn't be possible
- _ => return Err(err),
- }
- }
- }
- },
- _ => {
- // This handles the unsized case correctly as well, as well as
- // SIMD an all sorts of other array-like types.
- for (i, field) in self.mplace_array_fields(dest)?.enumerate() {
- let field = field?;
- path.push(PathElem::ArrayElem(i));
- self.validate_operand(
- field.into(),
- path,
- ref_tracking.as_mut().map(|r| &mut **r),
- const_mode,
- )?;
- path.truncate(path_len);
+ // This is the length of the array/slice.
+ let len = mplace.len(self.ecx)?;
+ // This is the element type size.
+ let ty_size = self.ecx.layout_of(tys)?.size;
+ // This is the size in bytes of the whole array.
+ let size = ty_size * len;
+
+ // NOTE: Keep this in sync with the handling of integer and float
+ // types above, in `visit_primitive`.
+ // In run-time mode, we accept pointers in here. This is actually more
+ // permissive than a per-element check would be, e.g. we accept
+ // an &[u8] that contains a pointer even though bytewise checking would
+ // reject it. However, that's good: We don't inherently want
+ // to reject those pointers, we just do not have the machinery to
+ // talk about parts of a pointer.
+ // We also accept undef, for consistency with the type-based checks.
+ match self.ecx.memory.check_bytes(
+ mplace.ptr,
+ size,
+ /*allow_ptr_and_undef*/!self.const_mode,
+ ) {
+ // In the happy case, we needn't check anything else.
+ Ok(()) => {},
+ // Some error happened, try to provide a more detailed description.
+ Err(err) => {
+ // For some errors we might be able to provide extra information
+ match err.kind {
+ EvalErrorKind::ReadUndefBytes(offset) => {
+ // Some byte was undefined, determine which
+ // element that byte belongs to so we can
+ // provide an index.
+ let i = (offset.bytes() / ty_size.bytes()) as usize;
+ self.path.push(PathElem::ArrayElem(i));
+
+ return validation_failure!(
+ "undefined bytes", self.path
+ )
+ },
+ // Other errors shouldn't be possible
+ _ => return Err(err),
}
}
}
- },
+ }
+ _ => {
+ self.walk_aggregate(op, fields)? // default handler
+ }
}
Ok(())
}
+}
- fn aggregate_field_path_elem(&self, layout: TyLayout<'tcx>, field: usize) -> PathElem {
- match layout.ty.sty {
- // generators and closures.
- ty::Closure(def_id, _) | ty::Generator(def_id, _, _) => {
- if let Some(upvar) = self.tcx.optimized_mir(def_id).upvar_decls.get(field) {
- PathElem::ClosureVar(upvar.debug_name)
- } else {
- // Sometimes the index is beyond the number of freevars (seen
- // for a generator).
- PathElem::ClosureVar(Symbol::intern(&field.to_string()))
- }
- }
-
- // tuples
- ty::Tuple(_) => PathElem::TupleElem(field),
-
- // enums
- ty::Adt(def, ..) if def.is_enum() => {
- let variant = match layout.variants {
- layout::Variants::Single { index } => &def.variants[index],
- _ => bug!("aggregate_field_path_elem: got enum but not in a specific variant"),
- };
- PathElem::Field(variant.fields[field].ident.name)
- }
+impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
+ /// This function checks the data at `op`. `op` is assumed to cover valid memory if it
+ /// is an indirect operand.
+ /// It will error if the bits at the destination do not match the ones described by the layout.
+ ///
+ /// `ref_tracking` can be None to avoid recursive checking below references.
+ /// This also toggles between "run-time" (no recursion) and "compile-time" (with recursion)
+ /// validation (e.g., pointer values are fine in integers at runtime).
+ pub fn validate_operand(
+ &self,
+ op: OpTy<'tcx, M::PointerTag>,
+ path: Vec<PathElem>,
+ ref_tracking: Option<&mut RefTracking<'tcx, M::PointerTag>>,
+ const_mode: bool,
+ ) -> EvalResult<'tcx> {
+ trace!("validate_operand: {:?}, {:?}", *op, op.layout.ty);
- // other ADTs
- ty::Adt(def, _) => PathElem::Field(def.non_enum_variant().fields[field].ident.name),
+ // Construct a visitor
+ let mut visitor = ValidityVisitor {
+ path,
+ ref_tracking,
+ const_mode,
+ ecx: self,
+ };
- // nothing else has an aggregate layout
- _ => bug!("aggregate_field_path_elem: got non-aggregate type {:?}", layout.ty),
- }
+ // Run it
+ visitor.visit_value(op)
}
}
--- /dev/null
+//! Visitor for a run-time value with a given layout: Traverse enums, structs and other compound
+//! types until we arrive at the leaves, with custom handling for primitive types.
+
+use rustc::ty::layout::{self, TyLayout};
+use rustc::ty;
+use rustc::mir::interpret::{
+ EvalResult,
+};
+
+use super::{
+ Machine, EvalContext, MPlaceTy, OpTy, ImmTy,
+};
+
+// A thing that we can project into, and that has a layout.
+// This wouldn't have to depend on `Machine` but with the current type inference,
+// that's just more convenient to work with (avoids repeating all the `Machine` bounds).
+pub trait Value<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>: Copy
+{
+ /// Get this value's layout.
+ fn layout(&self) -> TyLayout<'tcx>;
+
+ /// Make this into an `OpTy`.
+ fn to_op(
+ self,
+ ecx: &EvalContext<'a, 'mir, 'tcx, M>,
+ ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>>;
+
+ /// Create this from an `MPlaceTy`.
+ fn from_mem_place(MPlaceTy<'tcx, M::PointerTag>) -> Self;
+
+ /// Project to the given enum variant.
+ fn project_downcast(
+ self,
+ ecx: &EvalContext<'a, 'mir, 'tcx, M>,
+ variant: usize,
+ ) -> EvalResult<'tcx, Self>;
+
+ /// Project to the n-th field.
+ fn project_field(
+ self,
+ ecx: &EvalContext<'a, 'mir, 'tcx, M>,
+ field: u64,
+ ) -> EvalResult<'tcx, Self>;
+}
+
+// Operands and memory-places are both values.
+// Places in general are not due to `place_field` having to do `force_allocation`.
+impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
+ for OpTy<'tcx, M::PointerTag>
+{
+ #[inline(always)]
+ fn layout(&self) -> TyLayout<'tcx> {
+ self.layout
+ }
+
+ #[inline(always)]
+ fn to_op(
+ self,
+ _ecx: &EvalContext<'a, 'mir, 'tcx, M>,
+ ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
+ Ok(self)
+ }
+
+ #[inline(always)]
+ fn from_mem_place(mplace: MPlaceTy<'tcx, M::PointerTag>) -> Self {
+ mplace.into()
+ }
+
+ #[inline(always)]
+ fn project_downcast(
+ self,
+ ecx: &EvalContext<'a, 'mir, 'tcx, M>,
+ variant: usize,
+ ) -> EvalResult<'tcx, Self> {
+ ecx.operand_downcast(self, variant)
+ }
+
+ #[inline(always)]
+ fn project_field(
+ self,
+ ecx: &EvalContext<'a, 'mir, 'tcx, M>,
+ field: u64,
+ ) -> EvalResult<'tcx, Self> {
+ ecx.operand_field(self, field)
+ }
+}
+impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
+ for MPlaceTy<'tcx, M::PointerTag>
+{
+ #[inline(always)]
+ fn layout(&self) -> TyLayout<'tcx> {
+ self.layout
+ }
+
+ #[inline(always)]
+ fn to_op(
+ self,
+ _ecx: &EvalContext<'a, 'mir, 'tcx, M>,
+ ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
+ Ok(self.into())
+ }
+
+ #[inline(always)]
+ fn from_mem_place(mplace: MPlaceTy<'tcx, M::PointerTag>) -> Self {
+ mplace
+ }
+
+ #[inline(always)]
+ fn project_downcast(
+ self,
+ ecx: &EvalContext<'a, 'mir, 'tcx, M>,
+ variant: usize,
+ ) -> EvalResult<'tcx, Self> {
+ ecx.mplace_downcast(self, variant)
+ }
+
+ #[inline(always)]
+ fn project_field(
+ self,
+ ecx: &EvalContext<'a, 'mir, 'tcx, M>,
+ field: u64,
+ ) -> EvalResult<'tcx, Self> {
+ ecx.mplace_field(self, field)
+ }
+}
+
+macro_rules! make_value_visitor {
+ ($visitor_trait_name:ident, $($mutability:ident)*) => {
+ // How to traverse a value and what to do when we are at the leaves.
+ pub trait $visitor_trait_name<'a, 'mir, 'tcx: 'mir+'a, M: Machine<'a, 'mir, 'tcx>>: Sized {
+ type V: Value<'a, 'mir, 'tcx, M>;
+
+ /// The visitor must have an `EvalContext` in it.
+ fn ecx(&$($mutability)* self)
+ -> &$($mutability)* EvalContext<'a, 'mir, 'tcx, M>;
+
+ // Recursive actions, ready to be overloaded.
+ /// Visit the given value, dispatching as appropriate to more specialized visitors.
+ #[inline(always)]
+ fn visit_value(&mut self, v: Self::V) -> EvalResult<'tcx>
+ {
+ self.walk_value(v)
+ }
+ /// Visit the given value as a union. No automatic recursion can happen here.
+ #[inline(always)]
+ fn visit_union(&mut self, _v: Self::V) -> EvalResult<'tcx>
+ {
+ Ok(())
+ }
+ /// Visit this vale as an aggregate, you are even getting an iterator yielding
+ /// all the fields (still in an `EvalResult`, you have to do error handling yourself).
+ /// Recurses into the fields.
+ #[inline(always)]
+ fn visit_aggregate(
+ &mut self,
+ v: Self::V,
+ fields: impl Iterator<Item=EvalResult<'tcx, Self::V>>,
+ ) -> EvalResult<'tcx> {
+ self.walk_aggregate(v, fields)
+ }
+ /// Called each time we recurse down to a field, passing in old and new value.
+ /// This gives the visitor the chance to track the stack of nested fields that
+ /// we are descending through.
+ #[inline(always)]
+ fn visit_field(
+ &mut self,
+ _old_val: Self::V,
+ _field: usize,
+ new_val: Self::V,
+ ) -> EvalResult<'tcx> {
+ self.visit_value(new_val)
+ }
+
+ /// Called whenever we reach a value with uninhabited layout.
+ /// Recursing to fields will *always* continue after this! This is not meant to control
+ /// whether and how we descend recursively/ into the scalar's fields if there are any,
+ /// it is meant to provide the chance for additional checks when a value of uninhabited
+ /// layout is detected.
+ #[inline(always)]
+ fn visit_uninhabited(&mut self) -> EvalResult<'tcx>
+ { Ok(()) }
+ /// Called whenever we reach a value with scalar layout.
+ /// We do NOT provide a `ScalarMaybeUndef` here to avoid accessing memory if the
+ /// visitor is not even interested in scalars.
+ /// Recursing to fields will *always* continue after this! This is not meant to control
+ /// whether and how we descend recursively/ into the scalar's fields if there are any,
+ /// it is meant to provide the chance for additional checks when a value of scalar
+ /// layout is detected.
+ #[inline(always)]
+ fn visit_scalar(&mut self, _v: Self::V, _layout: &layout::Scalar) -> EvalResult<'tcx>
+ { Ok(()) }
+
+ /// Called whenever we reach a value of primitive type. There can be no recursion
+ /// below such a value. This is the leave function.
+ #[inline(always)]
+ fn visit_primitive(&mut self, _val: ImmTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
+ { Ok(()) }
+
+ // Default recursors. Not meant to be overloaded.
+ fn walk_aggregate(
+ &mut self,
+ v: Self::V,
+ fields: impl Iterator<Item=EvalResult<'tcx, Self::V>>,
+ ) -> EvalResult<'tcx> {
+ // Now iterate over it.
+ for (idx, field_val) in fields.enumerate() {
+ self.visit_field(v, idx, field_val?)?;
+ }
+ Ok(())
+ }
+ fn walk_value(&mut self, v: Self::V) -> EvalResult<'tcx>
+ {
+ trace!("walk_value: type: {}", v.layout().ty);
+ // If this is a multi-variant layout, we have find the right one and proceed with
+ // that.
+ match v.layout().variants {
+ layout::Variants::NicheFilling { .. } |
+ layout::Variants::Tagged { .. } => {
+ let op = v.to_op(self.ecx())?;
+ let idx = self.ecx().read_discriminant(op)?.1;
+ let inner = v.project_downcast(self.ecx(), idx)?;
+ trace!("walk_value: variant layout: {:#?}", inner.layout());
+ // recurse with the inner type
+ return self.visit_field(v, idx, inner);
+ }
+ layout::Variants::Single { .. } => {}
+ }
+
+ // Even for single variants, we might be able to get a more refined type:
+ // If it is a trait object, switch to the actual type that was used to create it.
+ match v.layout().ty.sty {
+ ty::Dynamic(..) => {
+ // immediate trait objects are not a thing
+ let dest = v.to_op(self.ecx())?.to_mem_place();
+ let inner = self.ecx().unpack_dyn_trait(dest)?.1;
+ trace!("walk_value: dyn object layout: {:#?}", inner.layout);
+ // recurse with the inner type
+ return self.visit_field(v, 0, Value::from_mem_place(inner));
+ },
+ _ => {},
+ };
+
+ // If this is a scalar, visit it as such.
+ // Things can be aggregates and have scalar layout at the same time, and that
+ // is very relevant for `NonNull` and similar structs: We need to visit them
+ // at their scalar layout *before* descending into their fields.
+ // FIXME: We could avoid some redundant checks here. For newtypes wrapping
+ // scalars, we do the same check on every "level" (e.g. first we check
+ // MyNewtype and then the scalar in there).
+ match v.layout().abi {
+ layout::Abi::Uninhabited => {
+ self.visit_uninhabited()?;
+ }
+ layout::Abi::Scalar(ref layout) => {
+ self.visit_scalar(v, layout)?;
+ }
+ // FIXME: Should we do something for ScalarPair? Vector?
+ _ => {}
+ }
+
+ // Check primitive types. We do this after checking the scalar layout,
+ // just to have that done as well. Primitives can have varying layout,
+ // so we check them separately and before aggregate handling.
+ // It is CRITICAL that we get this check right, or we might be
+ // validating the wrong thing!
+ let primitive = match v.layout().fields {
+ // Primitives appear as Union with 0 fields - except for Boxes and fat pointers.
+ layout::FieldPlacement::Union(0) => true,
+ _ => v.layout().ty.builtin_deref(true).is_some(),
+ };
+ if primitive {
+ let op = v.to_op(self.ecx())?;
+ let val = self.ecx().read_immediate(op)?;
+ return self.visit_primitive(val);
+ }
+
+ // Proceed into the fields.
+ match v.layout().fields {
+ layout::FieldPlacement::Union(fields) => {
+ // Empty unions are not accepted by rustc. That's great, it means we can
+ // use that as an unambiguous signal for detecting primitives. Make sure
+ // we did not miss any primitive.
+ debug_assert!(fields > 0);
+ self.visit_union(v)?;
+ },
+ layout::FieldPlacement::Arbitrary { ref offsets, .. } => {
+ // FIXME: We collect in a vec because otherwise there are lifetime errors:
+ // Projecting to a field needs (mutable!) access to `ecx`.
+ let fields: Vec<EvalResult<'tcx, Self::V>> =
+ (0..offsets.len()).map(|i| {
+ v.project_field(self.ecx(), i as u64)
+ })
+ .collect();
+ self.visit_aggregate(v, fields.into_iter())?;
+ },
+ layout::FieldPlacement::Array { .. } => {
+ // Let's get an mplace first.
+ let mplace = if v.layout().is_zst() {
+ // it's a ZST, the memory content cannot matter
+ MPlaceTy::dangling(v.layout(), self.ecx())
+ } else {
+ // non-ZST array/slice/str cannot be immediate
+ v.to_op(self.ecx())?.to_mem_place()
+ };
+ // Now we can go over all the fields.
+ let iter = self.ecx().mplace_array_fields(mplace)?
+ .map(|f| f.and_then(|f| {
+ Ok(Value::from_mem_place(f))
+ }));
+ self.visit_aggregate(v, iter)?;
+ }
+ }
+ Ok(())
+ }
+ }
+ }
+}
+
+make_value_visitor!(ValueVisitor,);
+make_value_visitor!(MutValueVisitor,mut);
//
// * 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
let source_info = SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE };
let return_block = BasicBlock::new(1);
- let mut blocks = IndexVec::new();
+ let mut blocks = IndexVec::with_capacity(2);
let block = |blocks: &mut IndexVec<_, _>, kind| {
blocks.push(BasicBlockData {
statements: vec![],
}));
}
- let mut blocks = IndexVec::new();
+ let n_blocks = if let Adjustment::RefMut = rcvr_adjustment { 5 } else { 2 };
+ let mut blocks = IndexVec::with_capacity(n_blocks);
let block = |blocks: &mut IndexVec<_, _>, statements, kind, is_cleanup| {
blocks.push(BasicBlockData {
statements,
})?;
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(
let target = self.patch.new_block(BasicBlockData {
statements: vec![assign],
terminator: Some(Terminator {
- kind: TerminatorKind::Goto { target: target },
+ kind: TerminatorKind::Goto { target },
..*terminator
}),
is_cleanup: false,
let callee_mir = match self.tcx.try_optimized_mir(callsite.location.span,
callsite.callee) {
- Ok(callee_mir) if self.should_inline(callsite, callee_mir) => {
+ Ok(callee_mir) if self.consider_optimizing(callsite, callee_mir) => {
self.tcx.subst_and_normalize_erasing_regions(
&callsite.substs,
param_env,
}
}
+ fn consider_optimizing(&self,
+ callsite: CallSite<'tcx>,
+ callee_mir: &Mir<'tcx>)
+ -> bool
+ {
+ debug!("consider_optimizing({:?})", callsite);
+ self.should_inline(callsite, callee_mir)
+ && self.tcx.consider_optimizing(|| format!("Inline {:?} into {:?}",
+ callee_mir.span,
+ callsite))
+ }
+
fn should_inline(&self,
callsite: CallSite<'tcx>,
callee_mir: &Mir<'tcx>)
let map = make_local_map(&mut mir.local_decls, marker.locals);
// Update references to all vars and tmps now
- LocalUpdater { map: map }.visit_mir(mir);
+ LocalUpdater { map }.visit_mir(mir);
mir.local_decls.shrink_to_fit();
}
}
TerminatorKind::Assert {
target, cond: Operand::Constant(ref c), expected, ..
} if (c.literal.assert_bool(tcx) == Some(true)) == expected => {
- TerminatorKind::Goto { target: target }
+ TerminatorKind::Goto { target }
},
TerminatorKind::FalseEdges { real_target, .. } => {
TerminatorKind::Goto { target: real_target }
is_banned: false,
}, krate);
- visit::walk_crate(&mut AstValidator { session: session }, krate)
+ visit::walk_crate(&mut AstValidator { session }, krate)
}
// declared as public (due to pruning, we don't explore
// outside crate private modules => no need to check this)
if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
- candidates.push(ImportSuggestion { path: path });
+ candidates.push(ImportSuggestion { path });
}
}
}
span: name_binding.span,
segments: path_segments,
};
- result = Some((module, ImportSuggestion { path: path }));
+ result = Some((module, ImportSuggestion { path }));
} else {
// add the module to the lookup
if seen_modules.insert(module.def_id().unwrap()) {
return Err(Determinacy::Determined);
}
}
+ Def::Err => {
+ return Err(Determinacy::Determined);
+ }
_ => panic!("expected `Def::Macro` or `Def::NonMacroAttr`"),
}
config: Config,
) -> JsonDumper<CallbackOutput<'b>> {
JsonDumper {
- output: CallbackOutput { callback: callback },
+ output: CallbackOutput { callback },
config: config.clone(),
result: Analysis::new(config),
}
// argument is *not* necessary for normal builds, but it can't hurt!
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,--eh-frame-hdr".to_string());
- // There's a whole bunch of circular dependencies when dealing with MUSL
- // unfortunately. To put this in perspective libc is statically linked to
- // liblibc and libunwind is statically linked to libstd:
- //
- // * libcore depends on `fmod` which is in libc (transitively in liblibc).
- // liblibc, however, depends on libcore.
- // * compiler-rt has personality symbols that depend on libunwind, but
- // libunwind is in libstd which depends on compiler-rt.
- //
- // Recall that linkers discard libraries and object files as much as
- // possible, and with all the static linking and archives flying around with
- // MUSL the linker is super aggressively stripping out objects. For example
- // the first case has fmod stripped from liblibc (it's in its own object
- // file) so it's not there when libcore needs it. In the second example all
- // the unused symbols from libunwind are stripped (each is in its own object
- // file in libstd) before we end up linking compiler-rt which depends on
- // those symbols.
- //
- // To deal with these circular dependencies we just force the compiler to
- // link everything as a group, not stripping anything out until everything
- // is processed. The linker will still perform a pass to strip out object
- // files but it won't do so until all objects/archives have been processed.
- base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,-(".to_string());
- base.post_link_args.insert(LinkerFlavor::Gcc, vec!["-Wl,-)".to_string()]);
-
// When generating a statically linked executable there's generally some
// small setup needed which is listed in these files. These are provided by
// a musl toolchain and are linked by default by the `musl-gcc` script. Note
report_unexpected_def(def);
return self.tcx.types.err;
}
- // Replace constructor type with constructed type for tuple struct patterns.
- let pat_ty = pat_ty.fn_sig(tcx).output();
- let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
-
- self.demand_eqtype(pat.span, expected, pat_ty);
let variant = match def {
Def::Err => {
}
_ => bug!("unexpected pattern definition: {:?}", def)
};
+
+ // Replace constructor type with constructed type for tuple struct patterns.
+ let pat_ty = pat_ty.fn_sig(tcx).output();
+ let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
+
+ self.demand_eqtype(pat.span, expected, pat_ty);
+
// Type check subpatterns.
if subpats.len() == variant.fields.len() ||
subpats.len() < variant.fields.len() && ddpos.is_some() {
if num_impl_m_type_params != num_trait_m_type_params {
let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap();
let impl_m_item = tcx.hir.expect_impl_item(impl_m_node_id);
- let span = if impl_m_item.generics.params.is_empty() {
+ let span = if impl_m_item.generics.params.is_empty()
+ || impl_m_item.generics.span.is_dummy() // impl Trait in argument position (#55374)
+ {
impl_m_span
} else {
impl_m_item.generics.span
// 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() {
AdtField { ty: field_ty, span: field.span }
})
.collect();
- AdtVariant { fields: fields }
+ AdtVariant { fields }
}
fn enum_variants(&self, enum_def: &hir::EnumDef) -> Vec<AdtVariant<'tcx>> {
use rustc::hir;
pub fn check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
- let mut orphan = OrphanChecker { tcx: tcx };
+ let mut orphan = OrphanChecker { tcx };
tcx.hir.krate().visit_all_item_likes(&mut orphan);
}
use rustc::hir::{self, Unsafety};
pub fn check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
- let mut unsafety = UnsafetyChecker { tcx: tcx };
+ let mut unsafety = UnsafetyChecker { tcx };
tcx.hir.krate().visit_all_item_likes(&mut unsafety);
}
// Main entry point
pub fn collect_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
- let mut visitor = CollectItemTypesVisitor { tcx: tcx };
+ let mut visitor = CollectItemTypesVisitor { tcx };
tcx.hir
.krate()
.visit_all_item_likes(&mut visitor.as_deep_visitor());
// We will tag this as part of the WF check -- logically, it is,
// but it's one that we must perform earlier than the rest of
// WfCheck.
- tcx.hir.krate().visit_all_item_likes(&mut ImplWfCheck { tcx: tcx });
+ tcx.hir.krate().visit_all_item_likes(&mut ImplWfCheck { tcx });
}
struct ImplWfCheck<'a, 'tcx: 'a> {
source: cx.tcx.def_span(self.did).clean(cx),
visibility: Some(Inherited),
def_id: self.did,
- inner: VariantItem(Variant { kind: kind }),
+ inner: VariantItem(Variant { kind }),
stability: get_stability(cx, self.did),
deprecation: get_deprecation(cx, self.did),
}
slot.borrow_mut()[k] += 1;
});
- Droppable { k: k }
+ Droppable { k }
}
}
fn _open(&self, path: &Path) -> io::Result<File> {
let inner = fs_imp::File::open(path, &self.0)?;
- Ok(File { inner: inner })
+ Ok(File { inner })
}
}
///
/// [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
/// assert_eq!(buffer, [0b101, 0b101, 0b101]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
-pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } }
+pub fn repeat(byte: u8) -> Repeat { Repeat { byte } }
#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Repeat {
#![feature(doc_keyword)]
#![feature(panic_info_message)]
#![feature(non_exhaustive)]
+#![feature(alloc_layout_extra)]
#![default_lib_allocator]
impl<T> SyncSender<T> {
fn new(inner: Arc<sync::Packet<T>>) -> SyncSender<T> {
- SyncSender { inner: inner }
+ SyncSender { inner }
}
/// Sends a value on this synchronous channel.
let mut t = mem::uninitialized();
let ret = abi::clock_time_get(abi::clockid::MONOTONIC, 0, &mut t);
assert_eq!(ret, abi::errno::SUCCESS);
- Instant { t: t }
+ Instant { t }
}
}
let mut t = mem::uninitialized();
let ret = abi::clock_time_get(abi::clockid::REALTIME, 0, &mut t);
assert_eq!(ret, abi::errno::SUCCESS);
- SystemTime { t: t }
+ SystemTime { t }
}
}
impl FileDesc {
pub fn new(fd: usize) -> FileDesc {
- FileDesc { fd: fd }
+ FileDesc { fd }
}
pub fn raw(&self) -> usize { self.fd }
pub fn file_attr(&self) -> io::Result<FileAttr> {
let mut stat = syscall::Stat::default();
cvt(syscall::fstat(self.0.raw(), &mut stat))?;
- Ok(FileAttr { stat: stat })
+ Ok(FileAttr { stat })
}
pub fn fsync(&self) -> io::Result<()> {
impl Error {
pub fn new(errno: i32) -> Error {
- Error { errno: errno }
+ Error { errno }
}
pub fn mux(result: Result<usize>) -> usize {
panic!("thread failed to exit");
} else {
mem::forget(p);
- Ok(Thread { id: id })
+ Ok(Thread { id })
}
}
impl From<syscall::TimeSpec> for SystemTime {
fn from(t: syscall::TimeSpec) -> SystemTime {
- SystemTime { t: Timespec { t: t } }
+ SystemTime { t: Timespec { t } }
}
}
impl FileDesc {
pub fn new(fd: c_int) -> FileDesc {
- FileDesc { fd: fd }
+ FileDesc { fd }
}
pub fn raw(&self) -> c_int { self.fd }
cvt(unsafe {
fstatat64(fd, self.entry.d_name.as_ptr(), &mut stat, libc::AT_SYMLINK_NOFOLLOW)
})?;
- Ok(FileAttr { stat: stat })
+ Ok(FileAttr { stat })
}
#[cfg(not(any(target_os = "linux", target_os = "emscripten", target_os = "android")))]
cvt(unsafe {
fstat64(self.0.raw(), &mut stat)
})?;
- Ok(FileAttr { stat: stat })
+ Ok(FileAttr { stat })
}
pub fn fsync(&self) -> io::Result<()> {
cvt(unsafe {
stat64(p.as_ptr(), &mut stat)
})?;
- Ok(FileAttr { stat: stat })
+ Ok(FileAttr { stat })
}
pub fn lstat(p: &Path) -> io::Result<FileAttr> {
cvt(unsafe {
lstat64(p.as_ptr(), &mut stat)
})?;
- Ok(FileAttr { stat: stat })
+ Ok(FileAttr { stat })
}
pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
impl From<libc::timespec> for SystemTime {
fn from(t: libc::timespec) -> SystemTime {
- SystemTime { t: Timespec { t: t } }
+ SystemTime { t: Timespec { t } }
}
}
impl From<libc::timespec> for SystemTime {
fn from(t: libc::timespec) -> SystemTime {
- SystemTime { t: Timespec { t: t } }
+ SystemTime { t: Timespec { t } }
}
}
fn new(lock: &'a Mutex) -> DropGuard<'a> {
unsafe {
lock.lock();
- DropGuard { lock: lock }
+ DropGuard { lock }
}
}
}
impl From<c::FILETIME> for SystemTime {
fn from(t: c::FILETIME) -> SystemTime {
- SystemTime { t: t }
+ SystemTime { t }
}
}
/// [`RwLock::read`]: ../../std/sync/struct.RwLock.html#method.read
#[stable(feature = "sync_poison", since = "1.2.0")]
pub fn new(guard: T) -> PoisonError<T> {
- PoisonError { guard: guard }
+ PoisonError { guard }
}
/// Consumes this error indicating that a lock is poisoned, returning the
/// Only use when `value` is known to be less than or equal to 0x10FFFF.
#[inline]
pub unsafe fn from_u32_unchecked(value: u32) -> CodePoint {
- CodePoint { value: value }
+ CodePoint { value }
}
/// Creates a new `CodePoint` if the value is a valid code point.
#[inline]
pub fn from_u32(value: u32) -> Option<CodePoint> {
match value {
- 0 ..= 0x10FFFF => Some(CodePoint { value: value }),
+ 0 ..= 0x10FFFF => Some(CodePoint { value }),
_ => None
}
}
// 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);
}
}
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))
}
}
- Box::new(ExpandResult { p: p })
+ Box::new(ExpandResult { p })
}
// include_str! : read the given file, insert it as a literal string expr
(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,
ItemKind::Enum(enum_definition, generics) => {
let generics = folder.fold_generics(generics);
let variants = enum_definition.variants.move_map(|x| folder.fold_variant(x));
- ItemKind::Enum(ast::EnumDef { variants: variants }, generics)
+ ItemKind::Enum(ast::EnumDef { variants }, generics)
}
ItemKind::Struct(struct_def, generics) => {
let generics = folder.fold_generics(generics);
_ => ()
}
- Ok(ast::EnumDef { variants: variants })
+ Ok(ast::EnumDef { variants })
}
/// Parse an "enum" declaration
unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), Bundles, Name));
}
+extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B,
+ LLVMValueRef Dst, unsigned DstAlign,
+ LLVMValueRef Src, unsigned SrcAlign,
+ LLVMValueRef Size, bool IsVolatile) {
+#if LLVM_VERSION_GE(7, 0)
+ return wrap(unwrap(B)->CreateMemCpy(
+ unwrap(Dst), DstAlign,
+ unwrap(Src), SrcAlign,
+ unwrap(Size), IsVolatile));
+#else
+ unsigned Align = std::min(DstAlign, SrcAlign);
+ return wrap(unwrap(B)->CreateMemCpy(
+ unwrap(Dst), unwrap(Src),
+ unwrap(Size), Align, IsVolatile));
+#endif
+}
+
+extern "C" LLVMValueRef LLVMRustBuildMemMove(LLVMBuilderRef B,
+ LLVMValueRef Dst, unsigned DstAlign,
+ LLVMValueRef Src, unsigned SrcAlign,
+ LLVMValueRef Size, bool IsVolatile) {
+#if LLVM_VERSION_GE(7, 0)
+ return wrap(unwrap(B)->CreateMemMove(
+ unwrap(Dst), DstAlign,
+ unwrap(Src), SrcAlign,
+ unwrap(Size), IsVolatile));
+#else
+ unsigned Align = std::min(DstAlign, SrcAlign);
+ return wrap(unwrap(B)->CreateMemMove(
+ unwrap(Dst), unwrap(Src),
+ unwrap(Size), Align, IsVolatile));
+#endif
+}
+
extern "C" LLVMValueRef
LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
unsigned NumArgs, LLVMBasicBlockRef Then,
-Subproject commit 431766a3fbcfb6dafb2d5a3866c1609bf44ee554
+Subproject commit 0309be1ade6bf61066f2c69f77ac3567b7dc31b5
pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 {
// CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array
// CHECK: call void %{{.*}}(%Array* noalias nocapture sret dereferenceable(32) [[ALLOCA]])
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 %{{.*}}, i8* align 1 %{{.*}}, i{{[0-9]+}} 32, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 %{{.*}}, i8* align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
// check that calls whose destination is a field of a packed struct
// go through an alloca rather than calling the function with an
// unaligned destination.
pub fn call_pkd2(f: fn() -> Array) -> BigPacked2 {
// CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array
// CHECK: call void %{{.*}}(%Array* noalias nocapture sret dereferenceable(32) [[ALLOCA]])
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 2 %{{.*}}, i8* align 2 %{{.*}}, i{{[0-9]+}} 32, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 2 %{{.*}}, i8* align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
// check that calls whose destination is a field of a packed struct
// go through an alloca rather than calling the function with an
// unaligned destination.
// CHECK: store i32 %0, i32* [[TMP]]
// CHECK: [[Y8:%[0-9]+]] = bitcast [4 x i8]* %y to i8*
// CHECK: [[TMP8:%[0-9]+]] = bitcast i32* [[TMP]] to i8*
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 [[Y8]], i8* align 1 [[TMP8]], i{{[0-9]+}} 4, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 [[Y8]], i8* align 4 [[TMP8]], i{{[0-9]+}} 4, i1 false)
*x = y;
}
// CHECK: store i32 %0, i32* [[TMP]]
// CHECK: [[Y8:%[0-9]+]] = bitcast %Bytes* %y to i8*
// CHECK: [[TMP8:%[0-9]+]] = bitcast i32* [[TMP]] to i8*
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 [[Y8]], i8* align 1 [[TMP8]], i{{[0-9]+}} 4, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 [[Y8]], i8* align 4 [[TMP8]], i{{[0-9]+}} 4, i1 false)
*x = y;
}
// 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 }]
--- /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
// 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 {}
}
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() {
+}
--- /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>,
+{}
// ignore-mips
// ignore-mips64
-#![feature(asm, rustc_attrs)]
+#![feature(asm)]
#[cfg(any(target_arch = "x86",
target_arch = "x86_64"))]
-#[rustc_error]
+
pub fn main() {
unsafe {
// clobber formatted as register input/output
// ignore-mips
// ignore-mips64
-#![feature(asm, rustc_attrs)]
-
+// compile-pass
+// skip-codegen
+#![feature(asm)]
#![allow(dead_code, non_upper_case_globals)]
#[cfg(any(target_arch = "x86",
target_arch = "x86_64"))]
-#[rustc_error]
-pub fn main() { //~ ERROR compilation successful
+pub fn main() {
// assignment not dead
let mut x: isize = 0;
unsafe {
LL | asm!("add $2, $1; mov $1, $0" : "=r"(x) : "r"(x), "r"(8_usize) : "cc", "volatile");
| ^^^^^^^^^^
-error: compilation successful
- --> $DIR/asm-misplaced-option.rs:31:1
- |
-LL | / pub fn main() { //~ ERROR compilation successful
-LL | | // assignment not dead
-LL | | let mut x: isize = 0;
-LL | | unsafe {
-... |
-LL | | assert_eq!(x, 13);
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(warnings)]
-
pub type ParseResult<T> = Result<T, ()>;
pub enum Item<'a> { Literal(&'a str),
Ok(())
}
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+
+fn main() { }
+++ /dev/null
-error: compilation successful
- --> $DIR/chrono-scan.rs:39:1
- |
-LL | fn main() { } //~ ERROR compilation successful
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(warnings)]
-
// Check that you are allowed to implement using elision but write
// trait without elision (a bug in this cropped up during
// bootstrapping, so this is a regression test).
}
}
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+
+fn main() { }
+++ /dev/null
-error: compilation successful
- --> $DIR/elision.rs:34:1
- |
-LL | fn main() { } //~ ERROR compilation successful
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
#![warn(unused)]
#![deny(warnings)]
-#![feature(rustc_attrs)]
-
+// compile-pass
+// skip-codegen
use std::option; //~ WARN
-#[rustc_error]
-fn main() {} //~ ERROR: compilation successful
+
+fn main() {}
| ^^^^^^^^
= note: #[warn(unused_imports)] implied by #[warn(warnings)]
-error: compilation successful
- --> $DIR/bad-lint-cap3.rs:20:1
- |
-LL | fn main() {} //~ ERROR: compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
|
= 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`.
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- - impl<'_, T> std::marker::Copy for &T
+ - impl<T> std::marker::Copy for &T
where T: ?Sized;
error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&[NotSync]`:
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- - impl<'_, T> std::marker::Copy for &T
+ - impl<T> std::marker::Copy for &T
where T: ?Sized;
error[E0206]: the trait `Copy` may not be implemented for this type
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(dead_code)]
-
// Here we do not get a coherence conflict because `Baz: Iterator`
// does not hold and (due to the orphan rules), we can rely on that.
impl<A:Iterator> Foo<A::Item> for A { }
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/coherence-projection-ok-orphan.rs:29:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
-
+// compile-pass
+// skip-codegen
pub trait Foo<P> {}
pub trait Bar {
type Output = u32;
}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/coherence-projection-ok.rs:28:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// `MyType: !MyTrait` along with other "fundamental" wrappers.
// aux-build:coherence_copy_like_lib.rs
-
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codgen
#![allow(dead_code)]
extern crate coherence_copy_like_lib as lib;
// Huzzah.
impl MyTrait for lib::MyFundamentalStruct<MyType> { }
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+
+fn main() { }
+++ /dev/null
-error: compilation successful
- --> $DIR/coherence_copy_like_err_fundamental_struct.rs:34:1
- |
-LL | fn main() { } //~ ERROR compilation successful
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// `MyType: !MyTrait` along with other "fundamental" wrappers.
// aux-build:coherence_copy_like_lib.rs
-
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(dead_code)]
extern crate coherence_copy_like_lib as lib;
// Huzzah.
impl<'a> MyTrait for lib::MyFundamentalStruct<&'a MyType> { }
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+
+fn main() { }
+++ /dev/null
-error: compilation successful
- --> $DIR/coherence_copy_like_err_fundamental_struct_ref.rs:34:1
- |
-LL | fn main() { } //~ ERROR compilation successful
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// aux-build:coherence_copy_like_lib.rs
-#![feature(rustc_attrs)]
+
extern crate coherence_copy_like_lib as lib;
// Tuples are not fundamental.
impl MyTrait for lib::MyFundamentalStruct<(MyType,)> { } //~ ERROR E0119
-#[rustc_error]
+
fn main() { }
// `MyType: !MyTrait` along with other "fundamental" wrappers.
// aux-build:coherence_copy_like_lib.rs
-
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(dead_code)]
extern crate coherence_copy_like_lib as lib;
impl lib::MyCopy for lib::MyFundamentalStruct<MyType> { }
impl lib::MyCopy for lib::MyFundamentalStruct<Box<MyType>> { }
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+
+fn main() { }
+++ /dev/null
-error: compilation successful
- --> $DIR/coherence_local.rs:33:1
- |
-LL | fn main() { } //~ ERROR compilation successful
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// aux-build:coherence_copy_like_lib.rs
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
extern crate coherence_copy_like_lib as lib;
// MyStruct is not fundamental.
impl lib::MyCopy for lib::MyStruct<MyType> { } //~ ERROR E0117
-#[rustc_error]
+
fn main() { }
// aux-build:coherence_copy_like_lib.rs
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
extern crate coherence_copy_like_lib as lib;
// Tuples are not fundamental, so this is not a local impl.
impl lib::MyCopy for (MyType,) { } //~ ERROR E0117
-#[rustc_error]
+
fn main() { }
// `MyType: !MyTrait` along with other "fundamental" wrappers.
// aux-build:coherence_copy_like_lib.rs
-
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(dead_code)]
extern crate coherence_copy_like_lib as lib;
// naturally, legal
impl lib::MyCopy for MyType { }
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+
+fn main() { }
+++ /dev/null
-error: compilation successful
- --> $DIR/coherence_local_ref.rs:27:1
- |
-LL | fn main() { } //~ ERROR compilation successful
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(dead_code)]
#![deny(unused_attributes)] // c.f #35584
-
mod auxiliary {
#[cfg_attr(any(), path = "nonexistent_file.rs")] pub mod namespaced_enums;
#[cfg_attr(all(), path = "namespaced_enums.rs")] pub mod nonexistent_file;
}
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
let _ = auxiliary::namespaced_enums::Foo::A;
let _ = auxiliary::nonexistent_file::Foo::A;
}
+++ /dev/null
-error: compilation successful
- --> $DIR/cfg_attr_path.rs:21:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | let _ = auxiliary::namespaced_enums::Foo::A;
-LL | | let _ = auxiliary::nonexistent_file::Foo::A;
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
LL | | Union { u8: &BAR }.foo,
LL | | Union { u8: &BAR }.bar,
LL | | )};
- | |___^ type validation failed: encountered invalid enum discriminant 5 at .1.<deref>
+ | |___^ type validation failed: encountered 5 at .1.<deref>, but expected a valid enum discriminant
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
--> $DIR/transmute-const.rs:15:1
|
LL | static FOO: bool = unsafe { mem::transmute(3u8) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3, but expected something in the range 0..=1
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3, but expected something less or equal to 1
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![allow(const_err)] // make sure we cannot allow away the errors tested here
+
#[repr(usize)]
#[derive(Copy, Clone)]
enum Enum {
}
union TransmuteEnum {
a: &'static u8,
- b: Enum,
+ out: Enum,
}
// A pointer is guaranteed non-null
-const BAD_ENUM: Enum = unsafe { TransmuteEnum { a: &1 }.b };
+const BAD_ENUM: Enum = unsafe { TransmuteEnum { a: &1 }.out };
//~^ ERROR is undefined behavior
-// Invalid enum discriminant
+// (Potentially) invalid enum discriminant
#[repr(usize)]
#[derive(Copy, Clone)]
enum Enum2 {
A = 2,
}
+#[repr(transparent)]
+#[derive(Copy, Clone)]
+struct Wrap<T>(T);
union TransmuteEnum2 {
- a: usize,
- b: Enum2,
+ in1: usize,
+ in2: &'static u8,
+ in3: (),
+ out1: Enum2,
+ out2: Wrap<Enum2>, // something wrapping the enum so that we test layout first, not enum
}
-const BAD_ENUM2 : Enum2 = unsafe { TransmuteEnum2 { a: 0 }.b };
+const BAD_ENUM2: Enum2 = unsafe { TransmuteEnum2 { in1: 0 }.out1 };
+//~^ ERROR is undefined behavior
+const BAD_ENUM3: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 };
+//~^ ERROR is undefined behavior
+const BAD_ENUM4: Wrap<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out2 };
+//~^ ERROR is undefined behavior
+
+// Undef enum discriminant. In an arry to avoid `Scalar` layout.
+const BAD_ENUM_UNDEF: [Enum2; 2] = [unsafe { TransmuteEnum2 { in3: () }.out1 }; 2];
//~^ ERROR is undefined behavior
-// Invalid enum field content (mostly to test printing of apths for enum tuple
+// Invalid enum field content (mostly to test printing of paths for enum tuple
// variants and tuples).
union TransmuteChar {
a: u32,
b: char,
}
// Need to create something which does not clash with enum layout optimizations.
-const BAD_ENUM_CHAR : Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
+const BAD_ENUM_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
//~^ ERROR is undefined behavior
fn main() {
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-enum.rs:22:1
+ --> $DIR/ub-enum.rs:24:1
|
-LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { a: &1 }.b };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer enum discriminant
+LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { a: &1 }.out };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-enum.rs:35:1
+ --> $DIR/ub-enum.rs:43:1
|
-LL | const BAD_ENUM2 : Enum2 = unsafe { TransmuteEnum2 { a: 0 }.b };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid enum discriminant 0
+LL | const BAD_ENUM2: Enum2 = unsafe { TransmuteEnum2 { in1: 0 }.out1 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected a valid enum discriminant
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:45:1
|
-LL | const BAD_ENUM_CHAR : Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 4294967295 at .Some.0.1, but expected something in the range 0..=1114111
+LL | const BAD_ENUM3: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
-error: aborting due to 3 previous errors
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-enum.rs:47:1
+ |
+LL | const BAD_ENUM4: Wrap<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out2 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected something that cannot possibly fail to be in the range 2..=2
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-enum.rs:51:1
+ |
+LL | const BAD_ENUM_UNDEF: [Enum2; 2] = [unsafe { TransmuteEnum2 { in3: () }.out1 }; 2];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-enum.rs:61:1
+ |
+LL | const BAD_ENUM_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 4294967295 at .Some.0.1, but expected something less or equal to 1114111
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+
+error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0080`.
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(const_transmute)]
+#![feature(rustc_attrs, const_transmute)]
+#![allow(const_err)] // make sure we cannot allow away the errors tested here
use std::mem;
use std::ptr::NonNull;
const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
//~^ ERROR it is undefined behavior to use this value
+// Also test other uses of rustc_layout_scalar_valid_range_start
+
+#[rustc_layout_scalar_valid_range_start(10)]
+#[rustc_layout_scalar_valid_range_end(30)]
+struct RestrictedRange1(u32);
+const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
+//~^ ERROR it is undefined behavior to use this value
+
+#[rustc_layout_scalar_valid_range_start(30)]
+#[rustc_layout_scalar_valid_range_end(10)]
+struct RestrictedRange2(u32);
+const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
+//~^ ERROR it is undefined behavior to use this value
+
fn main() {}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-nonnull.rs:17:1
+ --> $DIR/ub-nonnull.rs:18:1
|
LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-nonnull.rs:20:1
+ --> $DIR/ub-nonnull.rs:21:1
|
LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-nonnull.rs:22:1
+ --> $DIR/ub-nonnull.rs:23:1
|
LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
-error: aborting due to 3 previous errors
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-nonnull.rs:31:1
+ |
+LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 42, but expected something in the range 10..=30
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-nonnull.rs:37:1
+ |
+LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 20, but expected something less or equal to 10, or greater or equal to 30
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+
+error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0080`.
// except according to those terms.
#![feature(const_transmute)]
+#![allow(const_err)] // make sure we cannot allow away the errors tested here
use std::mem;
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref.rs:15:1
+ --> $DIR/ub-ref.rs:16:1
|
LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered unaligned reference
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref.rs:18:1
+ --> $DIR/ub-ref.rs:19:1
|
LL | const NULL: &u16 = unsafe { mem::transmute(0usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref.rs:21:1
+ --> $DIR/ub-ref.rs:22:1
|
LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain bits
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref.rs:24:1
+ --> $DIR/ub-ref.rs:25:1
|
LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a raw memory access tried to access part of a pointer value as raw bytes
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .<deref>, but expected plain bytes
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref.rs:27:1
+ --> $DIR/ub-ref.rs:28:1
|
LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered integer pointer in non-ZST reference
// except according to those terms.
#![feature(const_transmute)]
+#![allow(const_err)] // make sure we cannot allow away the errors tested here
use std::mem;
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-uninhabit.rs:18:1
+ --> $DIR/ub-uninhabit.rs:19:1
|
LL | const BAD_BAD_BAD: Bar = unsafe { mem::transmute(()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-uninhabit.rs:21:1
+ --> $DIR/ub-uninhabit.rs:22:1
|
LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type at .<deref>
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-uninhabit.rs:24:1
+ --> $DIR/ub-uninhabit.rs:25:1
|
LL | const BAD_BAD_ARRAY: [Bar; 1] = unsafe { mem::transmute(()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type at [0]
// except according to those terms.
#![feature(const_transmute,const_let)]
+#![allow(const_err)] // make sure we cannot allow away the errors tested here
use std::mem;
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-upvars.rs:15:1
+ --> $DIR/ub-upvars.rs:16:1
|
LL | / const BAD_UPVAR: &FnOnce() = &{ //~ ERROR it is undefined behavior to use this value
LL | | let bad_ref: &'static u16 = unsafe { mem::transmute(0usize) };
LL | | let another_var = 13;
LL | | move || { let _ = bad_ref; let _ = another_var; }
LL | | };
- | |__^ type validation failed: encountered 0 at .<deref>.<closure-var(bad_ref)>, but expected something greater or equal to 1
+ | |__^ type validation failed: encountered 0 at .<deref>.<dyn-downcast>.<closure-var(bad_ref)>, but expected something greater or equal to 1
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
// except according to those terms.
#![allow(unused)]
+#![allow(const_err)] // make sure we cannot allow away the errors tested here
// normalize-stderr-test "alignment \d+" -> "alignment N"
// normalize-stderr-test "offset \d+" -> "offset N"
error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ub-fat-ptr.rs:87:1
+ --> $DIR/union-ub-fat-ptr.rs:88:1
|
LL | const B: &str = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.str};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling (not entirely in bounds) reference
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ub-fat-ptr.rs:90:1
+ --> $DIR/union-ub-fat-ptr.rs:91:1
|
LL | const C: &str = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.str};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in fat pointer
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ub-fat-ptr.rs:93:1
+ --> $DIR/union-ub-fat-ptr.rs:94:1
|
LL | const C2: &MyStr = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.my_str};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in fat pointer
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ub-fat-ptr.rs:99:1
+ --> $DIR/union-ub-fat-ptr.rs:100:1
|
LL | const B2: &[u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.slice};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling (not entirely in bounds) reference
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ub-fat-ptr.rs:102:1
+ --> $DIR/union-ub-fat-ptr.rs:103:1
|
LL | const C3: &[u8] = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.slice};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in fat pointer
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ub-fat-ptr.rs:106:1
+ --> $DIR/union-ub-fat-ptr.rs:107:1
|
LL | const D: &Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vtable: &3 } }.rust};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop fn in vtable
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ub-fat-ptr.rs:109:1
+ --> $DIR/union-ub-fat-ptr.rs:110:1
|
LL | const E: &Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.rust};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop fn in vtable
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ub-fat-ptr.rs:112:1
+ --> $DIR/union-ub-fat-ptr.rs:113:1
|
LL | const F: &Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 3 } }.rust};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-pointer vtable in fat pointer
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ub-fat-ptr.rs:116:1
+ --> $DIR/union-ub-fat-ptr.rs:117:1
|
LL | const G: &Trait = &unsafe { BoolTransmute { val: 3 }.bl };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>, but expected something in the range 0..=1
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.<dyn-downcast>, but expected something less or equal to 1
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ub-fat-ptr.rs:120:1
+ --> $DIR/union-ub-fat-ptr.rs:121:1
|
LL | const H: &[bool] = &[unsafe { BoolTransmute { val: 3 }.bl }];
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>[0], but expected something in the range 0..=1
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>[0], but expected something less or equal to 1
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ub-fat-ptr.rs:126:1
+ --> $DIR/union-ub-fat-ptr.rs:127:1
|
LL | const I2: &MySliceBool = &MySlice(unsafe { BoolTransmute { val: 3 }.bl }, [false]);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.0, but expected something in the range 0..=1
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.0, but expected something less or equal to 1
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ub-fat-ptr.rs:129:1
+ --> $DIR/union-ub-fat-ptr.rs:130:1
|
LL | const I3: &MySliceBool = &MySlice(true, [unsafe { BoolTransmute { val: 3 }.bl }]);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.1[0], but expected something in the range 0..=1
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.1[0], but expected something less or equal to 1
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ub-fat-ptr.rs:133:1
+ --> $DIR/union-ub-fat-ptr.rs:134:1
|
LL | const J1: &str = unsafe { SliceTransmute { slice: &[0xFF] }.str };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized or non-UTF-8 data in str at .<deref>
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ub-fat-ptr.rs:136:1
+ --> $DIR/union-ub-fat-ptr.rs:137:1
|
LL | const J2: &MyStr = unsafe { SliceTransmute { slice: &[0xFF] }.my_str };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized or non-UTF-8 data in str at .<deref>.0
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![allow(const_err)] // make sure we cannot allow away the errors tested here
+
union DummyUnion {
u8: u8,
bool: bool,
error[E0080]: it is undefined behavior to use this value
- --> $DIR/union-ub.rs:36:1
+ --> $DIR/union-ub.rs:38:1
|
LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool};
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 42, but expected something in the range 0..=1
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 42, but expected something less or equal to 1
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
// Test use of const fn from another crate without a feature gate.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(unused_variables)]
-
// aux-build:const_fn_lib.rs
extern crate const_fn_lib;
use const_fn_lib::foo;
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
let x = foo(); // use outside a constant is ok
}
+++ /dev/null
-error: compilation successful
- --> $DIR/const-fn-stability-calls-3.rs:23:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | let x = foo(); // use outside a constant is ok
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
--- /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`.
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- - impl<'_, T> std::ops::Deref for &T
+ - impl<T> std::ops::Deref for &T
where T: ?Sized;
error[E0210]: type parameter `Foo` must be used as the type parameter for some local type (e.g. `MyStruct<Foo>`)
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
// <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(custom_attribute, rustc_attrs)]
-
+// skip-codegen
+// compile-pass
+#![feature(custom_attribute)]
macro_rules! mac {
{} => {
#[cfg(attr)]
mac! {}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/expanded-cfg.rs:32:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
--- /dev/null
+// Check extern items cannot be const + `rustfix` suggests using
+// extern static.
+//
+// #54388: an unused reference to an undefined static may or may not
+// compile. To sidestep this by using one that *is* defined.
+
+// run-rustfix
+// ignore-wasm32 no external library to link to.
+// compile-flags: -g -Z continue-parse-after-error
+#![feature(libc)]
+extern crate libc;
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern "C" {
+ static rust_dbg_static_mut: libc::c_int; //~ ERROR extern items cannot be `const`
+}
+
+fn main() {
+ // We suggest turning the (illegal) extern `const` into an extern `static`,
+ // but this also requires `unsafe` (a deny-by-default lint at comment time,
+ // future error; Issue #36247)
+ unsafe {
+ let _x = rust_dbg_static_mut;
+ }
+}
-// 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.
+// Check extern items cannot be const + `rustfix` suggests using
+// extern static.
//
-// 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.
+// #54388: an unused reference to an undefined static may or may not
+// compile. To sidestep this by using one that *is* defined.
-// FIXME(#54388): re-enable rustfix later, when this test has consistent output across targets
-// compile-flags: -Z continue-parse-after-error
+// run-rustfix
+// ignore-wasm32 no external library to link to.
+// compile-flags: -g -Z continue-parse-after-error
+#![feature(libc)]
+extern crate libc;
+#[link(name = "rust_test_helpers", kind = "static")]
extern "C" {
- const C: u8; //~ ERROR extern items cannot be `const`
+ const rust_dbg_static_mut: libc::c_int; //~ ERROR extern items cannot be `const`
}
fn main() {
// but this also requires `unsafe` (a deny-by-default lint at comment time,
// future error; Issue #36247)
unsafe {
- let _x = C;
+ let _x = rust_dbg_static_mut;
}
}
error: extern items cannot be `const`
--> $DIR/extern-const.rs:15:5
|
-LL | const C: u8; //~ ERROR extern items cannot be `const`
+LL | const rust_dbg_static_mut: libc::c_int; //~ ERROR extern items cannot be `const`
| ^^^^^ help: try using a static value: `static`
error: aborting due to previous error
// inputs are handled by each, and (2.) to ease searching for related
// occurrences in the source text.
-#![feature(rustc_attrs)] // For `rustc_error`; see note below.
+// skip-codegen
#![warn(unused_attributes, unknown_lints)]
#![allow(dead_code)]
#![allow(stable_features)]
#[export_name = "2200"] impl S { }
}
-// Note that this test ends with a `#[rustc_error] fn main()`, so it
+// Note that this test has a `skip-codegen`, so it
// will never invoke the linker. These are here nonetheless to point
// out that we allow them at non-crate-level (though I do not know
// whether they have the same effect here as at crate-level).
//~| WARN crate-level attribute should be an inner attribute
}
-// Since we expect for the mix of attributes used here to compile
-// successfully, and we are just testing for the expected warnings of
-// various (mis)uses of attributes, we use the `rustc_error` attribute
-// on the `fn main()`.
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+
+
+
+
+fn main() {
println!("Hello World");
}
LL | #![proc_macro_derive = "2500"] //~ WARN unused attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: compilation successful
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:844:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | println!("Hello World");
-LL | | }
- | |_^
+error: invalid windows subsystem `1000`, only `windows` and `console` are allowed
error: aborting due to previous error
//
// (For non-crate-level cases, see issue-43106-gating-of-builtin-attrs.rs)
-#![feature(rustc_attrs)] // For `rustc_error`; see note below.
+// compile-pass
+// skip-codegen
#![allow(dead_code)]
-
#![deprecated = "1100"]
// Since we expect for the mix of attributes used here to compile
// various (mis)uses of attributes, we use the `rustc_error` attribute
// on the `fn main()`.
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
println!("Hello World");
}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-43106-gating-of-deprecated.rs:29:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | println!("Hello World");
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
-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
-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
// Check that literals in attributes parse just fine.
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
#![allow(unused_variables)]
#[fake_doc(r"doc")] //~ ERROR attribute `fake_doc` is currently unknown
struct Q { }
-#[rustc_error]
+
fn main() { }
-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`.
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
-
+// compile-pass
+// skip-codegen
mod foo {
pub use bar::*;
pub use main as f;
pub use super::*;
}
-#[rustc_error]
-pub fn main() {} //~ ERROR compilation successful
+
+pub fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/glob-cycles.rs:29:1
- |
-LL | pub fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// ignore-pretty pretty-printing is unhygienic
#![feature(decl_macro, associated_type_defaults)]
-#![feature(rustc_attrs)]
-
+// compile-pass
+// skip-codegen
trait Base {
type AssocTy;
fn f();
mac!();
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/assoc_ty_bindings.rs:49:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(warnings)]
-
// This used to ICE because the "if" being unreachable was not handled correctly
fn err() {
if loop {} {}
}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/if-loop.rs:20:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
--- /dev/null
+// This used to ICE because it creates an `impl Trait` that captures a
+// hidden empty region.
+
+#![feature(conservative_impl_trait)]
+
+fn server() -> impl FilterBase2 { //~ ERROR [E0700]
+ segment2(|| { loop { } }).map2(|| "")
+}
+
+trait FilterBase2 {
+ fn map2<F>(self, _fn: F) -> Map2<F> where Self: Sized { loop { } }
+}
+
+struct Map2<F> { _func: F }
+
+impl<F> FilterBase2 for Map2<F> { }
+
+fn segment2<F>(_fn: F) -> Map2<F> where F: Fn() -> Result<(), ()> {
+ loop { }
+}
+
+fn main() { server(); }
--- /dev/null
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+ --> $DIR/issue-55608-captures-empty-region.rs:6:16
+ |
+LL | fn server() -> impl FilterBase2 { //~ ERROR [E0700]
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: hidden type `Map2<[closure@$DIR/issue-55608-captures-empty-region.rs:7:36: 7:41]>` captures an empty lifetime
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0700`.
// aux-build:import_crate_var.rs
-#![feature(rustc_attrs)]
-
+// compile-pass
+// skip-codegen
#[macro_use] extern crate import_crate_var;
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
m!();
//~^ WARN `$crate` may not be imported
//~| NOTE `use $crate;` was erroneously allowed and will become a hard error
= note: `use $crate;` was erroneously allowed and will become a hard error in a future release
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
-error: compilation successful
- --> $DIR/import-crate-var.rs:18:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | m!();
-LL | | //~^ WARN `$crate` may not be imported
-LL | | //~| NOTE `use $crate;` was erroneously allowed and will become a hard error
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
--- /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.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(warnings)]
-
struct Attr {
name: String,
value: String,
}
}
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
let element = Element { attrs: Vec::new() };
let _ = unsafe { element.get_attr("foo") };
}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-11740.rs:35:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | let element = Element { attrs: Vec::new() };
-LL | | let _ = unsafe { element.get_attr("foo") };
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// 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;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
-
+// compile-pass
+// skip-codegen
fn cb<'a,T>(_x: Box<Fn((&'a i32, &'a (Vec<&'static i32>, bool))) -> T>) -> T {
panic!()
}
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
cb(Box::new(|(k, &(ref v, b))| (*k, v.clone(), b)));
}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-16994.rs:18:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | cb(Box::new(|(k, &(ref v, b))| (*k, v.clone(), b)));
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
--- /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.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(warnings)]
-
trait A<T> {}
struct B<T> where B<T>: A<B<T>> { t: T }
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-19601.rs:18:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// 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;
// <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(unboxed_closures, fn_traits, rustc_attrs)]
-
+// skip-codegen
+// compile-pass
+#![feature(unboxed_closures, fn_traits)]
struct Foo;
impl<A> FnOnce<(A,)> for Foo {
extern "rust-call" fn call_once(self, (_,): (A,)) {
}
}
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
println!("{:?}", Foo("bar"));
}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-22603.rs:21:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | println!("{:?}", Foo("bar"));
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(unboxed_closures, fn_traits, rustc_attrs)]
-
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+// compile-pass
+// skip-codegen
+#![feature(unboxed_closures, fn_traits)]
+fn main() {
let k = |x: i32| { x + 1 };
Fn::call(&k, (0,));
}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-22789.rs:14:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | let k = |x: i32| { x + 1 };
-LL | | Fn::call(&k, (0,));
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(warnings)]
-
struct CNFParser {
token: char,
}
}
}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-22933-1.rs:35:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
-
+// compile-pass
+// skip-codegen
mod a {
pub mod b { pub struct Foo; }
pub use self::c::*;
}
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
let _ = a::c::Bar(a::b::Foo);
let _ = a::Bar(a::b::Foo);
}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-24883.rs:25:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | let _ = a::c::Bar(a::b::Foo);
-LL | | let _ = a::Bar(a::b::Foo);
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(warnings)]
-
trait Mirror {
type It;
}
}
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
let c: <u32 as Mirror>::It = 5;
const CCCC: <u32 as Mirror>::It = 5;
}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-26614.rs:24:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | let c: <u32 as Mirror>::It = 5;
-LL | | const CCCC: <u32 as Mirror>::It = 5;
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(unused)]
-
extern crate core;
use core as core_export;
use self::x::*;
mod x {}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-26930.rs:20:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// 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.
-
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
use std::marker::PhantomData;
impl<T: 'static, W: Bar<Output = T>> Foo<*mut T> for W {}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-29857.rs:31:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// 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`.
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![deny(non_snake_case)]
-
#[no_mangle]
pub extern "C" fn SparklingGenerationForeignFunctionInterface() {}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-31924-non-snake-ffi.rs:18:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(dead_code)]
-
pub type T = ();
mod foo { pub use super::T; }
mod bar { pub use super::T; }
pub use self::bar::*;
}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-32119.rs:29:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(warnings)]
mod foo {
pub use a::bar;
}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-32222.rs:34:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
pub use bar::*;
mod bar {
pub use main as f;
}
-#[rustc_error]
-pub fn main() {} //~ ERROR compilation successful
+
+pub fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-32797.rs:24:1
- |
-LL | pub fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
--- /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`.
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(warnings)]
macro_rules! foo { () => {
}
}
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
foo! {};
bar! {};
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-32922.rs:35:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | foo! {};
-LL | | bar! {};
-LL | |
-LL | | let mut a = true;
-LL | | baz!(a);
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
use std::fmt;
// an unsized tuple by transmuting a trait object.
fn any<T>() -> T { unreachable!() }
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
let t: &(u8, fmt::Debug) = any();
println!("{:?}", &t.1);
}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-33241.rs:20:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | let t: &(u8, fmt::Debug) = any();
-LL | | println!("{:?}", &t.1);
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
macro_rules! m {
() => { #[cfg(any())] fn f() {} }
trait T {}
impl T for () { m!(); }
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-34028.rs:21:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
macro_rules! null { ($i:tt) => {} }
macro_rules! apply_null {
($i:item) => { null! { $i } }
}
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
apply_null!(#[cfg(all())] fn f() {});
}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-34171.rs:19:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | apply_null!(#[cfg(all())] fn f() {});
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(unused)]
macro_rules! make_item {
make_stmt! {}
}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-34418.rs:31:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(dead_code)]
trait RegularExpression: Sized {
Dynamic(FindCaptures<'t, ExecNoSyncStr<'r>>),
}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-34839.rs:31:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
use std::mem;
fn takes_lifetime(_f: for<'a> fn(&'a ()) -> <() as Lifetime<'a>>::Out) {
}
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
takes_lifetime(foo);
}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-35570.rs:38:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | takes_lifetime(foo);
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// Unnecessary path disambiguator is ok
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(unused)]
-
macro_rules! m {
($p: path) => {
let _ = $p(0);
m!(S::<u8>); // OK, no warning
}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
LL | let g: Foo::<i32> = Foo { _a: 42 }; //~ WARN unnecessary path disambiguator
| ^^ try removing `::`
-error: compilation successful
- --> $DIR/issue-36116.rs:37:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
fn _test() -> impl Default { }
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+
+fn main() { }
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-36379.rs:16:1
- |
-LL | fn main() { } //~ ERROR compilation successful
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
pub trait Foo {
type Bar;
}
}
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
let _m: &Broken<Assoc=()> = &();
}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-36839.rs:30:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | let _m: &Broken<Assoc=()> = &();
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs, associated_type_defaults)]
+// compile-pass
+// skip-codegen
+#![feature(associated_type_defaults)]
#![allow(warnings)]
-
trait State: Sized {
type NextState: State = StateMachineEnded;
fn execute(self) -> Option<Self::NextState>;
}
}
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-37051.rs:28:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// except according to those terms.
// ignore-emscripten
-
-#![feature(rustc_attrs, asm)]
+// compile-pass
+// skip-codegen
+#![feature(asm)]
macro_rules! interrupt_handler {
() => {
}
interrupt_handler!{}
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-37366.rs:25:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
fn foo(_: &mut i32) -> bool { true }
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
let opt = Some(92);
let mut x = 62;
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-37510.rs:16:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | let opt = Some(92);
-LL | | let mut x = 62;
-LL | |
-... |
-LL | | }
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// <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)]
+// skip-codegen
+// compile-pass
#![warn(unused)]
type Z = for<'x> Send;
//~^ WARN type alias is never used
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
}
| ^^^^^^
= note: #[warn(dead_code)] implied by #[warn(unused)]
-error: compilation successful
- --> $DIR/issue-37515.rs:18:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(associated_consts, rustc_attrs)]
+// compile-pass
+// skip-codegen
+#![feature(associated_consts)]
#![allow(warnings)]
-
trait MyTrait {
const MY_CONST: &'static str;
}
my_macro!();
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-38160.rs:31:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
use std::ops::Deref;
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
let _x: fn(&i32) -> <&i32 as Deref>::Target = unimplemented!();
}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-38381.rs:16:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | let _x: fn(&i32) -> <&i32 as Deref>::Target = unimplemented!();
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
--- /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];
-}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
+// skip-codegen
#![allow(warnings)]
enum E {
}
}
-#[rustc_error]
-fn main() {}
-//~^ ERROR compilation successful
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-40350.rs:22:1
- |
-LL | fn main() {}
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
It represents potential unsoundness in your code.
This warning will become a hard error in the future.
-error: compilation successful
- --> $DIR/issue-40510-1.rs:23:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(unused)]
fn f() {
};
}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-40510-1.rs:23:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(unused)]
fn f() {
};
}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-40510-2.rs:23:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
It represents potential unsoundness in your code.
This warning will become a hard error in the future.
-error: compilation successful
- --> $DIR/issue-40510-3.rs:25:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(unused)]
fn f() {
};
}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-40510-3.rs:25:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(unused)]
fn f() {
};
}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-40510-4.rs:25:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
--- /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`.
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
if ('x' as char) < ('y' as char) {
print!("x");
} else {
+++ /dev/null
-error: compilation successful
- --> $DIR/issue-41998.rs:14:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | if ('x' as char) < ('y' as char) {
-LL | | print!("x");
-LL | | } else {
-LL | | print!("y");
-LL | | }
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// 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`.
--- /dev/null
+trait Foo {
+ type T;
+ fn foo(&self, t: Self::T);
+//~^ NOTE expected 0 type parameters
+}
+
+impl Foo for u32 {
+ type T = ();
+
+ fn foo(&self, t: impl Clone) {}
+//~^ ERROR method `foo` has 1 type parameter but its trait declaration has 0 type parameters
+//~| NOTE found 1 type parameter
+}
+
+fn main() {}
--- /dev/null
+error[E0049]: method `foo` has 1 type parameter but its trait declaration has 0 type parameters
+ --> $DIR/type-arg-mismatch-due-to-impl-trait.rs:10:5
+ |
+LL | fn foo(&self, t: Self::T);
+ | -------------------------- expected 0 type parameters
+...
+LL | fn foo(&self, t: impl Clone) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found 1 type parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0049`.
#![allow(dead_code)]
#![allow(unused_variables)]
-#![feature(rustc_attrs)]
+
extern crate lifetime_bound_will_change_warning_lib as lib;
lib::ref_obj(x)
}
-#[rustc_error]
+
fn main() {
}
// aux-build:lint_output_format.rs
#![feature(unstable_test_feature)]
-#![feature(rustc_attrs)]
+// compile-pass
extern crate lint_output_format;
use lint_output_format::{foo, bar};
//~^ WARNING use of deprecated item 'lint_output_format::foo': text
-#[rustc_error]
-fn main() { //~ ERROR: compilation successful
+
+fn main() {
let _x = foo();
//~^ WARNING use of deprecated item 'lint_output_format::foo': text
let _y = bar();
LL | let _x = foo();
| ^^^
-error: compilation successful
- --> $DIR/lint-output-format-2.rs:21:1
- |
-LL | / fn main() { //~ ERROR: compilation successful
-LL | | let _x = foo();
-LL | | //~^ WARNING use of deprecated item 'lint_output_format::foo': text
-LL | | let _y = bar();
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+// compile-pass
// aux-build:lint_stability.rs
// aux-build:inherited_stability.rs
// aux-build:stability_cfg1.rs
// aux-build:stability_cfg2.rs
// ignore-tidy-linelength
-
#![warn(deprecated)]
#![allow(dead_code, unused_extern_crates)]
-#![feature(staged_api, unstable_test_feature, rustc_attrs)]
+#![feature(staged_api, unstable_test_feature)]
#![stable(feature = "rust1", since = "1.0.0")]
trait LocalTrait : DeprecatedTrait { } //~ WARN use of deprecated item 'this_crate::DeprecatedTrait'
}
-#[rustc_error] fn main() {} //~ ERROR: compilation successful
+fn main() {}
LL | foo.trait_deprecated_text(); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
| ^^^^^^^^^^^^^^^^^^^^^
-error: compilation successful
- --> $DIR/lint-stability-deprecated.rs:473:16
- |
-LL | #[rustc_error] fn main() {} //~ ERROR: compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// <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: -O
#![warn(overflowing_literals)]
#![warn(const_err)]
-#![feature(rustc_attrs)]
+// compile-pass
#[allow(unused_variables)]
-#[rustc_error]
-fn main() { //~ ERROR: compilation successful
+
+fn main() {
let x2: i8 = --128; //~ warn: literal out of range for i8
let x = -3.40282357e+38_f32; //~ warn: literal out of range for f32
LL | let x = 1.7976931348623159e+308_f64; //~ warn: literal out of range for f64
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: compilation successful
- --> $DIR/lint-type-overflow2.rs:18:1
- |
-LL | / fn main() { //~ ERROR: compilation successful
-LL | | let x2: i8 = --128; //~ warn: literal out of range for i8
-LL | |
-LL | | let x = -3.40282357e+38_f32; //~ warn: literal out of range for f32
-... |
-LL | | let x = 1.7976931348623159e+308_f64; //~ warn: literal out of range for f64
-LL | | }
- | |_^
-
-error: aborting due to previous error
+warning: this expression will panic at runtime
+ --> $DIR/lint-type-overflow2.rs:19:18
+ |
+LL | let x2: i8 = --128; //~ warn: literal out of range for i8
+ | ^^^^^ attempt to negate with overflow
+ |
+note: lint level defined here
+ --> $DIR/lint-type-overflow2.rs:13:9
+ |
+LL | #![warn(const_err)]
+ | ^^^^^^^^^
// FIXME(#44232) we should warn that this isn't used.
#![feature(rust1)]
-#![feature(rustc_attrs)]
+// compile-pass
-#[rustc_error]
-fn main() { } //~ ERROR: compilation successful
+
+fn main() { }
+++ /dev/null
-error: compilation successful
- --> $DIR/lint-unknown-feature-default.rs:20:1
- |
-LL | fn main() { } //~ ERROR: compilation successful
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// FIXME(#44232) we should warn that this isn't used.
#![feature(rust1)]
-#![feature(rustc_attrs)]
+// compile-pass
-#[rustc_error]
-fn main() {} //~ ERROR: compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/lint-unknown-feature.rs:20:1
- |
-LL | fn main() {} //~ ERROR: compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
// ignore-tidy-linelength
//~^ WARN label name `'lt` shadows a label name that is already in scope
}
-#[rustc_error]
-pub fn main() { //~ ERROR compilation successful
+
+pub fn main() {
foo();
}
LL | { 'lt: while let Some(_) = None::<i32> { break; } }
| ^^^ lifetime 'lt already in scope
-error: compilation successful
- --> $DIR/loops-reject-duplicate-labels-2.rs:43:1
- |
-LL | / pub fn main() { //~ ERROR compilation successful
-LL | | foo();
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
// ignore-tidy-linelength
fn m2(&self) { 'okay: loop { break 'okay; } }
}
-#[rustc_error]
-pub fn main() { //~ ERROR compilation successful
+
+pub fn main() {
let s = S;
s.m1();
s.m2();
LL | 'lt: while let Some(_) = None::<i32> { break; }
| ^^^ lifetime 'lt already in scope
-error: compilation successful
- --> $DIR/loops-reject-duplicate-labels.rs:50:1
- |
-LL | / pub fn main() { //~ ERROR compilation successful
-LL | | let s = S;
-LL | | s.m1();
-LL | | s.m2();
-LL | | foo();
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// Issue #21633: reject duplicate loop labels in function bodies.
// This is testing interaction between lifetime-params and labels.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(dead_code, unused_variables)]
}
}
-#[rustc_error]
-pub fn main() { //~ ERROR compilation successful
+
+pub fn main() {
foo();
}
LL | 'bad: loop { break 'bad; }
| ^^^^ lifetime 'bad already in scope
-error: compilation successful
- --> $DIR/loops-reject-labels-shadowing-lifetimes.rs:117:1
- |
-LL | / pub fn main() { //~ ERROR compilation successful
-LL | | foo();
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(dead_code, unused_variables)]
}
}
-#[rustc_error]
-pub fn main() { //~ ERROR compilation successful
+
+pub fn main() {
foo();
}
LL | let b = Box::new(|x: &i8| *x) as Box<for <'a> Fn(&'a i8) -> i8>;
| ^^ lifetime 'a already in scope
-error: compilation successful
- --> $DIR/loops-reject-lifetime-shadowing-label.rs:39:1
- |
-LL | / pub fn main() { //~ ERROR compilation successful
-LL | | foo();
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// except according to those terms.
// ignore-emscripten no asm! support
-
-#![feature(asm, rustc_attrs)]
+// compile-pass
+#![feature(asm)]
#![allow(unused)]
#[macro_use]
m!();
fn f() { n!(); }
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/test.rs:23:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
macro_rules! m { ($s:stmt;) => { $s } }
m!(vec![].push(0););
}
+++ /dev/null
-error: compilation successful
- --> $DIR/macro-stmt-matchers.rs:14:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | macro_rules! m { ($s:stmt;) => { $s } }
-LL | | m!(vec![].push(0););
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(dead_code)]
macro_rules! foo {
foo!(Box);
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/macro-tt-matchers.rs:21:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// aux-build:two_macros.rs
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(unused)]
fn f() {
} }
m!();
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/macro-use-scope.rs:32:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
--- /dev/null
+use std::path::Path;
+
+fn main() {
+ let path = Path::new("foo");
+ match path {
+ Path::new("foo") => println!("foo"),
+ //~^ ERROR expected tuple struct/variant
+ Path::new("bar") => println!("bar"),
+ //~^ ERROR expected tuple struct/variant
+ _ => (),
+ }
+}
--- /dev/null
+error[E0164]: expected tuple struct/variant, found method `<Path>::new`
+ --> $DIR/match-fn-call.rs:6:9
+ |
+LL | Path::new("foo") => println!("foo"),
+ | ^^^^^^^^^^^^^^^^ not a tuple variant or struct
+
+error[E0164]: expected tuple struct/variant, found method `<Path>::new`
+ --> $DIR/match-fn-call.rs:8:9
+ |
+LL | Path::new("bar") => println!("bar"),
+ | ^^^^^^^^^^^^^^^^ not a tuple variant or struct
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0164`.
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
struct S<T>(*const T) where T: ?Sized;
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
let u = vec![1, 2, 3];
let _s: S<[u8]> = S(&u[..]);
}
+++ /dev/null
-error: compilation successful
- --> $DIR/maybe-bounds-where-cpass.rs:16:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | let u = vec![1, 2, 3];
-LL | | let _s: S<[u8]> = S(&u[..]);
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(unused)]
struct S;
S.early_and_type::<u16>();
}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/method-call-lifetime-args-subst-index.rs:25:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(unused)]
macro_rules! m {
}
}
-#[rustc_error]
-fn main() { m!(0, 0; 0, 0); } //~ ERROR compilation successful
+
+fn main() { m!(0, 0; 0, 0); }
LL | $( let x = $e1 )*; //~ WARN expected `;`
| ^^^
...
-LL | fn main() { m!(0, 0; 0, 0); } //~ ERROR compilation successful
+LL | fn main() { m!(0, 0; 0, 0); }
| --------------- in this macro invocation
|
= note: This was erroneously allowed and will become a hard error in a future release
LL | $( println!("{}", $e2) )*; //~ WARN expected `;`
| ^^^^^^^
...
-LL | fn main() { m!(0, 0; 0, 0); } //~ ERROR compilation successful
+LL | fn main() { m!(0, 0; 0, 0); }
| --------------- in this macro invocation
|
= note: This was erroneously allowed and will become a hard error in a future release
-error: compilation successful
- --> $DIR/missing-semicolon-warning.rs:22:1
- |
-LL | fn main() { m!(0, 0; 0, 0); } //~ ERROR compilation successful
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// Test that an assignment of type ! makes the rest of the block dead code.
#![feature(never_type)]
-#![feature(rustc_attrs)]
+// compile-pass
#![warn(unused)]
-#[rustc_error]
-fn main() { //~ ERROR: compilation successful
+
+fn main() {
let x: ! = panic!("aah"); //~ WARN unused
drop(x); //~ WARN unreachable
//~^ WARN unreachable
| ^^^^^^
= note: #[warn(unused_variables)] implied by #[warn(unused)]
-error: compilation successful
- --> $DIR/never-assign-dead-code.rs:18:1
- |
-LL | / fn main() { //~ ERROR: compilation successful
-LL | | let x: ! = panic!("aah"); //~ WARN unused
-LL | | drop(x); //~ WARN unreachable
-LL | | //~^ WARN unreachable
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// even though the compiler should enforce an invariant that any drop
// flag for such subcontent of `Foo` will always have the same value
// as the drop flag for `Foo` itself.
-//
-// This test is structured in a funny way; we cannot test for emission
-// of the warning in question via the lint system, and therefore
-// `#![deny(warnings)]` does nothing to detect it.
-//
-// So instead we use `#[rustc_error]` and put the test into
-// `compile_fail`, where the emitted warning *will* be caught.
-#![feature(rustc_attrs)]
+
+
+
+
+
+
+
+// compile-pass
struct Foo(String);
f.0 = String::from("bar");
}
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
inline();
outline();
}
+++ /dev/null
-error: compilation successful
- --> $DIR/no-warn-on-field-replace-issue-34101.rs:53:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | inline();
-LL | | outline();
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// Check that a trait with by-value self is considered object-safe.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(dead_code)]
#![allow(trivial_casts)]
t as &Quux
}
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
}
+++ /dev/null
-error: compilation successful
- --> $DIR/object-safety-by-value-self.rs:55:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// Check that `Self` appearing in a phantom fn does not make a trait not object safe.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(dead_code)]
trait Baz {
t
}
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
}
+++ /dev/null
-error: compilation successful
- --> $DIR/object-safety-phantom-fn.rs:31:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// Test if the on_unimplemented message override works
#![feature(on_unimplemented)]
-#![feature(rustc_attrs)]
+
struct Foo<T>(T);
struct Bar<T>(T);
}
}
-#[rustc_error]
+
fn main() {
Index::index(&[] as &[i32], 2u32);
//~^ ERROR E0277
// Test if the on_unimplemented message override works
#![feature(on_unimplemented)]
-#![feature(rustc_attrs)]
+
#[rustc_on_unimplemented = "invalid"]
trait Index<Idx: ?Sized> {
}
}
-#[rustc_error]
+
fn main() {
Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
//~^ ERROR E0277
// Test new Index error message for slices
// ignore-tidy-linelength
-#![feature(rustc_attrs)]
+
use std::ops::Index;
-#[rustc_error]
+
fn main() {
let x = &[1, 2, 3] as &[i32];
x[1i32]; //~ ERROR 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-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
-
#![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
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(warnings)]
mod foo {
}
}
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
let s = foo::S::default();
let _: bool = s.x;
let _: bool = s.f();
+++ /dev/null
-error: compilation successful
- --> $DIR/lookup-ignores-private.rs:40:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | let s = foo::S::default();
-LL | | let _: bool = s.x;
-LL | | let _: bool = s.f();
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
use std::ops::*;
#[derive(Copy, Clone)]
struct R(RangeTo<usize>);
-#[rustc_error]
-fn main() {} //~ ERROR success
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/range_traits-4.rs:19:1
- |
-LL | fn main() {} //~ ERROR success
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
use std::ops::*;
#[derive(Copy, Clone)]
struct R(RangeFull);
-#[rustc_error]
-fn main() {} //~ ERROR success
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/range_traits-5.rs:19:1
- |
-LL | fn main() {} //~ ERROR success
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+// compile-pass
use std::ops::*;
#[derive(Copy, Clone)]
struct R(RangeToInclusive<usize>);
-#[rustc_error]
-fn main() {} //~ ERROR success
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/range_traits-7.rs:19:1
- |
-LL | fn main() {} //~ ERROR success
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// Test related to #22779. In this case, the impl is an inherent impl,
// so it doesn't have to match any trait, so no error results.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(dead_code)]
struct MySlice<'a, T:'a>(&'a mut [T]);
}
}
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+
+fn main() { }
+++ /dev/null
-error: compilation successful
- --> $DIR/region-bound-extra-bound-in-inherent-impl.rs:26:1
- |
-LL | fn main() { } //~ ERROR compilation successful
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// Test related to #22779, but where the `'a:'b` relation
// appears in the trait too. No error here.
-#![feature(rustc_attrs)]
+// compile-pass
trait Tr<'a, T> {
fn renew<'b: 'a>(self) -> &'b mut [T] where 'a: 'b;
}
}
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+
+fn main() { }
+++ /dev/null
-error: compilation successful
- --> $DIR/region-bound-same-bounds-in-trait-and-impl.rs:27:1
- |
-LL | fn main() { } //~ ERROR compilation successful
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// Various tests related to testing how region inference works
// with respect to the object receivers.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(warnings)]
trait Foo {
x.borrowed()
}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/region-object-lifetime-1.rs:28:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// Various tests related to testing how region inference works
// with respect to the object receivers.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(warnings)]
trait Foo {
x.borrowed()
}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/region-object-lifetime-3.rs:28:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// "projection gap": in this test, we know that `T: 'x`, and that is
// enough to conclude that `T::Foo: 'x`.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(dead_code)]
#![allow(unused_variables)]
wf::<&'x T::Foo>();
}
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+
+fn main() { }
+++ /dev/null
-error: compilation successful
- --> $DIR/regions-implied-bounds-projection-gap-2.rs:33:1
- |
-LL | fn main() { } //~ ERROR compilation successful
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// "projection gap": in this test, we know that `T::Foo: 'x`, and that
// is (naturally) enough to conclude that `T::Foo: 'x`.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(dead_code)]
#![allow(unused_variables)]
wf::<&'x T::Foo>();
}
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+
+fn main() { }
+++ /dev/null
-error: compilation successful
- --> $DIR/regions-implied-bounds-projection-gap-3.rs:33:1
- |
-LL | fn main() { } //~ ERROR compilation successful
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// "projection gap": in this test, we know that `T: 'x`, and that
// is (naturally) enough to conclude that `T: 'x`.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(dead_code)]
#![allow(unused_variables)]
wf::<&'x T>();
}
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+
+fn main() { }
+++ /dev/null
-error: compilation successful
- --> $DIR/regions-implied-bounds-projection-gap-4.rs:33:1
- |
-LL | fn main() { } //~ ERROR compilation successful
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// "outlives" requirements. Issue #22246.
#![allow(dead_code)]
-#![feature(rustc_attrs)]
+
///////////////////////////////////////////////////////////////////////////
//~^ ERROR reference has a longer lifetime
}
-#[rustc_error]
+
fn main() {
}
// `'r` is bound, that leads to badness. This test checks that
// everything works.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(dead_code)]
trait TheTrait {
wf::< <FnType<T> as TheTrait>::TheType >();
}
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+
+fn main() { }
+++ /dev/null
-error: compilation successful
- --> $DIR/regions-outlives-projection-hrtype.rs:36:1
- |
-LL | fn main() { } //~ ERROR compilation successful
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// Test that `<F as Foo<'a>>::Type: 'b`, where `trait Foo<'a> { Type:
// 'a; }`, does not require that `F: 'b`.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(dead_code)]
trait SomeTrait<'a> {
// here, then we would require that `T:'a`, which is too strong.
}
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+
+fn main() { }
+++ /dev/null
-error: compilation successful
- --> $DIR/regions-outlives-projection-trait-def.rs:31:1
- |
-LL | fn main() { } //~ ERROR compilation successful
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// Test that scalar values outlive all regions.
// Rule OutlivesScalar from RFC 1214.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(dead_code)]
struct Foo<'a> {
y: &'static i32
}
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+
+fn main() { }
+++ /dev/null
-error: compilation successful
- --> $DIR/regions-outlives-scalar.rs:23:1
- |
-LL | fn main() { } //~ ERROR compilation successful
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+
#![allow(warnings)]
pub fn fail(x: Option<&(Iterator<Item=()>+Send)>)
x
}
-#[rustc_error]
+
fn main() {}
//
// Rule OutlivesNominalType from RFC 1214.
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
mod rev_variant_struct_region {
}
}
-#[rustc_error]
+
fn main() { }
//
// Rule OutlivesNominalType from RFC 1214.
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
mod variant_struct_region {
}
}
-#[rustc_error]
+
fn main() { }
//
// Rule OutlivesNominalType from RFC 1214.
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
mod variant_struct_type {
}
}
-#[rustc_error]
+
fn main() { }
//
// Rule OutlivesNominalType from RFC 1214.
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
mod variant_struct_type {
}
}
-#[rustc_error]
+
fn main() { }
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
//! A test to ensure that helpful `note` messages aren't emitted more often
//! than necessary.
-#![feature(rustc_attrs)]
+// compile-pass
// Although there are three warnings, we should only get two "lint level defined
// here" notes pointing at the `warnings` span, one for each error type.
#![warn(unused)]
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
+
+fn main() {
let theTwo = 2; //~ WARN should have a snake case name
let theOtherTwo = 2; //~ WARN should have a snake case name
//~^ WARN unused variable
LL | let theOtherTwo = 2; //~ WARN should have a snake case name
| ^^^^^^^^^^^
-error: compilation successful
- --> $DIR/issue-24690.rs:21:1
- |
-LL | / fn main() { //~ ERROR compilation successful
-LL | | let theTwo = 2; //~ WARN should have a snake case name
-LL | | let theOtherTwo = 2; //~ WARN should have a snake case name
-LL | | //~^ WARN unused variable
-LL | | println!("{}", theTwo);
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs, get_type_id)]
+// compile-pass
+#![feature(get_type_id)]
#![allow(dead_code)]
-
mod foo {
pub use self::bar::T;
mod bar {
error.get_type_id(); // Regression test for #21670
}
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+
+fn main() {}
+++ /dev/null
-error: compilation successful
- --> $DIR/trait-privacy.rs:35:1
- |
-LL | fn main() {} //~ ERROR compilation successful
- | ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// types are required. This test now just compiles fine, since the
// relevant rules that triggered the overflow were removed.
-#![feature(rustc_attrs)]
+// compile-pass
#![allow(dead_code)]
use std::marker::PhantomData;
fn foo(_: Receipt<Complete<()>>) { }
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+
+fn main() { }
+++ /dev/null
-error: compilation successful
- --> $DIR/traits-issue-23003-overflow.rs:39:1
- |
-LL | fn main() { } //~ ERROR compilation successful
- | ^^^^^^^^^^^^^
-
-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) { }
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(never_type)]
-#![feature(exhaustive_patterns, rustc_attrs)]
+// compile-pass
+#![feature(never_type, exhaustive_patterns)]
#![warn(unreachable_code)]
#![warn(unreachable_patterns)]
Ok(y)
}
-#[rustc_error]
-fn main() { //~ ERROR: compilation successful
+
+fn main() {
let _ = bar(Err(123));
let _ = foo(Err(123));
let _ = qux(Ok(123));
LL | let y = (match x { Ok(n) => Ok(n), Err(e) => Err(e) })?;
| ^^^^^^
-error: compilation successful
- --> $DIR/unreachable-try-pattern.rs:46:1
- |
-LL | / fn main() { //~ ERROR: compilation successful
-LL | | let _ = bar(Err(123));
-LL | | let _ = foo(Err(123));
-LL | | let _ = qux(Ok(123));
-LL | | let _ = vom(Ok(123));
-LL | | }
- | |_^
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_attrs)]
+
use std::collections::btree_map::{IterMut, OccupiedEntry, VacantEntry};
v //~ ERROR mismatched types
}
-#[rustc_error]
+
fn main() { }
// Test various uses of structs with distint variances to make sure
// they permit lifetimes to be approximated as expected.
-#![feature(rustc_attrs)]
+
struct SomeStruct<T>(fn(T));
v //~ ERROR mismatched types
}
-#[rustc_error]
+
fn main() { }
// they permit lifetimes to be approximated as expected.
#![allow(dead_code)]
-#![feature(rustc_attrs)]
+// compile-pass
struct SomeStruct<T>(fn(T));
v
}
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+
+fn main() { }
+++ /dev/null
-error: compilation successful
- --> $DIR/variance-use-contravariant-struct-2.rs:27:1
- |
-LL | fn main() { } //~ ERROR compilation successful
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// be shortened.
#![allow(dead_code)]
-#![feature(rustc_attrs)]
+// compile-pass
struct SomeStruct<T>(T);
v
}
-#[rustc_error] fn main() { } //~ ERROR compilation successful
+fn main() { }
+++ /dev/null
-error: compilation successful
- --> $DIR/variance-use-covariant-struct-2.rs:26:16
- |
-LL | #[rustc_error] fn main() { } //~ ERROR compilation successful
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
// Test various uses of structs with distint variances to make sure
// they permit lifetimes to be approximated as expected.
-#![feature(rustc_attrs)]
+
struct SomeStruct<T>(*mut T);
v //~ ERROR mismatched types
}
-#[rustc_error]
+
fn main() { }
// Check that array elemen types must be Sized. Issue #25692.
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
struct Foo {
foo: [[u8]], //~ ERROR E0277
}
-#[rustc_error]
+
fn main() { }
// Test that we check the types of constants are well-formed.
#![feature(associated_type_defaults)]
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
struct IsCopy<T:Copy> { t: T }
const FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
//~^ ERROR E0277
-#[rustc_error]
+
fn main() { }
// Test that we check enum bounds for WFedness.
#![feature(associated_type_defaults)]
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
trait ExtraCopy<T:Copy> { }
SomeVariant(T,U)
}
-#[rustc_error]
+
fn main() { }
// Test that we check struct fields for WFedness.
#![feature(associated_type_defaults)]
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
struct IsCopy<T:Copy> {
}
}
-#[rustc_error]
+
fn main() { }
// Test that we check struct fields for WFedness.
#![feature(associated_type_defaults)]
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
struct IsCopy<T:Copy> {
SomeVariant(IsCopy<A>) //~ ERROR E0277
}
-#[rustc_error]
+
fn main() { }
// Test that we check where-clauses on fn items.
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
trait ExtraCopy<T:Copy> { }
//~^ ERROR E0277
//~| ERROR E0038
-#[rustc_error]
+
fn main() { }
// Check that we require that associated types in an impl are well-formed.
-#![feature(rustc_attrs)]
+
pub trait Foo<'a> {
type Bar;
type Bar = &'a T; //~ ERROR E0309
}
-#[rustc_error]
+
fn main() { }
// Check that we require that associated types in an impl are well-formed.
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
pub trait MyHash { }
//~^ ERROR the trait bound `T: MyHash` is not satisfied
}
-#[rustc_error]
+
fn main() { }
// types in fns.
#![allow(dead_code)]
-#![feature(rustc_attrs)]
+
struct MustBeCopy<T:Copy> {
t: T
x: fn(&'static T) //~ ERROR E0310
}
-#[rustc_error]
+
fn main() { }
// Check that we enforce WF conditions also for where clauses in fn items.
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
trait MustBeCopy<T:Copy> {
{
}
-#[rustc_error]
+
fn main() { }
// Check that we enforce WF conditions also for types in fns.
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
trait Object<T> { }
x: Object<&'static T> //~ ERROR E0310
}
-#[rustc_error]
+
fn main() { }
// Test that we check where-clauses on inherent impl methods.
#![feature(associated_type_defaults)]
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
trait ExtraCopy<T:Copy> { }
{}
}
-#[rustc_error]
+
fn main() { }
// Test that we check where-clauses on inherent impls.
#![feature(associated_type_defaults)]
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
trait ExtraCopy<T:Copy> { }
{
}
-#[rustc_error]
+
fn main() { }
// Test that we check the types of statics are well-formed.
#![feature(associated_type_defaults)]
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
struct IsCopy<T:Copy> { t: T }
static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
//~^ ERROR E0277
-#[rustc_error]
+
fn main() { }
// Test that we check struct bounds for WFedness.
#![feature(associated_type_defaults)]
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
trait ExtraCopy<T:Copy> { }
data: (T,U)
}
-#[rustc_error]
+
fn main() { }
// Test that we check struct fields for WFedness.
#![feature(associated_type_defaults)]
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
struct IsCopy<T:Copy> {
data: IsCopy<A> //~ ERROR E0277
}
-#[rustc_error]
+
fn main() { }
// Test that we check associated type bounds for WFedness.
#![feature(associated_type_defaults)]
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
trait ExtraCopy<T:Copy> { }
type Type1: ExtraCopy<T>;
}
-#[rustc_error]
+
fn main() { }
// Test that we check associated type default values for WFedness.
#![feature(associated_type_defaults)]
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
trait SomeTrait<'a> {
//~^ ERROR E0309
}
-#[rustc_error]
+
fn main() { }
// Test that we check associated type default values for WFedness.
#![feature(associated_type_defaults)]
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
struct IsCopy<T:Copy> { x: T }
//~^ ERROR E0277
}
-#[rustc_error]
+
fn main() { }
// Test that we check supertrait bounds for WFedness.
#![feature(associated_type_defaults)]
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
trait ExtraCopy<T:Copy> { }
{
}
-#[rustc_error]
+
fn main() { }
// Check that we test WF conditions for fn arguments. Because the
// current code is so goofy, this is only a warning for now.
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
#![allow(unused_variables)]
}
}
-#[rustc_error]
+
fn main() { }
// Check that we test WF conditions for fn arguments. Because the
// current code is so goofy, this is only a warning for now.
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
#![allow(unused_variables)]
}
}
-#[rustc_error]
+
fn main() { }
// Check that we test WF conditions for fn where clauses in a trait definition.
-#![feature(rustc_attrs)]
+
#![allow(dead_code)]
#![allow(unused_variables)]
// Here, Eq ought to be implemented.
}
-#[rustc_error]
+
fn main() { }
"aarch64-apple-ios",
"aarch64-fuchsia",
"aarch64-linux-android",
+ "aarch64-pc-windows-msvc",
"aarch64-unknown-cloudabi",
"aarch64-unknown-linux-gnu",
"aarch64-unknown-linux-musl",
"armv5te-unknown-linux-musleabi",
"armv7-apple-ios",
"armv7-linux-androideabi",
- "armv7-unknown-cloudabi-eabihf",
"armv7-unknown-linux-gnueabihf",
"armv7-unknown-linux-musleabihf",
"armebv7r-none-eabi",
"i686-linux-android",
"i686-pc-windows-gnu",
"i686-pc-windows-msvc",
- "i686-unknown-cloudabi",
"i686-unknown-freebsd",
"i686-unknown-linux-gnu",
"i686-unknown-linux-musl",
"mipsel-unknown-linux-gnu",
"mipsel-unknown-linux-musl",
"powerpc-unknown-linux-gnu",
- "powerpc-unknown-linux-gnuspe",
"powerpc64-unknown-linux-gnu",
"powerpc64le-unknown-linux-gnu",
- "powerpc64le-unknown-linux-musl",
"riscv32imc-unknown-none-elf",
"riscv32imac-unknown-none-elf",
"s390x-unknown-linux-gnu",
- "sparc-unknown-linux-gnu",
"sparc64-unknown-linux-gnu",
"sparcv9-sun-solaris",
"thumbv6m-none-eabi",
"x86_64-sun-solaris",
"x86_64-unknown-cloudabi",
"x86_64-unknown-freebsd",
- "x86_64-unknown-hermit",
"x86_64-unknown-linux-gnu",
"x86_64-unknown-linux-gnux32",
"x86_64-unknown-linux-musl",
-Subproject commit 29bf48582812212450f4caf7da1af3f18c52bfef
+Subproject commit fdea743be550ed8d7b61b2c908944cdd1290a6ad