Auto merge of #88556 - m-ou-se:rollup-q636wyd, r=m-ou-se

Rollup of 9 pull requests

Successful merges:

 - #86376 (Emit specific warning to clarify that `#[no_mangle]` should not be applied on foreign statics or functions)
 - #88040 (BTree: remove Ord bound from new)
 - #88053 (Fix the flock fallback implementation)
 - #88350 (add support for clobbering xer, cr, and cr[0-7] for asm! on OpenPower/PowerPC)
 - #88410 (Remove bolding on associated constants)
 - #88525 (fix(rustc_typeck): produce better errors for dyn auto trait)
 - #88542 (Use the return value of readdir_r() instead of errno)
 - #88548 (Stabilize `Iterator::intersperse()`)
 - #88551 (Stabilize `UnsafeCell::raw_get()`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-09-01 09:06:24 +00:00
commit 3ed6c1d23f
33 changed files with 401 additions and 81 deletions

View File

@ -616,6 +616,10 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'tcx>>)
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => "f",
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => {
@ -755,6 +759,10 @@ fn dummy_output_type(cx: &CodegenCx<'ll, 'tcx>, reg: InlineAsmRegClass) -> &'ll
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => cx.type_i32(),
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(),
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(),
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(),
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => cx.type_f32(),
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => {

View File

@ -222,6 +222,10 @@ cfg_if! {
let msg = "file locks not supported on this platform";
Err(io::Error::new(io::ErrorKind::Other, msg))
}
pub fn error_unsupported(_err: &io::Error) -> bool {
true
}
}
}
}

View File

@ -480,6 +480,7 @@ E0781: include_str!("./error_codes/E0781.md"),
E0782: include_str!("./error_codes/E0782.md"),
E0783: include_str!("./error_codes/E0783.md"),
E0784: include_str!("./error_codes/E0784.md"),
E0785: include_str!("./error_codes/E0785.md"),
;
// E0006, // merged with E0005
// E0008, // cannot bind by-move into a pattern guard

View File

@ -0,0 +1,30 @@
An inherent `impl` was written on a dyn auto trait.
Erroneous code example:
```compile_fail,E0785
#![feature(auto_traits)]
auto trait AutoTrait {}
impl dyn AutoTrait {}
```
Dyn objects allow any number of auto traits, plus at most one non-auto trait.
The non-auto trait becomes the "principal trait".
When checking if an impl on a dyn trait is coherent, the principal trait is
normally the only one considered. Since the erroneous code has no principal
trait, it cannot be implemented at all.
Working example:
```
#![feature(auto_traits)]
trait PrincipalTrait {}
auto trait AutoTrait {}
impl dyn PrincipalTrait + AutoTrait + Send {}
```

View File

@ -1331,6 +1331,36 @@ impl CheckAttrVisitor<'tcx> {
Target::Field | Target::Arm | Target::MacroDef => {
self.inline_attr_str_error_with_macro_def(hir_id, attr, "no_mangle");
}
// FIXME: #[no_mangle] was previously allowed on non-functions/statics, this should be an error
// The error should specify that the item that is wrong is specifically a *foreign* fn/static
// otherwise the error seems odd
Target::ForeignFn | Target::ForeignStatic => {
let foreign_item_kind = match target {
Target::ForeignFn => "function",
Target::ForeignStatic => "static",
_ => unreachable!(),
};
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
lint.build(&format!(
"`#[no_mangle]` has no effect on a foreign {}",
foreign_item_kind
))
.warn(
"this was previously accepted by the compiler but is \
being phased out; it will become a hard error in \
a future release!",
)
.span_label(*span, format!("foreign {}", foreign_item_kind))
.note("symbol names in extern blocks are not mangled")
.span_suggestion(
attr.span,
"remove this attribute",
String::new(),
Applicability::MachineApplicable,
)
.emit();
});
}
_ => {
// FIXME: #[no_mangle] was previously allowed on non-functions/statics and some
// crates used this, so only emit a warning.

View File

@ -479,6 +479,7 @@ symbols! {
core_panic_macro,
cosf32,
cosf64,
cr,
crate_id,
crate_in_paths,
crate_local,
@ -1418,6 +1419,7 @@ symbols! {
wreg,
write_bytes,
x87_reg,
xer,
xmm_reg,
ymm_reg,
zmm_reg,

View File

@ -355,7 +355,7 @@ impl InlineAsmReg {
Self::Arm(r) => r.overlapping_regs(|r| cb(Self::Arm(r))),
Self::AArch64(_) => cb(self),
Self::RiscV(_) => cb(self),
Self::PowerPC(_) => cb(self),
Self::PowerPC(r) => r.overlapping_regs(|r| cb(Self::PowerPC(r))),
Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))),
Self::Mips(_) => cb(self),
Self::S390x(_) => cb(self),

View File

@ -7,6 +7,8 @@ def_reg_class! {
reg,
reg_nonzero,
freg,
cr,
xer,
}
}
@ -44,6 +46,7 @@ impl PowerPCInlineAsmRegClass {
}
}
Self::freg => types! { _: F32, F64; },
Self::cr | Self::xer => &[],
}
}
}
@ -108,6 +111,16 @@ def_regs! {
f29: freg = ["f29", "fr29"],
f30: freg = ["f30", "fr30"],
f31: freg = ["f31", "fr31"],
cr: cr = ["cr"],
cr0: cr = ["cr0"],
cr1: cr = ["cr1"],
cr2: cr = ["cr2"],
cr3: cr = ["cr3"],
cr4: cr = ["cr4"],
cr5: cr = ["cr5"],
cr6: cr = ["cr6"],
cr7: cr = ["cr7"],
xer: xer = ["xer"],
#error = ["r1", "1", "sp"] =>
"the stack pointer cannot be used as an operand for inline asm",
#error = ["r2", "2"] =>
@ -136,17 +149,55 @@ impl PowerPCInlineAsmReg {
_arch: InlineAsmArch,
_modifier: Option<char>,
) -> fmt::Result {
macro_rules! do_emit {
(
$($(($reg:ident, $value:literal)),*;)*
) => {
out.write_str(match self {
$($(Self::$reg => $value,)*)*
})
};
}
// Strip off the leading prefix.
if self as u32 <= Self::r28 as u32 {
let index = self as u32 - Self::r28 as u32;
write!(out, "{}", index)
} else if self as u32 >= Self::f0 as u32 && self as u32 <= Self::f31 as u32 {
let index = self as u32 - Self::f31 as u32;
write!(out, "{}", index)
} else {
unreachable!()
do_emit! {
(r0, "0"), (r3, "3"), (r4, "4"), (r5, "5"), (r6, "6"), (r7, "7");
(r8, "8"), (r9, "9"), (r10, "10"), (r11, "11"), (r12, "12"), (r14, "14"), (r15, "15");
(r16, "16"), (r17, "17"), (r18, "18"), (r19, "19"), (r20, "20"), (r21, "21"), (r22, "22"), (r23, "23");
(r24, "24"), (r25, "25"), (r26, "26"), (r27, "27"), (r28, "28");
(f0, "0"), (f1, "1"), (f2, "2"), (f3, "3"), (f4, "4"), (f5, "5"), (f6, "6"), (f7, "7");
(f8, "8"), (f9, "9"), (f10, "10"), (f11, "11"), (f12, "12"), (f13, "13"), (f14, "14"), (f15, "15");
(f16, "16"), (f17, "17"), (f18, "18"), (f19, "19"), (f20, "20"), (f21, "21"), (f22, "22"), (f23, "23");
(f24, "24"), (f25, "25"), (f26, "26"), (f27, "27"), (f28, "28"), (f29, "29"), (f30, "30"), (f31, "31");
(cr, "cr");
(cr0, "0"), (cr1, "1"), (cr2, "2"), (cr3, "3"), (cr4, "4"), (cr5, "5"), (cr6, "6"), (cr7, "7");
(xer, "xer");
}
}
pub fn overlapping_regs(self, mut _cb: impl FnMut(PowerPCInlineAsmReg)) {}
pub fn overlapping_regs(self, mut cb: impl FnMut(PowerPCInlineAsmReg)) {
macro_rules! reg_conflicts {
(
$(
$full:ident : $($field:ident)*
),*;
) => {
match self {
$(
Self::$full => {
cb(Self::$full);
$(cb(Self::$field);)*
}
$(Self::$field)|* => {
cb(Self::$full);
cb(self);
}
)*
r => cb(r),
}
};
}
reg_conflicts! {
cr : cr0 cr1 cr2 cr3 cr4 cr5 cr6 cr7;
}
}
}

View File

@ -60,6 +60,17 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
ty::Dynamic(ref data, ..) if data.principal_def_id().is_some() => {
self.check_def_id(item, data.principal_def_id().unwrap());
}
ty::Dynamic(..) => {
struct_span_err!(
self.tcx.sess,
ty.span,
E0785,
"cannot define inherent `impl` for a dyn auto trait"
)
.span_label(ty.span, "impl requires at least one non-auto trait")
.note("define and implement a new trait or type instead")
.emit();
}
ty::Bool => {
self.check_primitive_impl(
item.def_id,

View File

@ -233,9 +233,7 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
}
if self.is_empty() {
// Ideally we'd call `BTreeMap::new` here, but that has the `K:
// Ord` constraint, which this method lacks.
BTreeMap { root: None, length: 0 }
BTreeMap::new()
} else {
clone_subtree(self.root.as_ref().unwrap().reborrow()) // unwrap succeeds because not empty
}
@ -499,10 +497,7 @@ impl<K, V> BTreeMap<K, V> {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_btree_new", issue = "71835")]
pub const fn new() -> BTreeMap<K, V>
where
K: Ord,
{
pub const fn new() -> BTreeMap<K, V> {
BTreeMap { root: None, length: 0 }
}
@ -522,7 +517,7 @@ impl<K, V> BTreeMap<K, V> {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn clear(&mut self) {
*self = BTreeMap { root: None, length: 0 };
*self = BTreeMap::new();
}
/// Returns a reference to the value corresponding to the key.
@ -1957,7 +1952,7 @@ impl<K: Hash, V: Hash> Hash for BTreeMap<K, V> {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<K: Ord, V> Default for BTreeMap<K, V> {
impl<K, V> Default for BTreeMap<K, V> {
/// Creates an empty `BTreeMap`.
fn default() -> BTreeMap<K, V> {
BTreeMap::new()

View File

@ -1745,7 +1745,7 @@ fn test_send() {
}
}
#[allow(dead_code)]
#[test]
fn test_ord_absence() {
fn map<K>(mut map: BTreeMap<K, ()>) {
map.is_empty();
@ -1784,6 +1784,12 @@ fn test_ord_absence() {
fn map_clone<K: Clone>(mut map: BTreeMap<K, ()>) {
map.clone_from(&map.clone());
}
#[derive(Debug, Clone)]
struct NonOrd;
map(BTreeMap::<NonOrd, _>::new());
map_debug(BTreeMap::<NonOrd, _>::new());
map_clone(BTreeMap::<NonOrd, _>::default());
}
#[test]

View File

@ -246,10 +246,7 @@ impl<T> BTreeSet<T> {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_btree_new", issue = "71835")]
pub const fn new() -> BTreeSet<T>
where
T: Ord,
{
pub const fn new() -> BTreeSet<T> {
BTreeSet { map: BTreeMap::new() }
}
@ -1192,7 +1189,7 @@ impl<'a, T: 'a + Ord + Copy> Extend<&'a T> for BTreeSet<T> {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Ord> Default for BTreeSet<T> {
impl<T> Default for BTreeSet<T> {
/// Creates an empty `BTreeSet`.
fn default() -> BTreeSet<T> {
BTreeSet::new()

View File

@ -607,7 +607,7 @@ fn test_send() {
}
}
#[allow(dead_code)]
#[test]
fn test_ord_absence() {
fn set<K>(mut set: BTreeSet<K>) {
set.is_empty();
@ -626,6 +626,12 @@ fn test_ord_absence() {
fn set_clone<K: Clone>(mut set: BTreeSet<K>) {
set.clone_from(&set.clone());
}
#[derive(Debug, Clone)]
struct NonOrd;
set(BTreeSet::<NonOrd>::new());
set_debug(BTreeSet::<NonOrd>::new());
set_clone(BTreeSet::<NonOrd>::default());
}
#[test]

View File

@ -1,29 +1,5 @@
// Test const functions in the library
use core::cmp::Ordering;
// FIXME remove this struct once we put `K: ?const Ord` on BTreeMap::new.
#[derive(PartialEq, Eq, PartialOrd)]
pub struct MyType;
impl const Ord for MyType {
fn cmp(&self, _: &Self) -> Ordering {
Ordering::Equal
}
fn max(self, _: Self) -> Self {
Self
}
fn min(self, _: Self) -> Self {
Self
}
fn clamp(self, _: Self, _: Self) -> Self {
Self
}
}
pub const MY_VEC: Vec<usize> = Vec::new();
pub const MY_VEC2: Vec<usize> = Default::default();
@ -32,13 +8,13 @@ pub const MY_STRING2: String = Default::default();
use std::collections::{BTreeMap, BTreeSet};
pub const MY_BTREEMAP: BTreeMap<MyType, MyType> = BTreeMap::new();
pub const MAP: &'static BTreeMap<MyType, MyType> = &MY_BTREEMAP;
pub const MY_BTREEMAP: BTreeMap<usize, usize> = BTreeMap::new();
pub const MAP: &'static BTreeMap<usize, usize> = &MY_BTREEMAP;
pub const MAP_LEN: usize = MAP.len();
pub const MAP_IS_EMPTY: bool = MAP.is_empty();
pub const MY_BTREESET: BTreeSet<MyType> = BTreeSet::new();
pub const SET: &'static BTreeSet<MyType> = &MY_BTREESET;
pub const MY_BTREESET: BTreeSet<usize> = BTreeSet::new();
pub const SET: &'static BTreeSet<usize> = &MY_BTREESET;
pub const SET_LEN: usize = SET.len();
pub const SET_IS_EMPTY: bool = SET.is_empty();

View File

@ -1921,7 +1921,7 @@ impl<T: ?Sized> UnsafeCell<T> {
}
/// Gets a mutable pointer to the wrapped value.
/// The difference to [`get`] is that this function accepts a raw pointer,
/// The difference from [`get`] is that this function accepts a raw pointer,
/// which is useful to avoid the creation of temporary references.
///
/// The result can be cast to a pointer of any kind.
@ -1937,7 +1937,6 @@ impl<T: ?Sized> UnsafeCell<T> {
/// calling `get` would require creating a reference to uninitialized data:
///
/// ```
/// #![feature(unsafe_cell_raw_get)]
/// use std::cell::UnsafeCell;
/// use std::mem::MaybeUninit;
///
@ -1948,7 +1947,7 @@ impl<T: ?Sized> UnsafeCell<T> {
/// assert_eq!(uc.into_inner(), 5);
/// ```
#[inline(always)]
#[unstable(feature = "unsafe_cell_raw_get", issue = "66358")]
#[stable(feature = "unsafe_cell_raw_get", since = "1.56.0")]
pub const fn raw_get(this: *const Self) -> *mut T {
// We can just cast the pointer from `UnsafeCell<T>` to `T` because of
// #[repr(transparent)]. This exploits libstd's special status, there is

View File

@ -4,7 +4,7 @@ use super::Peekable;
///
/// This `struct` is created by [`Iterator::intersperse`]. See its documentation
/// for more information.
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
#[stable(feature = "iter_intersperse", since = "1.56.0")]
#[derive(Debug, Clone)]
pub struct Intersperse<I: Iterator>
where
@ -24,7 +24,7 @@ where
}
}
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
#[stable(feature = "iter_intersperse", since = "1.56.0")]
impl<I> Iterator for Intersperse<I>
where
I: Iterator,
@ -61,7 +61,7 @@ where
///
/// This `struct` is created by [`Iterator::intersperse_with`]. See its
/// documentation for more information.
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
#[stable(feature = "iter_intersperse", since = "1.56.0")]
pub struct IntersperseWith<I, G>
where
I: Iterator,
@ -71,7 +71,7 @@ where
needs_sep: bool,
}
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
#[stable(feature = "iter_intersperse", since = "1.56.0")]
impl<I, G> crate::fmt::Debug for IntersperseWith<I, G>
where
I: Iterator + crate::fmt::Debug,
@ -87,7 +87,7 @@ where
}
}
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
#[stable(feature = "iter_intersperse", since = "1.56.0")]
impl<I, G> crate::clone::Clone for IntersperseWith<I, G>
where
I: Iterator + crate::clone::Clone,
@ -113,7 +113,7 @@ where
}
}
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
#[stable(feature = "iter_intersperse", since = "1.56.0")]
impl<I, G> Iterator for IntersperseWith<I, G>
where
I: Iterator,

View File

@ -42,7 +42,7 @@ pub use self::flatten::Flatten;
#[stable(feature = "iter_copied", since = "1.36.0")]
pub use self::copied::Copied;
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
#[stable(feature = "iter_intersperse", since = "1.56.0")]
pub use self::intersperse::{Intersperse, IntersperseWith};
#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]

View File

@ -414,7 +414,7 @@ pub use self::adapters::{
Chain, Cycle, Enumerate, Filter, FilterMap, FlatMap, Fuse, Inspect, Map, Peekable, Rev, Scan,
Skip, SkipWhile, Take, TakeWhile, Zip,
};
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
#[stable(feature = "iter_intersperse", since = "1.56.0")]
pub use self::adapters::{Intersperse, IntersperseWith};
pub(crate) use self::adapters::process_results;

View File

@ -535,8 +535,6 @@ pub trait Iterator {
/// Basic usage:
///
/// ```
/// #![feature(iter_intersperse)]
///
/// let mut a = [0, 1, 2].iter().intersperse(&100);
/// assert_eq!(a.next(), Some(&0)); // The first element from `a`.
/// assert_eq!(a.next(), Some(&100)); // The separator.
@ -547,9 +545,8 @@ pub trait Iterator {
/// ```
///
/// `intersperse` can be very useful to join an iterator's items using a common element:
/// ```
/// #![feature(iter_intersperse)]
///
/// ```
/// let hello = ["Hello", "World", "!"].iter().copied().intersperse(" ").collect::<String>();
/// assert_eq!(hello, "Hello World !");
/// ```
@ -557,7 +554,7 @@ pub trait Iterator {
/// [`Clone`]: crate::clone::Clone
/// [`intersperse_with`]: Iterator::intersperse_with
#[inline]
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
#[stable(feature = "iter_intersperse", since = "1.56.0")]
fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
where
Self: Sized,
@ -582,8 +579,6 @@ pub trait Iterator {
/// Basic usage:
///
/// ```
/// #![feature(iter_intersperse)]
///
/// #[derive(PartialEq, Debug)]
/// struct NotClone(usize);
///
@ -600,9 +595,8 @@ pub trait Iterator {
///
/// `intersperse_with` can be used in situations where the separator needs
/// to be computed:
/// ```
/// #![feature(iter_intersperse)]
///
/// ```
/// let src = ["Hello", "to", "all", "people", "!!"].iter().copied();
///
/// // The closure mutably borrows its context to generate an item.
@ -615,7 +609,7 @@ pub trait Iterator {
/// [`Clone`]: crate::clone::Clone
/// [`intersperse`]: Iterator::intersperse
#[inline]
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
#[stable(feature = "iter_intersperse", since = "1.56.0")]
fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where
Self: Sized,

View File

@ -2,6 +2,38 @@ use core::cell::*;
use core::default::Default;
use std::mem::drop;
#[test]
fn smoketest_unsafe_cell() {
let mut x = UnsafeCell::new(10);
let ref_mut = &mut x;
unsafe {
// The asserts are repeated in order to ensure that `get()`
// is non-mutating.
assert_eq!(*ref_mut.get(), 10);
assert_eq!(*ref_mut.get(), 10);
*ref_mut.get_mut() += 5;
assert_eq!(*ref_mut.get(), 15);
assert_eq!(*ref_mut.get(), 15);
assert_eq!(x.into_inner(), 15);
}
}
#[test]
fn unsafe_cell_raw_get() {
let x = UnsafeCell::new(10);
let ptr = &x as *const UnsafeCell<i32>;
unsafe {
// The asserts are repeated in order to ensure that `raw_get()`
// is non-mutating.
assert_eq!(*UnsafeCell::raw_get(ptr), 10);
assert_eq!(*UnsafeCell::raw_get(ptr), 10);
*UnsafeCell::raw_get(ptr) += 5;
assert_eq!(*UnsafeCell::raw_get(ptr), 15);
assert_eq!(*UnsafeCell::raw_get(ptr), 15);
assert_eq!(x.into_inner(), 15);
}
}
#[test]
fn smoketest_cell() {
let x = Cell::new(10);

View File

@ -48,7 +48,6 @@
#![feature(int_log)]
#![feature(iter_advance_by)]
#![feature(iter_partition_in_place)]
#![feature(iter_intersperse)]
#![feature(iter_is_partitioned)]
#![feature(iter_order_by)]
#![feature(iter_map_while)]

View File

@ -331,7 +331,6 @@
#![feature(try_reserve)]
#![feature(try_reserve_kind)]
#![feature(unboxed_closures)]
#![feature(unsafe_cell_raw_get)]
#![feature(unwrap_infallible)]
#![feature(vec_into_raw_parts)]
#![feature(vec_spare_capacity)]

View File

@ -506,7 +506,8 @@ impl Iterator for ReadDir {
let mut ret = DirEntry { entry: mem::zeroed(), dir: Arc::clone(&self.inner) };
let mut entry_ptr = ptr::null_mut();
loop {
if readdir64_r(self.inner.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 {
let err = readdir64_r(self.inner.dirp.0, &mut ret.entry, &mut entry_ptr);
if err != 0 {
if entry_ptr.is_null() {
// We encountered an error (which will be returned in this iteration), but
// we also reached the end of the directory stream. The `end_of_stream`
@ -514,7 +515,7 @@ impl Iterator for ReadDir {
// (instead of looping forever)
self.end_of_stream = true;
}
return Some(Err(Error::last_os_error()));
return Some(Err(Error::from_raw_os_error(err)));
}
if entry_ptr.is_null() {
return None;

View File

@ -585,6 +585,8 @@ Here is the list of currently supported register classes:
| PowerPC | `reg` | `r[0-31]` | `r` |
| PowerPC | `reg_nonzero` | | `r[1-31]` | `b` |
| PowerPC | `freg` | `f[0-31]` | `f` |
| PowerPC | `cr` | `cr[0-7]`, `cr` | Only clobbers |
| PowerPC | `xer` | `xer` | Only clobbers |
| wasm32 | `local` | None\* | `r` |
| BPF | `reg` | `r[0-10]` | `r` |
| BPF | `wreg` | `w[0-10]` | `w` |
@ -638,6 +640,8 @@ Each register class has constraints on which value types they can be used with.
| PowerPC | `reg` | None | `i8`, `i16`, `i32` |
| PowerPC | `reg_nonzero` | None | `i8`, `i16`, `i32` |
| PowerPC | `freg` | None | `f32`, `f64` |
| PowerPC | `cr` | N/A | Only clobbers |
| PowerPC | `xer` | N/A | Only clobbers |
| wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64` |
| BPF | `reg` | None | `i8` `i16` `i32` `i64` |
| BPF | `wreg` | `alu32` | `i8` `i16` `i32` |

View File

@ -753,7 +753,7 @@ fn assoc_const(
) {
write!(
w,
"{}{}const <a href=\"{}\" class=\"constant\"><b>{}</b></a>: {}",
"{}{}const <a href=\"{}\" class=\"constant\">{}</a>: {}",
extra,
it.visibility.print_with_space(it.def_id, cx),
naive_assoc_href(it, link, cx),

View File

@ -13,7 +13,6 @@
#![feature(never_type)]
#![feature(once_cell)]
#![feature(type_ascription)]
#![feature(iter_intersperse)]
#![recursion_limit = "256"]
#![warn(rustc::internal)]

View File

@ -194,3 +194,15 @@ check_reg!(reg_f32_f0, f32, "0", "f0", "fmr");
// CHECK: fmr 0, 0
// CHECK: #NO_APP
check_reg!(reg_f64_f0, f64, "0", "f0", "fmr");
// CHECK-LABEL: reg_f32_f18:
// CHECK: #APP
// CHECK: fmr 18, 18
// CHECK: #NO_APP
check_reg!(reg_f32_f18, f32, "18", "f18", "fmr");
// CHECK-LABEL: reg_f64_f18:
// CHECK: #APP
// CHECK: fmr 18, 18
// CHECK: #NO_APP
check_reg!(reg_f64_f18, f64, "18", "f18", "fmr");

View File

@ -0,0 +1,48 @@
// min-llvm-version: 10.0.1
// revisions: powerpc powerpc64 powerpc64le
//[powerpc] compile-flags: --target powerpc-unknown-linux-gnu
//[powerpc] needs-llvm-components: powerpc
//[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu
//[powerpc64] needs-llvm-components: powerpc
//[powerpc64le] compile-flags: --target powerpc64le-unknown-linux-gnu
//[powerpc64le] needs-llvm-components: powerpc
#![crate_type = "rlib"]
#![feature(no_core, rustc_attrs, lang_items)]
#![no_core]
#[lang = "sized"]
trait Sized {}
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
// CHECK-LABEL: @cr_clobber
// CHECK: call void asm sideeffect "", "~{cr}"()
#[no_mangle]
pub unsafe fn cr_clobber() {
asm!("", out("cr") _, options(nostack, nomem));
}
// CHECK-LABEL: @cr0_clobber
// CHECK: call void asm sideeffect "", "~{cr0}"()
#[no_mangle]
pub unsafe fn cr0_clobber() {
asm!("", out("cr0") _, options(nostack, nomem));
}
// CHECK-LABEL: @cr5_clobber
// CHECK: call void asm sideeffect "", "~{cr5}"()
#[no_mangle]
pub unsafe fn cr5_clobber() {
asm!("", out("cr5") _, options(nostack, nomem));
}
// CHECK-LABEL: @xer_clobber
// CHECK: call void asm sideeffect "", "~{xer}"()
#[no_mangle]
pub unsafe fn xer_clobber() {
asm!("", out("xer") _, options(nostack, nomem));
}

View File

@ -13,6 +13,21 @@ goto: file://|DOC_PATH|/test_docs/struct.Foo.html
assert-css: (".impl-items .method", {"font-weight": "600"}, ALL)
goto: file://|DOC_PATH|/lib2/trait.Trait.html
// This is a complex selector, so here's how it works:
//
// * //*[@class='docblock type-decl'] — selects element of any tag with classes docblock and type-decl
// * /pre[@class='rust trait'] — selects immediate child with tag pre and classes rust and trait
// * /code — selects immediate child with tag code
// * /a[@class='constant'] — selects immediate child with tag a and class constant
// * //text() — selects child that is text node
// * /parent::* — selects immediate parent of the text node (the * means it can be any tag)
//
// This uses '/parent::*' as a proxy for the style of the text node.
// We can't just select the '<a>' because intermediate tags could be added.
assert-count: ("//*[@class='docblock type-decl']/pre[@class='rust trait']/code/a[@class='constant']//text()/parent::*", 1)
assert-css: ("//*[@class='docblock type-decl']/pre[@class='rust trait']/code/a[@class='constant']//text()/parent::*", {"font-weight": "400"})
assert-count: (".methods .type", 1)
assert-css: (".methods .type", {"font-weight": "600"})
assert-count: (".methods .constant", 1)

View File

@ -0,0 +1,10 @@
#![feature(auto_traits)]
auto trait AutoTrait {}
// You cannot impl your own `dyn AutoTrait`.
impl dyn AutoTrait {} //~ERROR E0785
// You cannot impl someone else's `dyn AutoTrait`
impl dyn Unpin {} //~ERROR E0785
fn main() {}

View File

@ -0,0 +1,19 @@
error[E0785]: cannot define inherent `impl` for a dyn auto trait
--> $DIR/issue-85026.rs:5:6
|
LL | impl dyn AutoTrait {}
| ^^^^^^^^^^^^^ impl requires at least one non-auto trait
|
= note: define and implement a new trait or type instead
error[E0785]: cannot define inherent `impl` for a dyn auto trait
--> $DIR/issue-85026.rs:8:6
|
LL | impl dyn Unpin {}
| ^^^^^^^^^ impl requires at least one non-auto trait
|
= note: define and implement a new trait or type instead
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0785`.

30
src/test/ui/extern/extern-no-mangle.rs vendored Normal file
View File

@ -0,0 +1,30 @@
#![warn(unused_attributes)]
// Tests that placing the #[no_mangle] attribute on a foreign fn or static emits
// a specialized warning.
// The previous warning only talks about a "function or static" but foreign fns/statics
// are also not allowed to have #[no_mangle]
// build-pass
extern "C" {
#[no_mangle]
//~^ WARNING `#[no_mangle]` has no effect on a foreign static
//~^^ WARNING this was previously accepted by the compiler
pub static FOO: u8;
#[no_mangle]
//~^ WARNING `#[no_mangle]` has no effect on a foreign function
//~^^ WARNING this was previously accepted by the compiler
pub fn bar();
}
fn no_new_warn() {
// Should emit the generic "not a function or static" warning
#[no_mangle]
//~^ WARNING attribute should be applied to a free function, impl method or static
//~^^ WARNING this was previously accepted by the compiler
let x = 0_u8;
}
fn main() {}

View File

@ -0,0 +1,42 @@
warning: attribute should be applied to a free function, impl method or static
--> $DIR/extern-no-mangle.rs:24:5
|
LL | #[no_mangle]
| ^^^^^^^^^^^^
...
LL | let x = 0_u8;
| ------------- not a free function, impl method or static
|
note: the lint level is defined here
--> $DIR/extern-no-mangle.rs:1:9
|
LL | #![warn(unused_attributes)]
| ^^^^^^^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
warning: `#[no_mangle]` has no effect on a foreign static
--> $DIR/extern-no-mangle.rs:11:5
|
LL | #[no_mangle]
| ^^^^^^^^^^^^ help: remove this attribute
...
LL | pub static FOO: u8;
| ------------------- foreign static
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: symbol names in extern blocks are not mangled
warning: `#[no_mangle]` has no effect on a foreign function
--> $DIR/extern-no-mangle.rs:16:5
|
LL | #[no_mangle]
| ^^^^^^^^^^^^ help: remove this attribute
...
LL | pub fn bar();
| ------------- foreign function
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: symbol names in extern blocks are not mangled
warning: 3 warnings emitted