提交 b559710e 编写于 作者: B bors

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:
......@@ -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 @@ pub fn cargo(&self,
// 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 @@ fn run(self, builder: &Builder) {
host: true
});
host_test!(RunMake {
default_test!(RunMake {
path: "src/test/run-make",
mode: "run-make",
suite: "run-make"
......@@ -1041,7 +1041,7 @@ fn run(self, builder: &Builder) {
// 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 @@ fn run(self, builder: &Builder) {
}
}
}
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 @@ fn from(s: String) -> 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 @@ fn from(v: Vec<T>) -> 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 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);
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)
}
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub(crate) struct NonZero<T>(pub(crate) T);
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 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 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
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 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
/// 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 @@ pub fn new(n: $Int) -> Option<Self> {
}
/// 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 @@ pub fn get(self) -> $Int {
}
impl_nonzero_fmt! {
#[$stability]
(Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
}
)+
......@@ -95,8 +90,6 @@ pub fn get(self) -> $Int {
}
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 @@ pub fn get(self) -> $Int {
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 @@ pub const fn max_value() -> Self {
* `0-9`
* `a-z`
* `a-z`
* `A-Z`
# Panics
......
......@@ -23,7 +23,7 @@
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 @@ fn ge(&self, other: &*mut T) -> bool { *self >= *other }
#[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 @@ pub const fn empty() -> Self {
}
#[unstable(feature = "ptr_internals", issue = "0")]
#[allow(deprecated)]
impl<T: ?Sized> Unique<T> {
/// Creates a new `Unique`.
///
......@@ -2855,7 +2853,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
#[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 @@ fn from(reference: &'a mut T) -> Self {
}
#[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 @@ fn from(p: NonNull<T>) -> Self {
/// 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 @@ pub fn dangling() -> Self {
}
}
#[allow(deprecated)]
impl<T: ?Sized> NonNull<T> {
/// Creates a new `NonNull`.
///
......@@ -3054,7 +3049,6 @@ fn from(unique: Unique<T>) -> Self {
}
#[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 @@ fn from(reference: &'a mut T) -> Self {
}
#[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::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 @@ fn generalize_region<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'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 @@ fn generalize_region<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'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 @@ fn generalize_region<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'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 @@ fn fresh_bound_variable<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'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::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 @@ pub fn replace_late_bound_regions_with_fresh_var<T>(
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 @@ fn parse_cross_lang_lto(slot: &mut CrossLangLto, v: Option<&str>) -> bool {
"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 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 @@ fn new<F>(tcx: TyCtxt<'a, 'gcx, 'tcx>, fld_r: &'a mut F)
tcx,
current_depth: 1,
fld_r,
map: LazyBTreeMap::default()
map: BTreeMap::default()
}
}
}
......
// 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 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 @@
#![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 {
// 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 {
for p in self.params.iter().filter(|p| !is_impl_trait(p)) {
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());
}
}
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 @@ fn rust_input<R, F>(cratefile: PathBuf,
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 @@ fn rust_input<R, F>(cratefile: PathBuf,
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 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 @@ fn from(s: CString) -> 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 @@ fn from(s: &OsStr) -> 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 @@
#[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 @@ fn from(s: PathBuf) -> 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 @@ unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: usize, offset: i64)
}
}
#[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 @@ pub fn open_c(path: &CStr, opts: &OpenOptions) -> io::Result<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 @@
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;
......
// 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 { }
// 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;
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 @@ pub fn qux(_qux: impl IntoIterator<Item = S<impl Read>>) {
// @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,
) {
}
// 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
);
}
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`.
// 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
);
}
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`.
// 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
);
}
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`.
// 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];
}
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;
......
// 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`
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;
}
}
}
}
}
});
},
);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册