Auto merge of #50807 - kennytm:rollup, r=kennytm
Rollup of 17 pull requests Successful merges: - #50170 (Implement From for more types on Cow) - #50638 (Don't unconditionally set CLOEXEC twice on every fd we open on Linux) - #50656 (Fix `fn main() -> impl Trait` for non-`Termination` trait) - #50669 (rustdoc: deprecate `#![doc(passes, plugins, no_default_passes)]`) - #50726 (read2: Use inner function instead of closure) - #50728 (Fix rustdoc panic with `impl Trait` in type parameters) - #50736 (env: remove unwrap in examples in favor of try op) - #50740 (Remove LazyBTreeMap.) - #50752 (Add missing error codes in libsyntax-ext asm) - #50779 (Make mutable_noalias and arg_align_attributes be tracked) - #50787 (Fix run-make wasm tests) - #50788 (Fix an ICE when casting a nonexistent const) - #50789 (Ensure libraries built in stage0 have unique metadata) - #50793 (tidy: Add a check for empty UI test files) - #50797 (fix a typo in signed-integer::from_str_radix()) - #50808 (Stabilize num::NonZeroU*) - #50809 (GitHub: Stop treating Cargo.lock as a generated file.) Failed merges:
This commit is contained in:
commit
b559710e58
78 changed files with 590 additions and 362 deletions
2
.gitattributes
vendored
2
.gitattributes
vendored
|
@ -7,4 +7,4 @@
|
|||
src/etc/installer/gfx/* binary
|
||||
*.woff binary
|
||||
src/vendor/** -text
|
||||
Cargo.lock -merge
|
||||
Cargo.lock -merge linguist-generated=false
|
||||
|
|
|
@ -592,7 +592,15 @@ impl<'a> Builder<'a> {
|
|||
|
||||
// FIXME: Temporary fix for https://github.com/rust-lang/cargo/issues/3005
|
||||
// Force cargo to output binaries with disambiguating hashes in the name
|
||||
cargo.env("__CARGO_DEFAULT_LIB_METADATA", &self.config.channel);
|
||||
let metadata = if compiler.stage == 0 {
|
||||
// Treat stage0 like special channel, whether it's a normal prior-
|
||||
// release rustc or a local rebuild with the same version, so we
|
||||
// never mix these libraries by accident.
|
||||
"bootstrap"
|
||||
} else {
|
||||
&self.config.channel
|
||||
};
|
||||
cargo.env("__CARGO_DEFAULT_LIB_METADATA", &metadata);
|
||||
|
||||
let stage;
|
||||
if compiler.stage == 0 && self.local_rebuild {
|
||||
|
|
|
@ -838,7 +838,7 @@ test!(RunFailFullDepsPretty {
|
|||
host: true
|
||||
});
|
||||
|
||||
host_test!(RunMake {
|
||||
default_test!(RunMake {
|
||||
path: "src/test/run-make",
|
||||
mode: "run-make",
|
||||
suite: "run-make"
|
||||
|
@ -1041,7 +1041,7 @@ impl Step for Compiletest {
|
|||
|
||||
// Only pass correct values for these flags for the `run-make` suite as it
|
||||
// requires that a C++ compiler was configured which isn't always the case.
|
||||
if !builder.config.dry_run && mode == "run-make" {
|
||||
if !builder.config.dry_run && suite == "run-make-fulldeps" {
|
||||
let llvm_components = output(Command::new(&llvm_config).arg("--components"));
|
||||
let llvm_cxxflags = output(Command::new(&llvm_config).arg("--cxxflags"));
|
||||
cmd.arg("--cc").arg(builder.cc(target))
|
||||
|
@ -1054,13 +1054,13 @@ impl Step for Compiletest {
|
|||
}
|
||||
}
|
||||
}
|
||||
if mode == "run-make" && !builder.config.llvm_enabled {
|
||||
if suite == "run-make-fulldeps" && !builder.config.llvm_enabled {
|
||||
builder.info(
|
||||
&format!("Ignoring run-make test suite as they generally don't work without LLVM"));
|
||||
return;
|
||||
}
|
||||
|
||||
if mode != "run-make" {
|
||||
if suite != "run-make-fulldeps" {
|
||||
cmd.arg("--cc").arg("")
|
||||
.arg("--cxx").arg("")
|
||||
.arg("--cflags").arg("")
|
||||
|
|
|
@ -102,7 +102,6 @@
|
|||
#![feature(lang_items)]
|
||||
#![feature(libc)]
|
||||
#![feature(needs_allocator)]
|
||||
#![feature(nonzero)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(pattern)]
|
||||
#![feature(pin)]
|
||||
|
|
|
@ -2240,6 +2240,14 @@ impl<'a> From<String> for Cow<'a, str> {
|
|||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "cow_from_string_ref", since = "1.28.0")]
|
||||
impl<'a> From<&'a String> for Cow<'a, str> {
|
||||
#[inline]
|
||||
fn from(s: &'a String) -> Cow<'a, str> {
|
||||
Cow::Borrowed(s.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "cow_str_from_iter", since = "1.12.0")]
|
||||
impl<'a> FromIterator<char> for Cow<'a, str> {
|
||||
fn from_iter<I: IntoIterator<Item = char>>(it: I) -> Cow<'a, str> {
|
||||
|
|
|
@ -2286,6 +2286,13 @@ impl<'a, T: Clone> From<Vec<T>> for Cow<'a, [T]> {
|
|||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "cow_from_vec_ref", since = "1.28.0")]
|
||||
impl<'a, T: Clone> From<&'a Vec<T>> for Cow<'a, [T]> {
|
||||
fn from(v: &'a Vec<T>) -> Cow<'a, [T]> {
|
||||
Cow::Borrowed(v.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, T> FromIterator<T> for Cow<'a, [T]> where T: Clone {
|
||||
fn from_iter<I: IntoIterator<Item = T>>(it: I) -> Cow<'a, [T]> {
|
||||
|
|
|
@ -171,7 +171,6 @@ pub mod prelude;
|
|||
|
||||
pub mod intrinsics;
|
||||
pub mod mem;
|
||||
pub mod nonzero;
|
||||
pub mod ptr;
|
||||
pub mod hint;
|
||||
|
||||
|
@ -221,6 +220,7 @@ pub mod heap {
|
|||
|
||||
// note: does not need to be public
|
||||
mod iter_private;
|
||||
mod nonzero;
|
||||
mod tuple;
|
||||
mod unit;
|
||||
|
||||
|
|
|
@ -9,103 +9,13 @@
|
|||
// except according to those terms.
|
||||
|
||||
//! Exposes the NonZero lang item which provides optimization hints.
|
||||
#![unstable(feature = "nonzero", reason = "deprecated", issue = "49137")]
|
||||
#![rustc_deprecated(reason = "use `std::ptr::NonNull` or `std::num::NonZero*` instead",
|
||||
since = "1.26.0")]
|
||||
#![allow(deprecated)]
|
||||
|
||||
use ops::CoerceUnsized;
|
||||
|
||||
/// Unsafe trait to indicate what types are usable with the NonZero struct
|
||||
pub unsafe trait Zeroable {
|
||||
/// Whether this value is zero
|
||||
fn is_zero(&self) -> bool;
|
||||
}
|
||||
|
||||
macro_rules! impl_zeroable_for_pointer_types {
|
||||
( $( $Ptr: ty )+ ) => {
|
||||
$(
|
||||
/// For fat pointers to be considered "zero", only the "data" part needs to be null.
|
||||
unsafe impl<T: ?Sized> Zeroable for $Ptr {
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool {
|
||||
(*self).is_null()
|
||||
}
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_zeroable_for_integer_types {
|
||||
( $( $Int: ty )+ ) => {
|
||||
$(
|
||||
unsafe impl Zeroable for $Int {
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool {
|
||||
*self == 0
|
||||
}
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
impl_zeroable_for_pointer_types! {
|
||||
*const T
|
||||
*mut T
|
||||
}
|
||||
|
||||
impl_zeroable_for_integer_types! {
|
||||
usize u8 u16 u32 u64 u128
|
||||
isize i8 i16 i32 i64 i128
|
||||
}
|
||||
|
||||
/// A wrapper type for raw pointers and integers that will never be
|
||||
/// NULL or 0 that might allow certain optimizations.
|
||||
#[lang = "non_zero"]
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
|
||||
pub struct NonZero<T: Zeroable>(pub(crate) T);
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
pub(crate) struct NonZero<T>(pub(crate) T);
|
||||
|
||||
impl<T: Zeroable> NonZero<T> {
|
||||
/// Creates an instance of NonZero with the provided value.
|
||||
/// You must indeed ensure that the value is actually "non-zero".
|
||||
#[inline]
|
||||
pub const unsafe fn new_unchecked(inner: T) -> Self {
|
||||
NonZero(inner)
|
||||
}
|
||||
|
||||
/// Creates an instance of NonZero with the provided value.
|
||||
#[inline]
|
||||
pub fn new(inner: T) -> Option<Self> {
|
||||
if inner.is_zero() {
|
||||
None
|
||||
} else {
|
||||
Some(NonZero(inner))
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the inner value.
|
||||
pub fn get(self) -> T {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Zeroable+CoerceUnsized<U>, U: Zeroable> CoerceUnsized<NonZero<U>> for NonZero<T> {}
|
||||
|
||||
impl<'a, T: ?Sized> From<&'a mut T> for NonZero<*mut T> {
|
||||
fn from(reference: &'a mut T) -> Self {
|
||||
NonZero(reference)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> From<&'a mut T> for NonZero<*const T> {
|
||||
fn from(reference: &'a mut T) -> Self {
|
||||
let ptr: *mut T = reference;
|
||||
NonZero(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> From<&'a T> for NonZero<*const T> {
|
||||
fn from(reference: &'a T) -> Self {
|
||||
NonZero(reference)
|
||||
}
|
||||
}
|
||||
impl<T: CoerceUnsized<U>, U> CoerceUnsized<NonZero<U>> for NonZero<T> {}
|
||||
|
|
|
@ -16,15 +16,14 @@ use convert::TryFrom;
|
|||
use fmt;
|
||||
use intrinsics;
|
||||
use mem;
|
||||
#[allow(deprecated)] use nonzero::NonZero;
|
||||
use nonzero::NonZero;
|
||||
use ops;
|
||||
use str::FromStr;
|
||||
|
||||
macro_rules! impl_nonzero_fmt {
|
||||
( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
|
||||
( ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
|
||||
$(
|
||||
#[$stability]
|
||||
#[allow(deprecated)]
|
||||
#[stable(feature = "nonzero", since = "1.28.0")]
|
||||
impl fmt::$Trait for $Ty {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
|
@ -36,7 +35,7 @@ macro_rules! impl_nonzero_fmt {
|
|||
}
|
||||
|
||||
macro_rules! nonzero_integers {
|
||||
( #[$stability: meta] #[$deprecation: meta] $( $Ty: ident($Int: ty); )+ ) => {
|
||||
( $( $Ty: ident($Int: ty); )+ ) => {
|
||||
$(
|
||||
/// An integer that is known not to equal zero.
|
||||
///
|
||||
|
@ -47,27 +46,24 @@ macro_rules! nonzero_integers {
|
|||
/// use std::mem::size_of;
|
||||
/// assert_eq!(size_of::<Option<std::num::NonZeroU32>>(), size_of::<u32>());
|
||||
/// ```
|
||||
#[$stability]
|
||||
#[$deprecation]
|
||||
#[allow(deprecated)]
|
||||
#[stable(feature = "nonzero", since = "1.28.0")]
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
pub struct $Ty(NonZero<$Int>);
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl $Ty {
|
||||
/// Create a non-zero without checking the value.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The value must not be zero.
|
||||
#[$stability]
|
||||
#[stable(feature = "nonzero", since = "1.28.0")]
|
||||
#[inline]
|
||||
pub const unsafe fn new_unchecked(n: $Int) -> Self {
|
||||
$Ty(NonZero(n))
|
||||
}
|
||||
|
||||
/// Create a non-zero if the given value is not zero.
|
||||
#[$stability]
|
||||
#[stable(feature = "nonzero", since = "1.28.0")]
|
||||
#[inline]
|
||||
pub fn new(n: $Int) -> Option<Self> {
|
||||
if n != 0 {
|
||||
|
@ -78,7 +74,7 @@ macro_rules! nonzero_integers {
|
|||
}
|
||||
|
||||
/// Returns the value as a primitive type.
|
||||
#[$stability]
|
||||
#[stable(feature = "nonzero", since = "1.28.0")]
|
||||
#[inline]
|
||||
pub fn get(self) -> $Int {
|
||||
self.0 .0
|
||||
|
@ -87,7 +83,6 @@ macro_rules! nonzero_integers {
|
|||
}
|
||||
|
||||
impl_nonzero_fmt! {
|
||||
#[$stability]
|
||||
(Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
|
||||
}
|
||||
)+
|
||||
|
@ -95,8 +90,6 @@ macro_rules! nonzero_integers {
|
|||
}
|
||||
|
||||
nonzero_integers! {
|
||||
#[unstable(feature = "nonzero", issue = "49137")]
|
||||
#[allow(deprecated)] // Redundant, works around "error: inconsistent lockstep iteration"
|
||||
NonZeroU8(u8);
|
||||
NonZeroU16(u16);
|
||||
NonZeroU32(u32);
|
||||
|
@ -105,19 +98,6 @@ nonzero_integers! {
|
|||
NonZeroUsize(usize);
|
||||
}
|
||||
|
||||
nonzero_integers! {
|
||||
#[unstable(feature = "nonzero", issue = "49137")]
|
||||
#[rustc_deprecated(since = "1.26.0", reason = "\
|
||||
signed non-zero integers are considered for removal due to lack of known use cases. \
|
||||
If you’re using them, please comment on https://github.com/rust-lang/rust/issues/49137")]
|
||||
NonZeroI8(i8);
|
||||
NonZeroI16(i16);
|
||||
NonZeroI32(i32);
|
||||
NonZeroI64(i64);
|
||||
NonZeroI128(i128);
|
||||
NonZeroIsize(isize);
|
||||
}
|
||||
|
||||
/// Provides intentionally-wrapped arithmetic on `T`.
|
||||
///
|
||||
/// Operations like `+` on `u32` values is intended to never overflow,
|
||||
|
@ -252,7 +232,7 @@ depending on `radix`:
|
|||
|
||||
* `0-9`
|
||||
* `a-z`
|
||||
* `a-z`
|
||||
* `A-Z`
|
||||
|
||||
# Panics
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ use fmt;
|
|||
use hash;
|
||||
use marker::{PhantomData, Unsize};
|
||||
use mem;
|
||||
#[allow(deprecated)] use nonzero::NonZero;
|
||||
use nonzero::NonZero;
|
||||
|
||||
use cmp::Ordering::{self, Less, Equal, Greater};
|
||||
|
||||
|
@ -2742,7 +2742,6 @@ impl<T: ?Sized> PartialOrd for *mut T {
|
|||
#[unstable(feature = "ptr_internals", issue = "0",
|
||||
reason = "use NonNull instead and consider PhantomData<T> \
|
||||
(if you also use #[may_dangle]), Send, and/or Sync")]
|
||||
#[allow(deprecated)]
|
||||
#[doc(hidden)]
|
||||
pub struct Unique<T: ?Sized> {
|
||||
pointer: NonZero<*const T>,
|
||||
|
@ -2790,7 +2789,6 @@ impl<T: Sized> Unique<T> {
|
|||
}
|
||||
|
||||
#[unstable(feature = "ptr_internals", issue = "0")]
|
||||
#[allow(deprecated)]
|
||||
impl<T: ?Sized> Unique<T> {
|
||||
/// Creates a new `Unique`.
|
||||
///
|
||||
|
@ -2855,7 +2853,6 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> {
|
|||
}
|
||||
|
||||
#[unstable(feature = "ptr_internals", issue = "0")]
|
||||
#[allow(deprecated)]
|
||||
impl<'a, T: ?Sized> From<&'a mut T> for Unique<T> {
|
||||
fn from(reference: &'a mut T) -> Self {
|
||||
Unique { pointer: NonZero(reference as _), _marker: PhantomData }
|
||||
|
@ -2863,7 +2860,6 @@ impl<'a, T: ?Sized> From<&'a mut T> for Unique<T> {
|
|||
}
|
||||
|
||||
#[unstable(feature = "ptr_internals", issue = "0")]
|
||||
#[allow(deprecated)]
|
||||
impl<'a, T: ?Sized> From<&'a T> for Unique<T> {
|
||||
fn from(reference: &'a T) -> Self {
|
||||
Unique { pointer: NonZero(reference as _), _marker: PhantomData }
|
||||
|
@ -2896,7 +2892,7 @@ impl<'a, T: ?Sized> From<NonNull<T>> for Unique<T> {
|
|||
/// provide a public API that follows the normal shared XOR mutable rules of Rust.
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
pub struct NonNull<T: ?Sized> {
|
||||
#[allow(deprecated)] pointer: NonZero<*const T>,
|
||||
pointer: NonZero<*const T>,
|
||||
}
|
||||
|
||||
/// `NonNull` pointers are not `Send` because the data they reference may be aliased.
|
||||
|
@ -2923,7 +2919,6 @@ impl<T: Sized> NonNull<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl<T: ?Sized> NonNull<T> {
|
||||
/// Creates a new `NonNull`.
|
||||
///
|
||||
|
@ -3054,7 +3049,6 @@ impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
#[allow(deprecated)]
|
||||
impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> {
|
||||
fn from(reference: &'a mut T) -> Self {
|
||||
NonNull { pointer: NonZero(reference as _) }
|
||||
|
@ -3062,7 +3056,6 @@ impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
#[allow(deprecated)]
|
||||
impl<'a, T: ?Sized> From<&'a T> for NonNull<T> {
|
||||
fn from(reference: &'a T) -> Self {
|
||||
NonNull { pointer: NonZero(reference as _) }
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#![feature(iterator_step_by)]
|
||||
#![feature(iterator_flatten)]
|
||||
#![feature(iterator_repeat_with)]
|
||||
#![feature(nonzero)]
|
||||
#![feature(pattern)]
|
||||
#![feature(range_is_empty)]
|
||||
#![feature(raw)]
|
||||
|
|
|
@ -19,10 +19,10 @@ use super::{CombinedSnapshot,
|
|||
use super::combine::CombineFields;
|
||||
use super::region_constraints::{TaintDirections};
|
||||
|
||||
use rustc_data_structures::lazy_btree_map::LazyBTreeMap;
|
||||
use ty::{self, TyCtxt, Binder, TypeFoldable};
|
||||
use ty::error::TypeError;
|
||||
use ty::relate::{Relate, RelateResult, TypeRelation};
|
||||
use std::collections::BTreeMap;
|
||||
use syntax_pos::Span;
|
||||
use util::nodemap::{FxHashMap, FxHashSet};
|
||||
|
||||
|
@ -247,8 +247,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
|
|||
snapshot: &CombinedSnapshot<'a, 'tcx>,
|
||||
debruijn: ty::DebruijnIndex,
|
||||
new_vars: &[ty::RegionVid],
|
||||
a_map: &LazyBTreeMap<ty::BoundRegion,
|
||||
ty::Region<'tcx>>,
|
||||
a_map: &BTreeMap<ty::BoundRegion, ty::Region<'tcx>>,
|
||||
r0: ty::Region<'tcx>)
|
||||
-> ty::Region<'tcx> {
|
||||
// Regions that pre-dated the LUB computation stay as they are.
|
||||
|
@ -344,8 +343,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
|
|||
snapshot: &CombinedSnapshot<'a, 'tcx>,
|
||||
debruijn: ty::DebruijnIndex,
|
||||
new_vars: &[ty::RegionVid],
|
||||
a_map: &LazyBTreeMap<ty::BoundRegion,
|
||||
ty::Region<'tcx>>,
|
||||
a_map: &BTreeMap<ty::BoundRegion, ty::Region<'tcx>>,
|
||||
a_vars: &[ty::RegionVid],
|
||||
b_vars: &[ty::RegionVid],
|
||||
r0: ty::Region<'tcx>)
|
||||
|
@ -414,7 +412,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
|
|||
|
||||
fn rev_lookup<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
span: Span,
|
||||
a_map: &LazyBTreeMap<ty::BoundRegion, ty::Region<'tcx>>,
|
||||
a_map: &BTreeMap<ty::BoundRegion, ty::Region<'tcx>>,
|
||||
r: ty::Region<'tcx>) -> ty::Region<'tcx>
|
||||
{
|
||||
for (a_br, a_r) in a_map {
|
||||
|
@ -437,7 +435,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
fn var_ids<'a, 'gcx, 'tcx>(fields: &CombineFields<'a, 'gcx, 'tcx>,
|
||||
map: &LazyBTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
|
||||
map: &BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
|
||||
-> Vec<ty::RegionVid> {
|
||||
map.iter()
|
||||
.map(|(_, &r)| match *r {
|
||||
|
|
|
@ -28,9 +28,9 @@ use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
|
|||
use ty::fold::TypeFoldable;
|
||||
use ty::relate::RelateResult;
|
||||
use traits::{self, ObligationCause, PredicateObligations};
|
||||
use rustc_data_structures::lazy_btree_map::LazyBTreeMap;
|
||||
use rustc_data_structures::unify as ut;
|
||||
use std::cell::{Cell, RefCell, Ref, RefMut};
|
||||
use std::collections::BTreeMap;
|
||||
use std::fmt;
|
||||
use syntax::ast;
|
||||
use errors::DiagnosticBuilder;
|
||||
|
@ -198,7 +198,7 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
|||
|
||||
/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
|
||||
/// region that each late-bound region was replaced with.
|
||||
pub type SkolemizationMap<'tcx> = LazyBTreeMap<ty::BoundRegion, ty::Region<'tcx>>;
|
||||
pub type SkolemizationMap<'tcx> = BTreeMap<ty::BoundRegion, ty::Region<'tcx>>;
|
||||
|
||||
/// See `error_reporting` module for more details
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -1235,7 +1235,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
span: Span,
|
||||
lbrct: LateBoundRegionConversionTime,
|
||||
value: &ty::Binder<T>)
|
||||
-> (T, LazyBTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
|
||||
-> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
|
||||
where T : TypeFoldable<'tcx>
|
||||
{
|
||||
self.tcx.replace_late_bound_regions(
|
||||
|
|
|
@ -56,7 +56,6 @@
|
|||
#![feature(never_type)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(non_exhaustive)]
|
||||
#![feature(nonzero)]
|
||||
#![feature(proc_macro_internals)]
|
||||
#![feature(quote)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
|
|
@ -1239,9 +1239,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
|
|||
"print the result of the translation item collection pass"),
|
||||
mir_opt_level: usize = (1, parse_uint, [TRACKED],
|
||||
"set the MIR optimization level (0-3, default: 1)"),
|
||||
mutable_noalias: bool = (false, parse_bool, [UNTRACKED],
|
||||
mutable_noalias: bool = (false, parse_bool, [TRACKED],
|
||||
"emit noalias metadata for mutable references"),
|
||||
arg_align_attributes: bool = (false, parse_bool, [UNTRACKED],
|
||||
arg_align_attributes: bool = (false, parse_bool, [TRACKED],
|
||||
"emit align metadata for reference arguments"),
|
||||
dump_mir: Option<String> = (None, parse_opt_string, [UNTRACKED],
|
||||
"dump MIR state at various points in translation"),
|
||||
|
|
|
@ -43,7 +43,7 @@ use middle::const_val::ConstVal;
|
|||
use hir::def_id::DefId;
|
||||
use ty::{self, Binder, Ty, TyCtxt, TypeFlags};
|
||||
|
||||
use rustc_data_structures::lazy_btree_map::LazyBTreeMap;
|
||||
use std::collections::BTreeMap;
|
||||
use std::fmt;
|
||||
use util::nodemap::FxHashSet;
|
||||
|
||||
|
@ -332,7 +332,7 @@ struct RegionReplacer<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
|||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
current_depth: u32,
|
||||
fld_r: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a),
|
||||
map: LazyBTreeMap<ty::BoundRegion, ty::Region<'tcx>>
|
||||
map: BTreeMap<ty::BoundRegion, ty::Region<'tcx>>
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
|
@ -347,7 +347,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
pub fn replace_late_bound_regions<T,F>(self,
|
||||
value: &Binder<T>,
|
||||
mut f: F)
|
||||
-> (T, LazyBTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
|
||||
-> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
|
||||
where F : FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
|
||||
T : TypeFoldable<'tcx>,
|
||||
{
|
||||
|
@ -460,7 +460,7 @@ impl<'a, 'gcx, 'tcx> RegionReplacer<'a, 'gcx, 'tcx> {
|
|||
tcx,
|
||||
current_depth: 1,
|
||||
fld_r,
|
||||
map: LazyBTreeMap::default()
|
||||
map: BTreeMap::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,108 +0,0 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::collections::btree_map;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
/// A thin wrapper around BTreeMap that avoids allocating upon creation.
|
||||
///
|
||||
/// Vec, HashSet and HashMap all have the nice feature that they don't do any
|
||||
/// heap allocation when creating a new structure of the default size. In
|
||||
/// contrast, BTreeMap *does* allocate in that situation. The compiler uses
|
||||
/// B-Tree maps in some places such that many maps are created but few are
|
||||
/// inserted into, so having a BTreeMap alternative that avoids allocating on
|
||||
/// creation is a performance win.
|
||||
///
|
||||
/// Only a fraction of BTreeMap's functionality is currently supported.
|
||||
/// Additional functionality should be added on demand.
|
||||
#[derive(Debug)]
|
||||
pub struct LazyBTreeMap<K, V>(Option<BTreeMap<K, V>>);
|
||||
|
||||
impl<K, V> LazyBTreeMap<K, V> {
|
||||
pub fn new() -> LazyBTreeMap<K, V> {
|
||||
LazyBTreeMap(None)
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> Iter<K, V> {
|
||||
Iter(self.0.as_ref().map(|btm| btm.iter()))
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.as_ref().map_or(true, |btm| btm.is_empty())
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Ord, V> LazyBTreeMap<K, V> {
|
||||
fn instantiate(&mut self) -> &mut BTreeMap<K, V> {
|
||||
if let Some(ref mut btm) = self.0 {
|
||||
btm
|
||||
} else {
|
||||
let btm = BTreeMap::new();
|
||||
self.0 = Some(btm);
|
||||
self.0.as_mut().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, key: K, value: V) -> Option<V> {
|
||||
self.instantiate().insert(key, value)
|
||||
}
|
||||
|
||||
pub fn entry(&mut self, key: K) -> btree_map::Entry<K, V> {
|
||||
self.instantiate().entry(key)
|
||||
}
|
||||
|
||||
pub fn values<'a>(&'a self) -> Values<'a, K, V> {
|
||||
Values(self.0.as_ref().map(|btm| btm.values()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Ord, V> Default for LazyBTreeMap<K, V> {
|
||||
fn default() -> LazyBTreeMap<K, V> {
|
||||
LazyBTreeMap::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K: 'a, V: 'a> IntoIterator for &'a LazyBTreeMap<K, V> {
|
||||
type Item = (&'a K, &'a V);
|
||||
type IntoIter = Iter<'a, K, V>;
|
||||
|
||||
fn into_iter(self) -> Iter<'a, K, V> {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Iter<'a, K: 'a, V: 'a>(Option<btree_map::Iter<'a, K, V>>);
|
||||
|
||||
impl<'a, K: 'a, V: 'a> Iterator for Iter<'a, K, V> {
|
||||
type Item = (&'a K, &'a V);
|
||||
|
||||
fn next(&mut self) -> Option<(&'a K, &'a V)> {
|
||||
self.0.as_mut().and_then(|iter| iter.next())
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.0.as_ref().map_or_else(|| (0, Some(0)), |iter| iter.size_hint())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Values<'a, K: 'a, V: 'a>(Option<btree_map::Values<'a, K, V>>);
|
||||
|
||||
impl<'a, K, V> Iterator for Values<'a, K, V> {
|
||||
type Item = &'a V;
|
||||
|
||||
fn next(&mut self) -> Option<&'a V> {
|
||||
self.0.as_mut().and_then(|values| values.next())
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.0.as_ref().map_or_else(|| (0, Some(0)), |values| values.size_hint())
|
||||
}
|
||||
}
|
||||
|
|
@ -21,7 +21,6 @@
|
|||
html_root_url = "https://doc.rust-lang.org/nightly/")]
|
||||
|
||||
#![feature(collections_range)]
|
||||
#![feature(nonzero)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(fn_traits)]
|
||||
#![feature(unsize)]
|
||||
|
@ -61,7 +60,6 @@ pub mod bitvec;
|
|||
pub mod graph;
|
||||
pub mod indexed_set;
|
||||
pub mod indexed_vec;
|
||||
pub mod lazy_btree_map;
|
||||
pub mod obligation_forest;
|
||||
pub mod sip128;
|
||||
pub mod snapshot_map;
|
||||
|
|
|
@ -30,7 +30,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
|
|||
#![feature(exhaustive_patterns)]
|
||||
#![feature(range_contains)]
|
||||
#![feature(rustc_diagnostic_macros)]
|
||||
#![feature(nonzero)]
|
||||
#![feature(inclusive_range_methods)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(never_type)]
|
||||
|
|
|
@ -275,7 +275,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
|
|||
hir::ExprCast(ref from, _) => {
|
||||
debug!("Checking const cast(id={})", from.id);
|
||||
match v.tables.cast_kinds().get(from.hir_id) {
|
||||
None => span_bug!(e.span, "no kind for cast"),
|
||||
None => v.tcx.sess.delay_span_bug(e.span, "no kind for cast"),
|
||||
Some(&CastKind::PtrAddrCast) | Some(&CastKind::FnPtrAddrCast) => {
|
||||
v.promotable = false;
|
||||
}
|
||||
|
|
|
@ -1031,13 +1031,13 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
|
|||
let mut fcx = FnCtxt::new(inherited, param_env, body.value.id);
|
||||
*fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
|
||||
|
||||
let ret_ty = fn_sig.output();
|
||||
fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::SizedReturnType);
|
||||
let ret_ty = fcx.instantiate_anon_types_from_return_value(fn_id, &ret_ty);
|
||||
fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
|
||||
let declared_ret_ty = fn_sig.output();
|
||||
fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
|
||||
let revealed_ret_ty = fcx.instantiate_anon_types_from_return_value(fn_id, &declared_ret_ty);
|
||||
fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
|
||||
fn_sig = fcx.tcx.mk_fn_sig(
|
||||
fn_sig.inputs().iter().cloned(),
|
||||
ret_ty,
|
||||
revealed_ret_ty,
|
||||
fn_sig.variadic,
|
||||
fn_sig.unsafety,
|
||||
fn_sig.abi
|
||||
|
@ -1119,7 +1119,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
|
|||
actual_return_ty = fcx.next_diverging_ty_var(
|
||||
TypeVariableOrigin::DivergingFn(span));
|
||||
}
|
||||
fcx.demand_suptype(span, ret_ty, actual_return_ty);
|
||||
fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
|
||||
|
||||
// Check that the main return type implements the termination trait.
|
||||
if let Some(term_id) = fcx.tcx.lang_items().termination() {
|
||||
|
@ -1127,7 +1127,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
|
|||
if id == fn_id {
|
||||
match entry_type {
|
||||
config::EntryMain => {
|
||||
let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty)));
|
||||
let substs = fcx.tcx.mk_substs(iter::once(Kind::from(declared_ret_ty)));
|
||||
let trait_ref = ty::TraitRef::new(term_id, substs);
|
||||
let return_ty_span = decl.output.span();
|
||||
let cause = traits::ObligationCause::new(
|
||||
|
|
|
@ -1754,16 +1754,39 @@ pub struct Generics {
|
|||
|
||||
impl Clean<Generics> for hir::Generics {
|
||||
fn clean(&self, cx: &DocContext) -> Generics {
|
||||
let mut params = Vec::with_capacity(self.params.len());
|
||||
for p in &self.params {
|
||||
let p = p.clean(cx);
|
||||
if let GenericParamDef::Type(ref tp) = p {
|
||||
if tp.synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) {
|
||||
cx.impl_trait_bounds.borrow_mut().insert(tp.did, tp.bounds.clone());
|
||||
}
|
||||
// Synthetic type-parameters are inserted after normal ones.
|
||||
// In order for normal parameters to be able to refer to synthetic ones,
|
||||
// scans them first.
|
||||
fn is_impl_trait(param: &hir::GenericParam) -> bool {
|
||||
if let hir::GenericParam::Type(ref tp) = param {
|
||||
tp.synthetic == Some(hir::SyntheticTyParamKind::ImplTrait)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
let impl_trait_params = self.params
|
||||
.iter()
|
||||
.filter(|p| is_impl_trait(p))
|
||||
.map(|p| {
|
||||
let p = p.clean(cx);
|
||||
if let GenericParamDef::Type(ref tp) = p {
|
||||
cx.impl_trait_bounds
|
||||
.borrow_mut()
|
||||
.insert(tp.did, tp.bounds.clone());
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
p
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut params = Vec::with_capacity(self.params.len());
|
||||
for p in self.params.iter().filter(|p| !is_impl_trait(p)) {
|
||||
let p = p.clean(cx);
|
||||
params.push(p);
|
||||
}
|
||||
params.extend(impl_trait_params);
|
||||
|
||||
let mut g = Generics {
|
||||
params,
|
||||
where_predicates: self.where_clause.predicates.clean(cx)
|
||||
|
|
|
@ -654,6 +654,20 @@ where R: 'static + Send,
|
|||
|
||||
krate.version = crate_version;
|
||||
|
||||
let diag = core::new_handler(error_format, None);
|
||||
|
||||
fn report_deprecated_attr(name: &str, diag: &errors::Handler) {
|
||||
let mut msg = diag.struct_warn(&format!("the `#![doc({})]` attribute is \
|
||||
considered deprecated", name));
|
||||
msg.warn("please see https://github.com/rust-lang/rust/issues/44136");
|
||||
|
||||
if name == "no_default_passes" {
|
||||
msg.help("you may want to use `#![doc(document_private_items)]`");
|
||||
}
|
||||
|
||||
msg.emit();
|
||||
}
|
||||
|
||||
// Process all of the crate attributes, extracting plugin metadata along
|
||||
// with the passes which we are supposed to run.
|
||||
for attr in krate.module.as_ref().unwrap().attrs.lists("doc") {
|
||||
|
@ -661,18 +675,34 @@ where R: 'static + Send,
|
|||
let name = name.as_ref().map(|s| &s[..]);
|
||||
if attr.is_word() {
|
||||
if name == Some("no_default_passes") {
|
||||
report_deprecated_attr("no_default_passes", &diag);
|
||||
default_passes = false;
|
||||
}
|
||||
} else if let Some(value) = attr.value_str() {
|
||||
let sink = match name {
|
||||
Some("passes") => &mut passes,
|
||||
Some("plugins") => &mut plugins,
|
||||
Some("passes") => {
|
||||
report_deprecated_attr("passes = \"...\"", &diag);
|
||||
&mut passes
|
||||
},
|
||||
Some("plugins") => {
|
||||
report_deprecated_attr("plugins = \"...\"", &diag);
|
||||
&mut plugins
|
||||
},
|
||||
_ => continue,
|
||||
};
|
||||
for p in value.as_str().split_whitespace() {
|
||||
sink.push(p.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
if attr.is_word() && name == Some("document_private_items") {
|
||||
default_passes = false;
|
||||
|
||||
passes = vec![
|
||||
String::from("collapse-docs"),
|
||||
String::from("unindent-comments"),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if default_passes {
|
||||
|
|
|
@ -49,9 +49,11 @@ use sys::os as os_imp;
|
|||
/// ```
|
||||
/// use std::env;
|
||||
///
|
||||
/// // We assume that we are in a valid directory.
|
||||
/// let path = env::current_dir().unwrap();
|
||||
/// println!("The current directory is {}", path.display());
|
||||
/// fn main() -> std::io::Result<()> {
|
||||
/// let path = env::current_dir()?;
|
||||
/// println!("The current directory is {}", path.display());
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "env", since = "1.0.0")]
|
||||
pub fn current_dir() -> io::Result<PathBuf> {
|
||||
|
@ -441,15 +443,18 @@ pub struct JoinPathsError {
|
|||
/// Joining paths on a Unix-like platform:
|
||||
///
|
||||
/// ```
|
||||
/// # if cfg!(unix) {
|
||||
/// use std::env;
|
||||
/// use std::ffi::OsString;
|
||||
/// use std::path::Path;
|
||||
///
|
||||
/// let paths = [Path::new("/bin"), Path::new("/usr/bin")];
|
||||
/// let path_os_string = env::join_paths(paths.iter()).unwrap();
|
||||
/// assert_eq!(path_os_string, OsString::from("/bin:/usr/bin"));
|
||||
/// fn main() -> Result<(), env::JoinPathsError> {
|
||||
/// # if cfg!(unix) {
|
||||
/// let paths = [Path::new("/bin"), Path::new("/usr/bin")];
|
||||
/// let path_os_string = env::join_paths(paths.iter())?;
|
||||
/// assert_eq!(path_os_string, OsString::from("/bin:/usr/bin"));
|
||||
/// # }
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Joining a path containing a colon on a Unix-like platform results in an error:
|
||||
|
@ -471,11 +476,15 @@ pub struct JoinPathsError {
|
|||
/// use std::env;
|
||||
/// use std::path::PathBuf;
|
||||
///
|
||||
/// if let Some(path) = env::var_os("PATH") {
|
||||
/// let mut paths = env::split_paths(&path).collect::<Vec<_>>();
|
||||
/// paths.push(PathBuf::from("/home/xyz/bin"));
|
||||
/// let new_path = env::join_paths(paths).unwrap();
|
||||
/// env::set_var("PATH", &new_path);
|
||||
/// fn main() -> Result<(), env::JoinPathsError> {
|
||||
/// if let Some(path) = env::var_os("PATH") {
|
||||
/// let mut paths = env::split_paths(&path).collect::<Vec<_>>();
|
||||
/// paths.push(PathBuf::from("/home/xyz/bin"));
|
||||
/// let new_path = env::join_paths(paths)?;
|
||||
/// env::set_var("PATH", &new_path);
|
||||
/// }
|
||||
///
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "env", since = "1.0.0")]
|
||||
|
|
|
@ -682,6 +682,14 @@ impl Borrow<CStr> for CString {
|
|||
fn borrow(&self) -> &CStr { self }
|
||||
}
|
||||
|
||||
#[stable(feature = "cstring_from_cow_cstr", since = "1.28.0")]
|
||||
impl<'a> From<Cow<'a, CStr>> for CString {
|
||||
#[inline]
|
||||
fn from(s: Cow<'a, CStr>) -> Self {
|
||||
s.into_owned()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "box_from_c_str", since = "1.17.0")]
|
||||
impl<'a> From<&'a CStr> for Box<CStr> {
|
||||
fn from(s: &'a CStr) -> Box<CStr> {
|
||||
|
@ -706,6 +714,30 @@ impl From<CString> for Box<CStr> {
|
|||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "cow_from_cstr", since = "1.28.0")]
|
||||
impl<'a> From<CString> for Cow<'a, CStr> {
|
||||
#[inline]
|
||||
fn from(s: CString) -> Cow<'a, CStr> {
|
||||
Cow::Owned(s)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "cow_from_cstr", since = "1.28.0")]
|
||||
impl<'a> From<&'a CStr> for Cow<'a, CStr> {
|
||||
#[inline]
|
||||
fn from(s: &'a CStr) -> Cow<'a, CStr> {
|
||||
Cow::Borrowed(s)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "cow_from_cstr", since = "1.28.0")]
|
||||
impl<'a> From<&'a CString> for Cow<'a, CStr> {
|
||||
#[inline]
|
||||
fn from(s: &'a CString) -> Cow<'a, CStr> {
|
||||
Cow::Borrowed(s.as_c_str())
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "shared_from_slice2", since = "1.24.0")]
|
||||
impl From<CString> for Arc<CStr> {
|
||||
#[inline]
|
||||
|
|
|
@ -664,6 +664,38 @@ impl<'a> From<&'a OsStr> for Rc<OsStr> {
|
|||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "cow_from_osstr", since = "1.28.0")]
|
||||
impl<'a> From<OsString> for Cow<'a, OsStr> {
|
||||
#[inline]
|
||||
fn from(s: OsString) -> Cow<'a, OsStr> {
|
||||
Cow::Owned(s)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "cow_from_osstr", since = "1.28.0")]
|
||||
impl<'a> From<&'a OsStr> for Cow<'a, OsStr> {
|
||||
#[inline]
|
||||
fn from(s: &'a OsStr) -> Cow<'a, OsStr> {
|
||||
Cow::Borrowed(s)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "cow_from_osstr", since = "1.28.0")]
|
||||
impl<'a> From<&'a OsString> for Cow<'a, OsStr> {
|
||||
#[inline]
|
||||
fn from(s: &'a OsString) -> Cow<'a, OsStr> {
|
||||
Cow::Borrowed(s.as_os_str())
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "osstring_from_cow_osstr", since = "1.28.0")]
|
||||
impl<'a> From<Cow<'a, OsStr>> for OsString {
|
||||
#[inline]
|
||||
fn from(s: Cow<'a, OsStr>) -> Self {
|
||||
s.into_owned()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "box_default_extra", since = "1.17.0")]
|
||||
impl Default for Box<OsStr> {
|
||||
fn default() -> Box<OsStr> {
|
||||
|
|
|
@ -277,7 +277,6 @@
|
|||
#![feature(needs_panic_runtime)]
|
||||
#![feature(never_type)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(nonzero)]
|
||||
#![feature(num_bits_bytes)]
|
||||
#![feature(old_wrapping)]
|
||||
#![feature(on_unimplemented)]
|
||||
|
|
|
@ -21,12 +21,8 @@ pub use core::num::{FpCategory, ParseIntError, ParseFloatError, TryFromIntError}
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::num::Wrapping;
|
||||
|
||||
#[unstable(feature = "nonzero", issue = "49137")]
|
||||
#[allow(deprecated)]
|
||||
pub use core::num::{
|
||||
NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32,
|
||||
NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize,
|
||||
};
|
||||
#[stable(feature = "nonzero", since = "1.28.0")]
|
||||
pub use core::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize};
|
||||
|
||||
#[cfg(test)] use fmt;
|
||||
#[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem};
|
||||
|
|
|
@ -1504,6 +1504,22 @@ impl<'a> From<PathBuf> for Cow<'a, Path> {
|
|||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "cow_from_pathbuf_ref", since = "1.28.0")]
|
||||
impl<'a> From<&'a PathBuf> for Cow<'a, Path> {
|
||||
#[inline]
|
||||
fn from(p: &'a PathBuf) -> Cow<'a, Path> {
|
||||
Cow::Borrowed(p.as_path())
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "pathbuf_from_cow_path", since = "1.28.0")]
|
||||
impl<'a> From<Cow<'a, Path>> for PathBuf {
|
||||
#[inline]
|
||||
fn from(p: Cow<'a, Path>) -> Self {
|
||||
p.into_owned()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "shared_from_slice2", since = "1.24.0")]
|
||||
impl From<PathBuf> for Arc<Path> {
|
||||
#[inline]
|
||||
|
|
|
@ -154,6 +154,13 @@ impl FileDesc {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn get_cloexec(&self) -> io::Result<bool> {
|
||||
unsafe {
|
||||
Ok((cvt(libc::fcntl(self.fd, libc::F_GETFD))? & libc::FD_CLOEXEC) != 0)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_env = "newlib",
|
||||
target_os = "solaris",
|
||||
target_os = "emscripten",
|
||||
|
|
|
@ -441,15 +441,48 @@ impl File {
|
|||
|
||||
// Currently the standard library supports Linux 2.6.18 which did not
|
||||
// have the O_CLOEXEC flag (passed above). If we're running on an older
|
||||
// Linux kernel then the flag is just ignored by the OS, so we continue
|
||||
// to explicitly ask for a CLOEXEC fd here.
|
||||
// Linux kernel then the flag is just ignored by the OS. After we open
|
||||
// the first file, we check whether it has CLOEXEC set. If it doesn't,
|
||||
// we will explicitly ask for a CLOEXEC fd for every further file we
|
||||
// open, if it does, we will skip that step.
|
||||
//
|
||||
// The CLOEXEC flag, however, is supported on versions of macOS/BSD/etc
|
||||
// that we support, so we only do this on Linux currently.
|
||||
if cfg!(target_os = "linux") {
|
||||
fd.set_cloexec()?;
|
||||
#[cfg(target_os = "linux")]
|
||||
fn ensure_cloexec(fd: &FileDesc) -> io::Result<()> {
|
||||
use sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
const OPEN_CLOEXEC_UNKNOWN: usize = 0;
|
||||
const OPEN_CLOEXEC_SUPPORTED: usize = 1;
|
||||
const OPEN_CLOEXEC_NOTSUPPORTED: usize = 2;
|
||||
static OPEN_CLOEXEC: AtomicUsize = AtomicUsize::new(OPEN_CLOEXEC_UNKNOWN);
|
||||
|
||||
let need_to_set;
|
||||
match OPEN_CLOEXEC.load(Ordering::Relaxed) {
|
||||
OPEN_CLOEXEC_UNKNOWN => {
|
||||
need_to_set = !fd.get_cloexec()?;
|
||||
OPEN_CLOEXEC.store(if need_to_set {
|
||||
OPEN_CLOEXEC_NOTSUPPORTED
|
||||
} else {
|
||||
OPEN_CLOEXEC_SUPPORTED
|
||||
}, Ordering::Relaxed);
|
||||
},
|
||||
OPEN_CLOEXEC_SUPPORTED => need_to_set = false,
|
||||
OPEN_CLOEXEC_NOTSUPPORTED => need_to_set = true,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
if need_to_set {
|
||||
fd.set_cloexec()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
fn ensure_cloexec(_: &FileDesc) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
ensure_cloexec(&fd)?;
|
||||
Ok(File(fd))
|
||||
}
|
||||
|
||||
|
|
|
@ -100,24 +100,6 @@ pub fn read2(p1: AnonPipe,
|
|||
// wait for either pipe to become readable using `poll`
|
||||
cvt_r(|| unsafe { libc::poll(fds.as_mut_ptr(), 2, -1) })?;
|
||||
|
||||
// Read as much as we can from each pipe, ignoring EWOULDBLOCK or
|
||||
// EAGAIN. If we hit EOF, then this will happen because the underlying
|
||||
// reader will return Ok(0), in which case we'll see `Ok` ourselves. In
|
||||
// this case we flip the other fd back into blocking mode and read
|
||||
// whatever's leftover on that file descriptor.
|
||||
let read = |fd: &FileDesc, dst: &mut Vec<u8>| {
|
||||
match fd.read_to_end(dst) {
|
||||
Ok(_) => Ok(true),
|
||||
Err(e) => {
|
||||
if e.raw_os_error() == Some(libc::EWOULDBLOCK) ||
|
||||
e.raw_os_error() == Some(libc::EAGAIN) {
|
||||
Ok(false)
|
||||
} else {
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
if fds[0].revents != 0 && read(&p1, v1)? {
|
||||
p2.set_nonblocking(false)?;
|
||||
return p2.read_to_end(v2).map(|_| ());
|
||||
|
@ -127,4 +109,23 @@ pub fn read2(p1: AnonPipe,
|
|||
return p1.read_to_end(v1).map(|_| ());
|
||||
}
|
||||
}
|
||||
|
||||
// Read as much as we can from each pipe, ignoring EWOULDBLOCK or
|
||||
// EAGAIN. If we hit EOF, then this will happen because the underlying
|
||||
// reader will return Ok(0), in which case we'll see `Ok` ourselves. In
|
||||
// this case we flip the other fd back into blocking mode and read
|
||||
// whatever's leftover on that file descriptor.
|
||||
fn read(fd: &FileDesc, dst: &mut Vec<u8>) -> Result<bool, io::Error> {
|
||||
match fd.read_to_end(dst) {
|
||||
Ok(_) => Ok(true),
|
||||
Err(e) => {
|
||||
if e.raw_os_error() == Some(libc::EWOULDBLOCK) ||
|
||||
e.raw_os_error() == Some(libc::EAGAIN) {
|
||||
Ok(false)
|
||||
} else {
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,9 +179,11 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
|
|||
let (constraint, _str_style) = panictry!(p.parse_str());
|
||||
|
||||
if constraint.as_str().starts_with("=") {
|
||||
cx.span_err(p.prev_span, "input operand constraint contains '='");
|
||||
span_err_if_not_stage0!(cx, p.prev_span, E0662,
|
||||
"input operand constraint contains '='");
|
||||
} else if constraint.as_str().starts_with("+") {
|
||||
cx.span_err(p.prev_span, "input operand constraint contains '+'");
|
||||
span_err_if_not_stage0!(cx, p.prev_span, E0663,
|
||||
"input operand constraint contains '+'");
|
||||
}
|
||||
|
||||
panictry!(p.expect(&token::OpenDelim(token::Paren)));
|
||||
|
@ -203,7 +205,8 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
|
|||
if OPTIONS.iter().any(|&opt| s == opt) {
|
||||
cx.span_warn(p.prev_span, "expected a clobber, found an option");
|
||||
} else if s.as_str().starts_with("{") || s.as_str().ends_with("}") {
|
||||
cx.span_err(p.prev_span, "clobber should not be surrounded by braces");
|
||||
span_err_if_not_stage0!(cx, p.prev_span, E0664,
|
||||
"clobber should not be surrounded by braces");
|
||||
}
|
||||
|
||||
clobs.push(s);
|
||||
|
|
|
@ -38,6 +38,58 @@ let a;
|
|||
asm!("nop" : "r"(a));
|
||||
```
|
||||
|
||||
Considering that this would be a long explanation, we instead recommend you to
|
||||
take a look at the unstable book:
|
||||
https://doc.rust-lang.org/unstable-book/language-features/asm.html
|
||||
"##,
|
||||
|
||||
E0662: r##"
|
||||
An invalid input operand constraint was passed to the `asm` macro (third line).
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0662
|
||||
asm!("xor %eax, %eax"
|
||||
:
|
||||
: "=test"("a")
|
||||
);
|
||||
```
|
||||
|
||||
Considering that this would be a long explanation, we instead recommend you to
|
||||
take a look at the unstable book:
|
||||
https://doc.rust-lang.org/unstable-book/language-features/asm.html
|
||||
"##,
|
||||
|
||||
E0663: r##"
|
||||
An invalid input operand constraint was passed to the `asm` macro (third line).
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0663
|
||||
asm!("xor %eax, %eax"
|
||||
:
|
||||
: "+test"("a")
|
||||
);
|
||||
```
|
||||
|
||||
Considering that this would be a long explanation, we instead recommend you to
|
||||
take a look at the unstable book:
|
||||
https://doc.rust-lang.org/unstable-book/language-features/asm.html
|
||||
"##,
|
||||
|
||||
E0664: r##"
|
||||
A clobber was surrounded by braces in the `asm` macro.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0663
|
||||
asm!("mov $$0x200, %eax"
|
||||
:
|
||||
:
|
||||
: "{eax}"
|
||||
);
|
||||
```
|
||||
|
||||
Considering that this would be a long explanation, we instead recommend you to
|
||||
take a look at the unstable book:
|
||||
https://doc.rust-lang.org/unstable-book/language-features/asm.html
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# min-llvm-version 4.0
|
||||
# ignore-mingw
|
||||
|
||||
-include ../../run-make-fulldeps/tools.mk
|
||||
-include ../tools.mk
|
||||
|
||||
# This test makes sure that the expected .llvmbc sections for use by
|
||||
# linker-based LTO are available in object files when compiling with
|
|
@ -10,11 +10,9 @@
|
|||
|
||||
// https://github.com/rust-lang/rust/issues/41898
|
||||
|
||||
#![feature(nonzero, const_fn)]
|
||||
extern crate core;
|
||||
use core::nonzero::NonZero;
|
||||
use std::num::NonZeroU64;
|
||||
|
||||
fn main() {
|
||||
const FOO: NonZero<u64> = unsafe { NonZero::new_unchecked(2) };
|
||||
const FOO: NonZeroU64 = unsafe { NonZeroU64::new_unchecked(2) };
|
||||
if let FOO = FOO {}
|
||||
}
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(nonzero, core)]
|
||||
|
||||
use std::mem::size_of;
|
||||
use std::num::NonZeroUsize;
|
||||
use std::ptr::NonNull;
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
// 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(termination_trait_lib)]
|
||||
|
||||
fn main() -> impl std::process::Termination { }
|
17
src/test/rustdoc-ui/deprecated-attrs.rs
Normal file
17
src/test/rustdoc-ui/deprecated-attrs.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
// 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
|
||||
|
||||
#![doc(no_default_passes, passes = "collapse-docs unindent-comments")]
|
||||
|
||||
struct SomeStruct;
|
||||
|
||||
pub struct OtherStruct;
|
9
src/test/rustdoc-ui/deprecated-attrs.stderr
Normal file
9
src/test/rustdoc-ui/deprecated-attrs.stderr
Normal file
|
@ -0,0 +1,9 @@
|
|||
warning: the `#![doc(no_default_passes)]` attribute is considered deprecated
|
||||
|
|
||||
= warning: please see https://github.com/rust-lang/rust/issues/44136
|
||||
= help: you may want to use `#![doc(document_private_items)]`
|
||||
|
||||
warning: the `#![doc(passes = "...")]` attribute is considered deprecated
|
||||
|
|
||||
= warning: please see https://github.com/rust-lang/rust/issues/44136
|
||||
|
|
@ -8,10 +8,10 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(universal_impl_trait)]
|
||||
#![crate_name = "foo"]
|
||||
|
||||
use std::io::Read;
|
||||
use std::borrow::Borrow;
|
||||
|
||||
// @has foo/fn.foo.html
|
||||
// @has - //pre 'foo('
|
||||
|
@ -51,3 +51,15 @@ impl<T> S<T> {
|
|||
// @has - 'method</a>('
|
||||
// @matches - '_x: impl <a class="trait" href="[^"]+/trait\.Debug\.html"'
|
||||
impl<T> Trait for S<T> {}
|
||||
|
||||
// @has foo/fn.much_universe.html
|
||||
// @matches - 'T:.+Borrow.+impl .+trait\.Trait\.html'
|
||||
// @matches - 'U:.+IntoIterator.+= impl.+Iterator\.html.+= impl.+Clone\.html'
|
||||
// @matches - '_: impl .+trait\.Read\.html.+ \+ .+trait\.Clone\.html'
|
||||
pub fn much_universe<
|
||||
T: Borrow<impl Trait>,
|
||||
U: IntoIterator<Item = impl Iterator<Item = impl Clone>>,
|
||||
>(
|
||||
_: impl Read + Clone,
|
||||
) {
|
||||
}
|
||||
|
|
20
src/test/ui/E0662.rs
Normal file
20
src/test/ui/E0662.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
// 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.
|
||||
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(asm)]
|
||||
|
||||
fn main() {
|
||||
asm!("xor %eax, %eax"
|
||||
:
|
||||
: "=test"("a") //~ ERROR E0662
|
||||
);
|
||||
}
|
9
src/test/ui/E0662.stderr
Normal file
9
src/test/ui/E0662.stderr
Normal file
|
@ -0,0 +1,9 @@
|
|||
error[E0662]: input operand constraint contains '='
|
||||
--> $DIR/E0662.rs:18:12
|
||||
|
|
||||
LL | : "=test"("a") //~ ERROR E0662
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0662`.
|
20
src/test/ui/E0663.rs
Normal file
20
src/test/ui/E0663.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
// 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.
|
||||
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(asm)]
|
||||
|
||||
fn main() {
|
||||
asm!("xor %eax, %eax"
|
||||
:
|
||||
: "+test"("a") //~ ERROR E0663
|
||||
);
|
||||
}
|
9
src/test/ui/E0663.stderr
Normal file
9
src/test/ui/E0663.stderr
Normal file
|
@ -0,0 +1,9 @@
|
|||
error[E0663]: input operand constraint contains '+'
|
||||
--> $DIR/E0663.rs:18:12
|
||||
|
|
||||
LL | : "+test"("a") //~ ERROR E0663
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0663`.
|
21
src/test/ui/E0664.rs
Normal file
21
src/test/ui/E0664.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
// 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.
|
||||
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(asm)]
|
||||
|
||||
fn main() {
|
||||
asm!("mov $$0x200, %eax"
|
||||
:
|
||||
:
|
||||
: "{eax}" //~ ERROR E0664
|
||||
);
|
||||
}
|
9
src/test/ui/E0664.stderr
Normal file
9
src/test/ui/E0664.stderr
Normal file
|
@ -0,0 +1,9 @@
|
|||
error[E0664]: clobber should not be surrounded by braces
|
||||
--> $DIR/E0664.rs:19:12
|
||||
|
|
||||
LL | : "{eax}" //~ ERROR E0664
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0664`.
|
15
src/test/ui/issue-50599.rs
Normal file
15
src/test/ui/issue-50599.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
// 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() {
|
||||
const N: u32 = 1_000;
|
||||
const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; //~ ERROR cannot find value
|
||||
let mut digits = [0u32; M];
|
||||
}
|
15
src/test/ui/issue-50599.stderr
Normal file
15
src/test/ui/issue-50599.stderr
Normal file
|
@ -0,0 +1,15 @@
|
|||
error[E0425]: cannot find value `LOG10_2` in module `std::f64`
|
||||
--> $DIR/issue-50599.rs:13:48
|
||||
|
|
||||
LL | const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; //~ ERROR cannot find value
|
||||
| ^^^^^^^ not found in `std::f64`
|
||||
help: possible candidates are found in other modules, you can import them into scope
|
||||
|
|
||||
LL | use std::f32::consts::LOG10_2;
|
||||
|
|
||||
LL | use std::f64::consts::LOG10_2;
|
||||
|
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0425`.
|
|
@ -22,7 +22,6 @@
|
|||
// padding and overall computed sizes can be quite different.
|
||||
|
||||
#![feature(start)]
|
||||
#![feature(nonzero)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::num::NonZeroU32;
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
// 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.
|
||||
|
||||
// Tests that an `impl Trait` that is not `impl Termination` will not work.
|
||||
fn main() -> impl Copy { }
|
||||
//~^ ERROR `main` has invalid return type `impl std::marker::Copy`
|
|
@ -0,0 +1,11 @@
|
|||
error[E0277]: `main` has invalid return type `impl std::marker::Copy`
|
||||
--> $DIR/termination-trait-impl-trait.rs:12:14
|
||||
|
|
||||
LL | fn main() -> impl Copy { }
|
||||
| ^^^^^^^^^ `main` can only return types that implement `std::process::Termination`
|
||||
|
|
||||
= help: consider using `()`, or a `Result`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
|
@ -614,8 +614,8 @@ pub fn is_test(file_name: &OsString) -> bool {
|
|||
}
|
||||
|
||||
pub fn make_test(config: &Config, testpaths: &TestPaths) -> test::TestDescAndFn {
|
||||
|
||||
let early_props = if config.mode == Mode::RunMake {
|
||||
// Allow `ignore` directives to be in the Makefile.
|
||||
EarlyProps::from_file(config, &testpaths.file.join("Makefile"))
|
||||
} else {
|
||||
EarlyProps::from_file(config, &testpaths.file)
|
||||
|
|
|
@ -10,32 +10,49 @@
|
|||
|
||||
//! Tidy check to ensure that there are no stray `.stderr` files in UI test directories.
|
||||
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
pub fn check(path: &Path, bad: &mut bool) {
|
||||
super::walk_many(&[&path.join("test/ui"), &path.join("test/ui-fulldeps")],
|
||||
&mut |_| false,
|
||||
&mut |file_path| {
|
||||
if let Some(ext) = file_path.extension() {
|
||||
if ext == "stderr" || ext == "stdout" {
|
||||
// Test output filenames have the format:
|
||||
// $testname.stderr
|
||||
// $testname.$mode.stderr
|
||||
// $testname.$revision.stderr
|
||||
// $testname.$revision.$mode.stderr
|
||||
//
|
||||
// For now, just make sure that there is a corresponding
|
||||
// $testname.rs file.
|
||||
let testname = file_path.file_name().unwrap()
|
||||
.to_str().unwrap()
|
||||
.splitn(2, '.').next().unwrap();
|
||||
if !file_path.with_file_name(testname)
|
||||
.with_extension("rs")
|
||||
.exists() {
|
||||
println!("Stray file with UI testing output: {:?}", file_path);
|
||||
*bad = true;
|
||||
super::walk_many(
|
||||
&[&path.join("test/ui"), &path.join("test/ui-fulldeps")],
|
||||
&mut |_| false,
|
||||
&mut |file_path| {
|
||||
if let Some(ext) = file_path.extension() {
|
||||
if ext == "stderr" || ext == "stdout" {
|
||||
// Test output filenames have the format:
|
||||
// $testname.stderr
|
||||
// $testname.$mode.stderr
|
||||
// $testname.$revision.stderr
|
||||
// $testname.$revision.$mode.stderr
|
||||
//
|
||||
// For now, just make sure that there is a corresponding
|
||||
// $testname.rs file.
|
||||
let testname = file_path
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.splitn(2, '.')
|
||||
.next()
|
||||
.unwrap();
|
||||
if !file_path
|
||||
.with_file_name(testname)
|
||||
.with_extension("rs")
|
||||
.exists()
|
||||
{
|
||||
println!("Stray file with UI testing output: {:?}", file_path);
|
||||
*bad = true;
|
||||
}
|
||||
|
||||
if let Ok(metadata) = fs::metadata(file_path) {
|
||||
if metadata.len() == 0 {
|
||||
println!("Empty file with UI testing output: {:?}", file_path);
|
||||
*bad = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue