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:
commit
3ed6c1d23f
@ -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) => {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
30
compiler/rustc_error_codes/src/error_codes/E0785.md
Normal file
30
compiler/rustc_error_codes/src/error_codes/E0785.md
Normal 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 {}
|
||||
```
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
|
@ -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]
|
||||
|
@ -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()
|
||||
|
@ -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]
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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")]
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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)]
|
||||
|
@ -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)]
|
||||
|
@ -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;
|
||||
|
@ -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` |
|
||||
|
@ -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),
|
||||
|
@ -13,7 +13,6 @@
|
||||
#![feature(never_type)]
|
||||
#![feature(once_cell)]
|
||||
#![feature(type_ascription)]
|
||||
#![feature(iter_intersperse)]
|
||||
#![recursion_limit = "256"]
|
||||
#![warn(rustc::internal)]
|
||||
|
||||
|
@ -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");
|
||||
|
48
src/test/codegen/asm-powerpc-clobbers.rs
Normal file
48
src/test/codegen/asm-powerpc-clobbers.rs
Normal 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));
|
||||
}
|
@ -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)
|
||||
|
10
src/test/ui/coherence/issue-85026.rs
Normal file
10
src/test/ui/coherence/issue-85026.rs
Normal 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() {}
|
19
src/test/ui/coherence/issue-85026.stderr
Normal file
19
src/test/ui/coherence/issue-85026.stderr
Normal 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
30
src/test/ui/extern/extern-no-mangle.rs
vendored
Normal 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() {}
|
42
src/test/ui/extern/extern-no-mangle.stderr
vendored
Normal file
42
src/test/ui/extern/extern-no-mangle.stderr
vendored
Normal 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user