Auto merge of #128298 - matthiaskrgr:rollup-0wdu2wo, r=matthiaskrgr

Rollup of 5 pull requests

Successful merges:

 - #127853 (`#[naked]`: report incompatible attributes)
 - #128276 (Add a README to rustbook to explain its purpose)
 - #128279 (Stabilize `is_sorted`)
 - #128282 (bitwise and bytewise methods on `NonZero`)
 - #128285 (rustc book: document how the RUST_TARGET_PATH variable is used)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-07-28 09:18:53 +00:00
commit 3954398882
39 changed files with 878 additions and 240 deletions

View File

@ -220,6 +220,11 @@ builtin_macros_multiple_defaults = multiple declared defaults
.note = only one variant can be default
.suggestion = make `{$ident}` default
builtin_macros_naked_functions_testing_attribute =
cannot use `#[naked]` with testing attributes
.label = function marked with testing attribute here
.naked_attribute = `#[naked]` is incompatible with testing attributes
builtin_macros_no_default_variant = no default declared
.help = make a unit variant default by placing `#[default]` above it
.suggestion = make `{$ident}` default

View File

@ -923,3 +923,13 @@ pub(crate) struct ExpectedItem<'a> {
pub span: Span,
pub token: &'a str,
}
#[derive(Diagnostic)]
#[diag(builtin_macros_naked_functions_testing_attribute, code = E0736)]
pub struct NakedFunctionTestingAttribute {
#[primary_span]
#[label(builtin_macros_naked_attribute)]
pub naked_span: Span,
#[label]
pub testing_span: Span,
}

View File

@ -133,6 +133,14 @@ pub(crate) fn expand_test_or_bench(
};
};
if let Some(attr) = attr::find_by_name(&item.attrs, sym::naked) {
cx.dcx().emit_err(errors::NakedFunctionTestingAttribute {
testing_span: attr_sp,
naked_span: attr.span,
});
return vec![Annotatable::Item(item)];
}
// check_*_signature will report any errors in the type so compilation
// will fail. We shouldn't try to expand in this case because the errors
// would be spurious.

View File

@ -3,7 +3,6 @@
coroutines,
stmt_expr_attributes,
coroutine_trait,
is_sorted,
repr_simd,
tuple_trait,
unboxed_closures

View File

@ -1,5 +1,5 @@
#![allow(internal_features)]
#![feature(core_intrinsics, coroutines, coroutine_trait, is_sorted, stmt_expr_attributes)]
#![feature(core_intrinsics, coroutines, coroutine_trait, stmt_expr_attributes)]
#[cfg(feature="master")]
#[cfg(target_arch="x86_64")]

View File

@ -1,14 +1,20 @@
`#[track_caller]` and `#[naked]` cannot both be applied to the same function.
Functions marked with the `#[naked]` attribute are restricted in what other
attributes they may be marked with.
Notable attributes that are incompatible with `#[naked]` are:
* `#[inline]`
* `#[track_caller]`
* `#[test]`, `#[ignore]`, `#[should_panic]`
Erroneous code example:
```compile_fail,E0736
#[inline]
#[naked]
#[track_caller]
fn foo() {}
```
This is primarily due to ABI incompatibilities between the two attributes.
See [RFC 2091] for details on this and other limitations.
[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md
These incompatibilities are due to the fact that naked functions deliberately
impose strict restrictions regarding the code that the compiler is
allowed to produce for this function.

View File

@ -1,4 +1,4 @@
`#[track_caller]` can not be applied on struct.
`#[track_caller]` must be applied to a function
Erroneous code example:

View File

@ -64,7 +64,6 @@
#![doc(rust_logo)]
#![feature(control_flow_enum)]
#![feature(if_let_guard)]
#![feature(is_sorted)]
#![feature(iter_intersperse)]
#![feature(let_chains)]
#![feature(never_type)]

View File

@ -1984,14 +1984,18 @@
///
/// ```rust
/// trait MyIterator : Iterator {
/// // is_sorted is an unstable method that already exists on the Iterator trait
/// fn is_sorted(self) -> bool where Self: Sized {true}
/// // is_partitioned is an unstable method that already exists on the Iterator trait
/// fn is_partitioned<P>(self, predicate: P) -> bool
/// where
/// Self: Sized,
/// P: FnMut(Self::Item) -> bool,
/// {true}
/// }
///
/// impl<T: ?Sized> MyIterator for T where T: Iterator { }
///
/// let x = vec![1, 2, 3];
/// let _ = x.iter().is_sorted();
/// let _ = x.iter().is_partitioned(|_| true);
/// ```
///
/// {{produces}}
@ -2007,7 +2011,7 @@
/// is an early-warning to let you know that there may be a collision in
/// the future. This can be avoided by adding type annotations to
/// disambiguate which trait method you intend to call, such as
/// `MyIterator::is_sorted(my_iter)` or renaming or removing the method.
/// `MyIterator::is_partitioned(my_iter, my_predicate)` or renaming or removing the method.
///
/// [nightly channel]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html
/// [`feature` attribute]: https://doc.rust-lang.org/nightly/unstable-book/

View File

@ -6,7 +6,6 @@
#![feature(decl_macro)]
#![feature(if_let_guard)]
#![feature(impl_trait_in_assoc_type)]
#![feature(is_sorted)]
#![feature(let_chains)]
#![feature(map_try_insert)]
#![feature(never_type)]

View File

@ -1,6 +1,5 @@
// tidy-alphabetical-start
#![feature(array_windows)]
#![feature(is_sorted)]
// tidy-alphabetical-end
use rustc_hir::lang_items::LangItem;

View File

@ -69,9 +69,6 @@ passes_break_non_loop =
.suggestion = use `break` on its own without a value inside this `{$kind}` loop
.break_expr_suggestion = alternatively, you might have meant to use the available loop label
passes_cannot_inline_naked_function =
naked functions cannot be inlined
passes_cannot_stabilize_deprecated =
an API can't be stabilized after it is deprecated
.label = invalid version
@ -485,6 +482,11 @@ passes_naked_functions_asm_block =
passes_naked_functions_asm_options =
asm options unsupported in naked functions: {$unsupported_options}
passes_naked_functions_incompatible_attribute =
attribute incompatible with `#[naked]`
.label = the `{$attr}` attribute is incompatible with `#[naked]`
.naked_attribute = function marked with `#[naked]` here
passes_naked_functions_must_use_noreturn =
asm in naked functions must use `noreturn` option
.suggestion = consider specifying that the asm block is responsible for returning from the function
@ -492,9 +494,6 @@ passes_naked_functions_must_use_noreturn =
passes_naked_functions_operands =
only `const` and `sym` operands are supported in naked functions
passes_naked_tracked_caller =
cannot use `#[track_caller]` with `#[naked]`
passes_no_link =
attribute should be applied to an `extern crate` item
.label = not an `extern crate` item

View File

@ -155,7 +155,7 @@ fn check_attributes(
[sym::rustc_std_internal_symbol] => {
self.check_rustc_std_internal_symbol(attr, span, target)
}
[sym::naked] => self.check_naked(hir_id, attr, span, target),
[sym::naked] => self.check_naked(hir_id, attr, span, target, attrs),
[sym::rustc_never_returns_null_ptr] => {
self.check_applied_to_fn_or_method(hir_id, attr, span, target)
}
@ -410,12 +410,71 @@ fn check_generic_attr(
}
/// Checks if `#[naked]` is applied to a function definition.
fn check_naked(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool {
fn check_naked(
&self,
hir_id: HirId,
attr: &Attribute,
span: Span,
target: Target,
attrs: &[Attribute],
) -> bool {
// many attributes don't make sense in combination with #[naked].
// Notable attributes that are incompatible with `#[naked]` are:
//
// * `#[inline]`
// * `#[track_caller]`
// * `#[test]`, `#[ignore]`, `#[should_panic]`
//
// NOTE: when making changes to this list, check that `error_codes/E0736.md` remains accurate
const ALLOW_LIST: &[rustc_span::Symbol] = &[
// conditional compilation
sym::cfg,
sym::cfg_attr,
// testing (allowed here so better errors can be generated in `rustc_builtin_macros::test`)
sym::test,
sym::ignore,
sym::should_panic,
sym::bench,
// diagnostics
sym::allow,
sym::warn,
sym::deny,
sym::forbid,
sym::deprecated,
sym::must_use,
// abi, linking and FFI
sym::export_name,
sym::link_section,
sym::linkage,
sym::no_mangle,
sym::naked,
sym::instruction_set,
// code generation
sym::cold,
sym::target_feature,
// documentation
sym::doc,
];
match target {
Target::Fn
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {
for other_attr in attrs {
if !ALLOW_LIST.iter().any(|name| other_attr.has_name(*name)) {
self.dcx().emit_err(errors::NakedFunctionIncompatibleAttribute {
span: other_attr.span,
naked_span: attr.span,
attr: other_attr.name_or_empty(),
});
return false;
}
}
true
}
// FIXME(#80564): We permit struct fields, match arms and macro defs to have an
// `#[allow_internal_unstable]` attribute with just a lint, because we previously
// `#[naked]` attribute with just a lint, because we previously
// erroneously allowed it and some crates used it accidentally, to be compatible
// with crates depending on them, we can't throw an error here.
Target::Field | Target::Arm | Target::MacroDef => {
@ -488,7 +547,7 @@ fn check_collapse_debuginfo(&self, attr: &Attribute, span: Span, target: Target)
}
}
/// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid.
/// Checks if a `#[track_caller]` is applied to a function. Returns `true` if valid.
fn check_track_caller(
&self,
hir_id: HirId,
@ -498,10 +557,6 @@ fn check_track_caller(
target: Target,
) -> bool {
match target {
_ if attrs.iter().any(|attr| attr.has_name(sym::naked)) => {
self.dcx().emit_err(errors::NakedTrackedCaller { attr_span });
false
}
Target::Fn => {
// `#[track_caller]` is not valid on weak lang items because they are called via
// `extern` declarations and `#[track_caller]` would alter their ABI.

View File

@ -79,13 +79,6 @@ pub struct AttrShouldBeAppliedToFn {
pub on_crate: bool,
}
#[derive(Diagnostic)]
#[diag(passes_naked_tracked_caller, code = E0736)]
pub struct NakedTrackedCaller {
#[primary_span]
pub attr_span: Span,
}
#[derive(Diagnostic)]
#[diag(passes_should_be_applied_to_fn, code = E0739)]
pub struct TrackedCallerWrongLocation {
@ -1124,13 +1117,6 @@ pub struct UnlabeledCfInWhileCondition<'a> {
pub cf_type: &'a str,
}
#[derive(Diagnostic)]
#[diag(passes_cannot_inline_naked_function)]
pub struct CannotInlineNakedFunction {
#[primary_span]
pub span: Span,
}
#[derive(LintDiagnostic)]
#[diag(passes_undefined_naked_function_abi)]
pub struct UndefinedNakedFunctionAbi;
@ -1196,6 +1182,17 @@ pub struct NakedFunctionsMustUseNoreturn {
pub last_span: Span,
}
#[derive(Diagnostic)]
#[diag(passes_naked_functions_incompatible_attribute, code = E0736)]
pub struct NakedFunctionIncompatibleAttribute {
#[primary_span]
#[label]
pub span: Span,
#[label(passes_naked_attribute)]
pub naked_span: Span,
pub attr: Symbol,
}
#[derive(Diagnostic)]
#[diag(passes_attr_only_in_functions)]
pub struct AttrOnlyInFunctions {

View File

@ -14,9 +14,8 @@
use rustc_target::spec::abi::Abi;
use crate::errors::{
CannotInlineNakedFunction, NakedFunctionsAsmBlock, NakedFunctionsAsmOptions,
NakedFunctionsMustUseNoreturn, NakedFunctionsOperands, NoPatterns, ParamsNotAllowed,
UndefinedNakedFunctionAbi,
NakedFunctionsAsmBlock, NakedFunctionsAsmOptions, NakedFunctionsMustUseNoreturn,
NakedFunctionsOperands, NoPatterns, ParamsNotAllowed, UndefinedNakedFunctionAbi,
};
pub(crate) fn provide(providers: &mut Providers) {
@ -53,15 +52,6 @@ fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
check_no_patterns(tcx, body.params);
check_no_parameters_use(tcx, body);
check_asm(tcx, def_id, body);
check_inline(tcx, def_id);
}
}
/// Check that the function isn't inlined.
fn check_inline(tcx: TyCtxt<'_>, def_id: LocalDefId) {
let attrs = tcx.get_attrs(def_id, sym::inline);
for attr in attrs {
tcx.dcx().emit_err(CannotInlineNakedFunction { span: attr.span });
}
}

View File

@ -92,7 +92,6 @@
// tidy-alphabetical-start
#![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))]
#![cfg_attr(not(no_global_oom_handling), feature(const_btree_len))]
#![cfg_attr(test, feature(is_sorted))]
#![cfg_attr(test, feature(new_uninit))]
#![feature(alloc_layout_extra)]
#![feature(allocator_api)]

View File

@ -3951,8 +3951,6 @@ fn ge<I>(self, other: I) -> bool
/// # Examples
///
/// ```
/// #![feature(is_sorted)]
///
/// assert!([1, 2, 2, 9].iter().is_sorted());
/// assert!(![1, 3, 2, 4].iter().is_sorted());
/// assert!([0].iter().is_sorted());
@ -3960,7 +3958,7 @@ fn ge<I>(self, other: I) -> bool
/// assert!(![0.0, 1.0, f32::NAN].iter().is_sorted());
/// ```
#[inline]
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
#[stable(feature = "is_sorted", since = "CURRENT_RUSTC_VERSION")]
#[rustc_do_not_const_check]
fn is_sorted(self) -> bool
where
@ -3978,8 +3976,6 @@ fn is_sorted(self) -> bool
/// # Examples
///
/// ```
/// #![feature(is_sorted)]
///
/// assert!([1, 2, 2, 9].iter().is_sorted_by(|a, b| a <= b));
/// assert!(![1, 2, 2, 9].iter().is_sorted_by(|a, b| a < b));
///
@ -3989,7 +3985,7 @@ fn is_sorted(self) -> bool
/// assert!(std::iter::empty::<i32>().is_sorted_by(|a, b| false));
/// assert!(std::iter::empty::<i32>().is_sorted_by(|a, b| true));
/// ```
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
#[stable(feature = "is_sorted", since = "CURRENT_RUSTC_VERSION")]
#[rustc_do_not_const_check]
fn is_sorted_by<F>(mut self, compare: F) -> bool
where
@ -4030,13 +4026,11 @@ fn check<'a, T>(
/// # Examples
///
/// ```
/// #![feature(is_sorted)]
///
/// assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len()));
/// assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
/// ```
#[inline]
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
#[stable(feature = "is_sorted", since = "CURRENT_RUSTC_VERSION")]
#[rustc_do_not_const_check]
fn is_sorted_by_key<F, K>(self, f: F) -> bool
where

View File

@ -455,6 +455,12 @@ macro_rules! nonzero_integer {
UnsignedPrimitive = $Uint:ty,
// Used in doc comments.
rot = $rot:literal,
rot_op = $rot_op:literal,
rot_result = $rot_result:literal,
swap_op = $swap_op:literal,
swapped = $swapped:literal,
reversed = $reversed:literal,
leading_zeros_test = $leading_zeros_test:expr,
) => {
/// An integer that is known not to equal zero.
@ -604,6 +610,270 @@ pub const fn count_ones(self) -> NonZero<u32> {
unsafe { NonZero::new_unchecked(self.get().count_ones()) }
}
/// Shifts the bits to the left by a specified amount, `n`,
/// wrapping the truncated bits to the end of the resulting integer.
///
/// Please note this isn't the same operation as the `<<` shifting operator!
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(nonzero_bitwise)]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let n = NonZero::new(", $rot_op, stringify!($Int), ")?;")]
#[doc = concat!("let m = NonZero::new(", $rot_result, ")?;")]
///
#[doc = concat!("assert_eq!(n.rotate_left(", $rot, "), m);")]
/// # Some(())
/// # }
/// ```
#[unstable(feature = "nonzero_bitwise", issue = "128281")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
pub const fn rotate_left(self, n: u32) -> Self {
let result = self.get().rotate_left(n);
// SAFETY: Rotating bits preserves the property int > 0.
unsafe { Self::new_unchecked(result) }
}
/// Shifts the bits to the right by a specified amount, `n`,
/// wrapping the truncated bits to the beginning of the resulting
/// integer.
///
/// Please note this isn't the same operation as the `>>` shifting operator!
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(nonzero_bitwise)]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let n = NonZero::new(", $rot_result, stringify!($Int), ")?;")]
#[doc = concat!("let m = NonZero::new(", $rot_op, ")?;")]
///
#[doc = concat!("assert_eq!(n.rotate_right(", $rot, "), m);")]
/// # Some(())
/// # }
/// ```
#[unstable(feature = "nonzero_bitwise", issue = "128281")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
pub const fn rotate_right(self, n: u32) -> Self {
let result = self.get().rotate_right(n);
// SAFETY: Rotating bits preserves the property int > 0.
unsafe { Self::new_unchecked(result) }
}
/// Reverses the byte order of the integer.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(nonzero_bitwise)]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let n = NonZero::new(", $swap_op, stringify!($Int), ")?;")]
/// let m = n.swap_bytes();
///
#[doc = concat!("assert_eq!(m, NonZero::new(", $swapped, ")?);")]
/// # Some(())
/// # }
/// ```
#[unstable(feature = "nonzero_bitwise", issue = "128281")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
pub const fn swap_bytes(self) -> Self {
let result = self.get().swap_bytes();
// SAFETY: Shuffling bytes preserves the property int > 0.
unsafe { Self::new_unchecked(result) }
}
/// Reverses the order of bits in the integer. The least significant bit becomes the most significant bit,
/// second least-significant bit becomes second most-significant bit, etc.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(nonzero_bitwise)]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let n = NonZero::new(", $swap_op, stringify!($Int), ")?;")]
/// let m = n.reverse_bits();
///
#[doc = concat!("assert_eq!(m, NonZero::new(", $reversed, ")?);")]
/// # Some(())
/// # }
/// ```
#[unstable(feature = "nonzero_bitwise", issue = "128281")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
pub const fn reverse_bits(self) -> Self {
let result = self.get().reverse_bits();
// SAFETY: Reversing bits preserves the property int > 0.
unsafe { Self::new_unchecked(result) }
}
/// Converts an integer from big endian to the target's endianness.
///
/// On big endian this is a no-op. On little endian the bytes are
/// swapped.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(nonzero_bitwise)]
/// # use std::num::NonZero;
#[doc = concat!("use std::num::", stringify!($Ty), ";")]
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let n = NonZero::new(0x1A", stringify!($Int), ")?;")]
///
/// if cfg!(target_endian = "big") {
#[doc = concat!(" assert_eq!(", stringify!($Ty), "::from_be(n), n)")]
/// } else {
#[doc = concat!(" assert_eq!(", stringify!($Ty), "::from_be(n), n.swap_bytes())")]
/// }
/// # Some(())
/// # }
/// ```
#[unstable(feature = "nonzero_bitwise", issue = "128281")]
#[must_use]
#[inline(always)]
pub const fn from_be(x: Self) -> Self {
let result = $Int::from_be(x.get());
// SAFETY: Shuffling bytes preserves the property int > 0.
unsafe { Self::new_unchecked(result) }
}
/// Converts an integer from little endian to the target's endianness.
///
/// On little endian this is a no-op. On big endian the bytes are
/// swapped.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(nonzero_bitwise)]
/// # use std::num::NonZero;
#[doc = concat!("use std::num::", stringify!($Ty), ";")]
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let n = NonZero::new(0x1A", stringify!($Int), ")?;")]
///
/// if cfg!(target_endian = "little") {
#[doc = concat!(" assert_eq!(", stringify!($Ty), "::from_le(n), n)")]
/// } else {
#[doc = concat!(" assert_eq!(", stringify!($Ty), "::from_le(n), n.swap_bytes())")]
/// }
/// # Some(())
/// # }
/// ```
#[unstable(feature = "nonzero_bitwise", issue = "128281")]
#[must_use]
#[inline(always)]
pub const fn from_le(x: Self) -> Self {
let result = $Int::from_le(x.get());
// SAFETY: Shuffling bytes preserves the property int > 0.
unsafe { Self::new_unchecked(result) }
}
/// Converts `self` to big endian from the target's endianness.
///
/// On big endian this is a no-op. On little endian the bytes are
/// swapped.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(nonzero_bitwise)]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let n = NonZero::new(0x1A", stringify!($Int), ")?;")]
///
/// if cfg!(target_endian = "big") {
/// assert_eq!(n.to_be(), n)
/// } else {
/// assert_eq!(n.to_be(), n.swap_bytes())
/// }
/// # Some(())
/// # }
/// ```
#[unstable(feature = "nonzero_bitwise", issue = "128281")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
pub const fn to_be(self) -> Self {
let result = self.get().to_be();
// SAFETY: Shuffling bytes preserves the property int > 0.
unsafe { Self::new_unchecked(result) }
}
/// Converts `self` to little endian from the target's endianness.
///
/// On little endian this is a no-op. On big endian the bytes are
/// swapped.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(nonzero_bitwise)]
/// # use std::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("let n = NonZero::new(0x1A", stringify!($Int), ")?;")]
///
/// if cfg!(target_endian = "little") {
/// assert_eq!(n.to_le(), n)
/// } else {
/// assert_eq!(n.to_le(), n.swap_bytes())
/// }
/// # Some(())
/// # }
/// ```
#[unstable(feature = "nonzero_bitwise", issue = "128281")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
pub const fn to_le(self) -> Self {
let result = self.get().to_le();
// SAFETY: Shuffling bytes preserves the property int > 0.
unsafe { Self::new_unchecked(result) }
}
nonzero_integer_signedness_dependent_methods! {
Primitive = $signedness $Int,
UnsignedPrimitive = $Uint,
@ -826,22 +1096,54 @@ fn from_str(src: &str) -> Result<Self, Self::Err> {
nonzero_integer_signedness_dependent_impls!($signedness $Int);
};
(Self = $Ty:ident, Primitive = unsigned $Int:ident $(,)?) => {
(
Self = $Ty:ident,
Primitive = unsigned $Int:ident,
rot = $rot:literal,
rot_op = $rot_op:literal,
rot_result = $rot_result:literal,
swap_op = $swap_op:literal,
swapped = $swapped:literal,
reversed = $reversed:literal,
$(,)?
) => {
nonzero_integer! {
#[stable(feature = "nonzero", since = "1.28.0")]
Self = $Ty,
Primitive = unsigned $Int,
UnsignedPrimitive = $Int,
rot = $rot,
rot_op = $rot_op,
rot_result = $rot_result,
swap_op = $swap_op,
swapped = $swapped,
reversed = $reversed,
leading_zeros_test = concat!(stringify!($Int), "::MAX"),
}
};
(Self = $Ty:ident, Primitive = signed $Int:ident, $($rest:tt)*) => {
(
Self = $Ty:ident,
Primitive = signed $Int:ident,
UnsignedPrimitive = $UInt:ident,
rot = $rot:literal,
rot_op = $rot_op:literal,
rot_result = $rot_result:literal,
swap_op = $swap_op:literal,
swapped = $swapped:literal,
reversed = $reversed:literal,
) => {
nonzero_integer! {
#[stable(feature = "signed_nonzero", since = "1.34.0")]
Self = $Ty,
Primitive = signed $Int,
$($rest)*
UnsignedPrimitive = $UInt,
rot = $rot,
rot_op = $rot_op,
rot_result = $rot_result,
swap_op = $swap_op,
swapped = $swapped,
reversed = $reversed,
leading_zeros_test = concat!("-1", stringify!($Int)),
}
};
@ -1241,6 +1543,7 @@ pub const fn is_power_of_two(self) -> bool {
/// assert_eq!(ten.isqrt(), three);
/// # Some(())
/// # }
/// ```
#[unstable(feature = "isqrt", issue = "116226")]
#[rustc_const_unstable(feature = "isqrt", issue = "116226")]
#[must_use = "this returns the result of the operation, \
@ -1704,65 +2007,189 @@ macro_rules! sign_dependent_expr {
nonzero_integer! {
Self = NonZeroU8,
Primitive = unsigned u8,
rot = 2,
rot_op = "0x82",
rot_result = "0xa",
swap_op = "0x12",
swapped = "0x12",
reversed = "0x48",
}
nonzero_integer! {
Self = NonZeroU16,
Primitive = unsigned u16,
rot = 4,
rot_op = "0xa003",
rot_result = "0x3a",
swap_op = "0x1234",
swapped = "0x3412",
reversed = "0x2c48",
}
nonzero_integer! {
Self = NonZeroU32,
Primitive = unsigned u32,
rot = 8,
rot_op = "0x10000b3",
rot_result = "0xb301",
swap_op = "0x12345678",
swapped = "0x78563412",
reversed = "0x1e6a2c48",
}
nonzero_integer! {
Self = NonZeroU64,
Primitive = unsigned u64,
rot = 12,
rot_op = "0xaa00000000006e1",
rot_result = "0x6e10aa",
swap_op = "0x1234567890123456",
swapped = "0x5634129078563412",
reversed = "0x6a2c48091e6a2c48",
}
nonzero_integer! {
Self = NonZeroU128,
Primitive = unsigned u128,
rot = 16,
rot_op = "0x13f40000000000000000000000004f76",
rot_result = "0x4f7613f4",
swap_op = "0x12345678901234567890123456789012",
swapped = "0x12907856341290785634129078563412",
reversed = "0x48091e6a2c48091e6a2c48091e6a2c48",
}
#[cfg(target_pointer_width = "16")]
nonzero_integer! {
Self = NonZeroUsize,
Primitive = unsigned usize,
rot = 4,
rot_op = "0xa003",
rot_result = "0x3a",
swap_op = "0x1234",
swapped = "0x3412",
reversed = "0x2c48",
}
#[cfg(target_pointer_width = "32")]
nonzero_integer! {
Self = NonZeroUsize,
Primitive = unsigned usize,
rot = 8,
rot_op = "0x10000b3",
rot_result = "0xb301",
swap_op = "0x12345678",
swapped = "0x78563412",
reversed = "0x1e6a2c48",
}
#[cfg(target_pointer_width = "64")]
nonzero_integer! {
Self = NonZeroUsize,
Primitive = unsigned usize,
rot = 12,
rot_op = "0xaa00000000006e1",
rot_result = "0x6e10aa",
swap_op = "0x1234567890123456",
swapped = "0x5634129078563412",
reversed = "0x6a2c48091e6a2c48",
}
nonzero_integer! {
Self = NonZeroI8,
Primitive = signed i8,
UnsignedPrimitive = u8,
rot = 2,
rot_op = "-0x7e",
rot_result = "0xa",
swap_op = "0x12",
swapped = "0x12",
reversed = "0x48",
}
nonzero_integer! {
Self = NonZeroI16,
Primitive = signed i16,
UnsignedPrimitive = u16,
rot = 4,
rot_op = "-0x5ffd",
rot_result = "0x3a",
swap_op = "0x1234",
swapped = "0x3412",
reversed = "0x2c48",
}
nonzero_integer! {
Self = NonZeroI32,
Primitive = signed i32,
UnsignedPrimitive = u32,
rot = 8,
rot_op = "0x10000b3",
rot_result = "0xb301",
swap_op = "0x12345678",
swapped = "0x78563412",
reversed = "0x1e6a2c48",
}
nonzero_integer! {
Self = NonZeroI64,
Primitive = signed i64,
UnsignedPrimitive = u64,
rot = 12,
rot_op = "0xaa00000000006e1",
rot_result = "0x6e10aa",
swap_op = "0x1234567890123456",
swapped = "0x5634129078563412",
reversed = "0x6a2c48091e6a2c48",
}
nonzero_integer! {
Self = NonZeroI128,
Primitive = signed i128,
UnsignedPrimitive = u128,
rot = 16,
rot_op = "0x13f40000000000000000000000004f76",
rot_result = "0x4f7613f4",
swap_op = "0x12345678901234567890123456789012",
swapped = "0x12907856341290785634129078563412",
reversed = "0x48091e6a2c48091e6a2c48091e6a2c48",
}
#[cfg(target_pointer_width = "16")]
nonzero_integer! {
Self = NonZeroIsize,
Primitive = signed isize,
UnsignedPrimitive = usize,
rot = 4,
rot_op = "-0x5ffd",
rot_result = "0x3a",
swap_op = "0x1234",
swapped = "0x3412",
reversed = "0x2c48",
}
#[cfg(target_pointer_width = "32")]
nonzero_integer! {
Self = NonZeroIsize,
Primitive = signed isize,
UnsignedPrimitive = usize,
rot = 8,
rot_op = "0x10000b3",
rot_result = "0xb301",
swap_op = "0x12345678",
swapped = "0x78563412",
reversed = "0x1e6a2c48",
}
#[cfg(target_pointer_width = "64")]
nonzero_integer! {
Self = NonZeroIsize,
Primitive = signed isize,
UnsignedPrimitive = usize,
rot = 12,
rot_op = "0xaa00000000006e1",
rot_result = "0x6e10aa",
swap_op = "0x1234567890123456",
swapped = "0x5634129078563412",
reversed = "0x6a2c48091e6a2c48",
}

View File

@ -4069,7 +4069,6 @@ pub fn as_simd_mut<const LANES: usize>(&mut self) -> (&mut [T], &mut [Simd<T, LA
/// # Examples
///
/// ```
/// #![feature(is_sorted)]
/// let empty: [i32; 0] = [];
///
/// assert!([1, 2, 2, 9].is_sorted());
@ -4079,7 +4078,7 @@ pub fn as_simd_mut<const LANES: usize>(&mut self) -> (&mut [T], &mut [Simd<T, LA
/// assert!(![0.0, 1.0, f32::NAN].is_sorted());
/// ```
#[inline]
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
#[stable(feature = "is_sorted", since = "CURRENT_RUSTC_VERSION")]
#[must_use]
pub fn is_sorted(&self) -> bool
where
@ -4096,8 +4095,6 @@ pub fn is_sorted(&self) -> bool
/// # Examples
///
/// ```
/// #![feature(is_sorted)]
///
/// assert!([1, 2, 2, 9].is_sorted_by(|a, b| a <= b));
/// assert!(![1, 2, 2, 9].is_sorted_by(|a, b| a < b));
///
@ -4108,7 +4105,7 @@ pub fn is_sorted(&self) -> bool
/// assert!(empty.is_sorted_by(|a, b| false));
/// assert!(empty.is_sorted_by(|a, b| true));
/// ```
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
#[stable(feature = "is_sorted", since = "CURRENT_RUSTC_VERSION")]
#[must_use]
pub fn is_sorted_by<'a, F>(&'a self, mut compare: F) -> bool
where
@ -4128,13 +4125,11 @@ pub fn is_sorted_by<'a, F>(&'a self, mut compare: F) -> bool
/// # Examples
///
/// ```
/// #![feature(is_sorted)]
///
/// assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
/// assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
/// ```
#[inline]
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
#[stable(feature = "is_sorted", since = "CURRENT_RUSTC_VERSION")]
#[must_use]
pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
where

View File

@ -44,7 +44,6 @@
#![feature(hasher_prefixfree_extras)]
#![feature(hashmap_internals)]
#![feature(try_find)]
#![feature(is_sorted)]
#![feature(layout_for_ptr)]
#![feature(pattern)]
#![feature(slice_take)]

View File

@ -15,3 +15,16 @@ rustc +nightly -Z unstable-options --target=wasm32-unknown-unknown --print targe
```
To use a custom target, see the (unstable) [`build-std` feature](../../cargo/reference/unstable.html#build-std) of `cargo`.
## Custom Target Lookup Path
When `rustc` is given an option `--target=TARGET` (where `TARGET` is any string), it uses the following logic:
1. if `TARGET` is the name of a built-in target, use that
2. if `TARGET` is a path to a file, read that file as a json target
3. otherwise, search the colon-seperated list of directories found
in the `RUST_TARGET_PATH` environment variable from left to right
for a file named `TARGET.json`.
These steps are tried in order, so if there are multple potentially valid
interpretations for a target, whichever is found first will take priority.
If none of these methods find a target, an error is thrown.

View File

@ -1,11 +0,0 @@
# `is_sorted`
The tracking issue for this feature is: [#53485]
[#53485]: https://github.com/rust-lang/rust/issues/53485
------------------------
Add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to `[T]`;
add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to
`Iterator`.

View File

@ -5,7 +5,6 @@
#![feature(f128)]
#![feature(f16)]
#![feature(if_let_guard)]
#![feature(is_sorted)]
#![feature(iter_intersperse)]
#![feature(iter_partition_in_place)]
#![feature(let_chains)]

View File

@ -1,4 +1,3 @@
#![feature(is_sorted)]
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
#![warn(rust_2018_idioms, unused_lifetimes)]
#![allow(unused_extern_crates)]

View File

@ -2,7 +2,6 @@
#![allow(clippy::needless_return)]
#![allow(clippy::unused_unit)]
#![allow(clippy::useless_vec)]
#![feature(is_sorted)]
struct Struct {
field: isize,

View File

@ -1,11 +1,11 @@
error: this closure returns the unit type which also implements Ord
--> tests/ui/unit_return_expecting_ord.rs:19:25
--> tests/ui/unit_return_expecting_ord.rs:18:25
|
LL | structs.sort_by_key(|s| {
| ^^^
|
help: probably caused by this trailing semicolon
--> tests/ui/unit_return_expecting_ord.rs:21:24
--> tests/ui/unit_return_expecting_ord.rs:20:24
|
LL | double(s.field);
| ^
@ -13,25 +13,25 @@ LL | double(s.field);
= help: to override `-D warnings` add `#[allow(clippy::unit_return_expecting_ord)]`
error: this closure returns the unit type which also implements PartialOrd
--> tests/ui/unit_return_expecting_ord.rs:24:30
--> tests/ui/unit_return_expecting_ord.rs:23:30
|
LL | structs.is_sorted_by_key(|s| {
| ^^^
|
help: probably caused by this trailing semicolon
--> tests/ui/unit_return_expecting_ord.rs:26:24
--> tests/ui/unit_return_expecting_ord.rs:25:24
|
LL | double(s.field);
| ^
error: this closure returns the unit type which also implements PartialOrd
--> tests/ui/unit_return_expecting_ord.rs:28:30
--> tests/ui/unit_return_expecting_ord.rs:27:30
|
LL | structs.is_sorted_by_key(|s| {
| ^^^
error: this closure returns the unit type which also implements Ord
--> tests/ui/unit_return_expecting_ord.rs:39:25
--> tests/ui/unit_return_expecting_ord.rs:38:25
|
LL | structs.sort_by_key(|s| unit(s.field));
| ^^^

View File

@ -0,0 +1,34 @@
# Rustbook
This is a wrapper around [`mdbook`](https://github.com/rust-lang/mdBook/), which is used to generate the book-style documentation in the Rust project. This wrapper serves a few purposes:
- Avoids some of mdbook's large, optional dependencies (like tokio, webserver, etc.).
- Makes it a little easier to customize and override some of mdbook's behaviors (like swapping in custom preprocessors).
- Supports vendoring of the source via Rust's normal release process.
This is invoked automatically when building mdbook-style documentation, for example via `./x doc`.
## Cargo workspace
This package defines a separate cargo workspace from the main Rust workspace for a few reasons (ref [#127786](https://github.com/rust-lang/rust/pull/127786):
- Avoids requiring checking out submodules for developers who are not working on the documentation. Otherwise, some submodules such as those that have custom preprocessors would be required for cargo to find the dependencies.
- Avoids problems with updating dependencies. Unfortunately this workspace has a rather large set of dependencies, which can make coordinating updates difficult (see [#127890](https://github.com/rust-lang/rust/issues/127890)).
## Custom preprocessors
Some books have custom mdbook preprocessors that need to be integrated with both the book's repository, and the build system here in the `rust-lang/rust` repository. To add a new preprocessor, there are few things to do:
1. Implement the preprocessor as a cargo library in the book's repository.
2. Add the `[preprocessor]` table to the book's `book.toml` file. I recommend setting the command so that the preprocessor gets built automatically. It may look something like:
```toml
[preprocessor.spec]
command = "cargo run --manifest-path my-cool-extension/Cargo.toml"
[build]
extra-watch-dirs = ["my-cool-extension/src"]
```
3. Add the preprocessor as a dependency in rustbook's `Cargo.toml`.
4. Call `with_preprocessor` in `rustbook/src/main.rs`.
5. Be sure to test that it generates correctly, such as running `./x doc MY-BOOK-NAME --open` and verify the content looks correct.
6. Also test tidy and your book, such as running `./x test tidy` and `./x test MY-BOOK-NAME`.

View File

@ -1,8 +1,6 @@
//@ check-pass
// regression test for https://github.com/rust-lang/rust/issues/53485#issuecomment-885393452
#![feature(is_sorted)]
struct A {
name: String,
}

View File

@ -0,0 +1,38 @@
//@ needs-asm-support
#![feature(naked_functions)]
#![crate_type = "lib"]
use std::arch::asm;
#[naked]
pub unsafe extern "C" fn inline_none() {
asm!("", options(noreturn));
}
#[naked]
#[inline]
//~^ ERROR [E0736]
pub unsafe extern "C" fn inline_hint() {
asm!("", options(noreturn));
}
#[naked]
#[inline(always)]
//~^ ERROR [E0736]
pub unsafe extern "C" fn inline_always() {
asm!("", options(noreturn));
}
#[naked]
#[inline(never)]
//~^ ERROR [E0736]
pub unsafe extern "C" fn inline_never() {
asm!("", options(noreturn));
}
#[naked]
#[cfg_attr(all(), inline(never))]
//~^ ERROR [E0736]
pub unsafe extern "C" fn conditional_inline_never() {
asm!("", options(noreturn));
}

View File

@ -0,0 +1,35 @@
error[E0736]: attribute incompatible with `#[naked]`
--> $DIR/naked-functions-inline.rs:13:1
|
LL | #[naked]
| -------- function marked with `#[naked]` here
LL | #[inline]
| ^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]`
error[E0736]: attribute incompatible with `#[naked]`
--> $DIR/naked-functions-inline.rs:20:1
|
LL | #[naked]
| -------- function marked with `#[naked]` here
LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]`
error[E0736]: attribute incompatible with `#[naked]`
--> $DIR/naked-functions-inline.rs:27:1
|
LL | #[naked]
| -------- function marked with `#[naked]` here
LL | #[inline(never)]
| ^^^^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]`
error[E0736]: attribute incompatible with `#[naked]`
--> $DIR/naked-functions-inline.rs:34:19
|
LL | #[naked]
| -------- function marked with `#[naked]` here
LL | #[cfg_attr(all(), inline(never))]
| ^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]`
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0736`.

View File

@ -0,0 +1,30 @@
//@ compile-flags: --target armv5te-unknown-linux-gnueabi
//@ needs-llvm-components: arm
//@ needs-asm-support
//@ build-pass
#![crate_type = "lib"]
#![feature(no_core, lang_items, rustc_attrs, naked_functions)]
#![no_core]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[lang = "sized"]
trait Sized {}
#[no_mangle]
#[naked]
#[instruction_set(arm::t32)]
unsafe extern "C" fn test_thumb() {
asm!("bx lr", options(noreturn));
}
#[no_mangle]
#[naked]
#[instruction_set(arm::t32)]
unsafe extern "C" fn test_arm() {
asm!("bx lr", options(noreturn));
}

View File

@ -0,0 +1,39 @@
//@ needs-asm-support
//@ compile-flags: --test
#![allow(undefined_naked_function_abi)]
#![feature(naked_functions)]
#![feature(test)]
#![crate_type = "lib"]
use std::arch::asm;
#[test]
#[naked]
//~^ ERROR [E0736]
fn test_naked() {
unsafe { asm!("", options(noreturn)) };
}
#[should_panic]
#[test]
#[naked]
//~^ ERROR [E0736]
fn test_naked_should_panic() {
unsafe { asm!("", options(noreturn)) };
}
#[ignore]
#[test]
#[naked]
//~^ ERROR [E0736]
fn test_naked_ignore() {
unsafe { asm!("", options(noreturn)) };
}
#[bench]
#[naked]
//~^ ERROR [E0736]
fn bench_naked() {
unsafe { asm!("", options(noreturn)) };
}

View File

@ -0,0 +1,35 @@
error[E0736]: cannot use `#[naked]` with testing attributes
--> $DIR/naked-functions-testattrs.rs:12:1
|
LL | #[test]
| ------- function marked with testing attribute here
LL | #[naked]
| ^^^^^^^^ `#[naked]` is incompatible with testing attributes
error[E0736]: cannot use `#[naked]` with testing attributes
--> $DIR/naked-functions-testattrs.rs:20:1
|
LL | #[test]
| ------- function marked with testing attribute here
LL | #[naked]
| ^^^^^^^^ `#[naked]` is incompatible with testing attributes
error[E0736]: cannot use `#[naked]` with testing attributes
--> $DIR/naked-functions-testattrs.rs:28:1
|
LL | #[test]
| ------- function marked with testing attribute here
LL | #[naked]
| ^^^^^^^^ `#[naked]` is incompatible with testing attributes
error[E0736]: cannot use `#[naked]` with testing attributes
--> $DIR/naked-functions-testattrs.rs:35:1
|
LL | #[bench]
| -------- function marked with testing attribute here
LL | #[naked]
| ^^^^^^^^ `#[naked]` is incompatible with testing attributes
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0736`.

View File

@ -3,7 +3,7 @@
//@ ignore-spirv
#![feature(naked_functions)]
#![feature(asm_const, asm_unwind)]
#![feature(asm_const, asm_unwind, linkage)]
#![crate_type = "lib"]
use std::arch::asm;
@ -163,42 +163,6 @@ pub extern "C" fn valid_b() {
}
#[naked]
pub unsafe extern "C" fn inline_none() {
asm!("", options(noreturn));
}
#[naked]
#[inline]
//~^ ERROR naked functions cannot be inlined
pub unsafe extern "C" fn inline_hint() {
asm!("", options(noreturn));
}
#[naked]
#[inline(always)]
//~^ ERROR naked functions cannot be inlined
pub unsafe extern "C" fn inline_always() {
asm!("", options(noreturn));
}
#[naked]
#[inline(never)]
//~^ ERROR naked functions cannot be inlined
pub unsafe extern "C" fn inline_never() {
asm!("", options(noreturn));
}
#[naked]
#[inline]
//~^ ERROR naked functions cannot be inlined
#[inline(always)]
//~^ ERROR naked functions cannot be inlined
#[inline(never)]
//~^ ERROR naked functions cannot be inlined
pub unsafe extern "C" fn inline_all() {
asm!("", options(noreturn));
}
#[naked]
pub unsafe extern "C" fn allow_compile_error(a: u32) -> u32 {
compile_error!("this is a user specified error")
@ -217,3 +181,71 @@ pub extern "C" fn valid_b() {
asm!(invalid_syntax)
//~^ ERROR asm template must be a string literal
}
#[cfg(target_arch = "x86_64")]
#[cfg_attr(target_pointer_width = "64", no_mangle)]
#[naked]
pub unsafe extern "C" fn compatible_cfg_attributes() {
asm!("", options(noreturn, att_syntax));
}
#[allow(dead_code)]
#[warn(dead_code)]
#[deny(dead_code)]
#[forbid(dead_code)]
#[naked]
pub unsafe extern "C" fn compatible_diagnostic_attributes() {
asm!("", options(noreturn, raw));
}
#[deprecated = "test"]
#[naked]
pub unsafe extern "C" fn compatible_deprecated_attributes() {
asm!("", options(noreturn, raw));
}
#[cfg(target_arch = "x86_64")]
#[must_use]
#[naked]
pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 {
asm!(
"
mov rax, 42
ret
",
options(noreturn)
)
}
#[export_name = "exported_function_name"]
#[link_section = ".custom_section"]
#[no_mangle]
#[naked]
pub unsafe extern "C" fn compatible_ffi_attributes_1() {
asm!("", options(noreturn, raw));
}
#[cold]
#[naked]
pub unsafe extern "C" fn compatible_codegen_attributes() {
asm!("", options(noreturn, raw));
}
#[cfg(target_arch = "x86_64")]
#[target_feature(enable = "sse2")]
#[naked]
pub unsafe extern "C" fn compatible_target_feature() {
asm!("", options(noreturn));
}
#[doc = "foo bar baz"]
#[naked]
pub unsafe extern "C" fn compatible_doc_attributes() {
asm!("", options(noreturn, raw));
}
#[linkage = "external"]
#[naked]
pub unsafe extern "C" fn compatible_linkage() {
asm!("", options(noreturn, raw));
}

View File

@ -5,19 +5,19 @@ LL | asm!("", options(readonly, nostack), options(pure));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^
error: this is a user specified error
--> $DIR/naked-functions.rs:204:5
--> $DIR/naked-functions.rs:168:5
|
LL | compile_error!("this is a user specified error")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this is a user specified error
--> $DIR/naked-functions.rs:210:5
--> $DIR/naked-functions.rs:174:5
|
LL | compile_error!("this is a user specified error");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: asm template must be a string literal
--> $DIR/naked-functions.rs:217:10
--> $DIR/naked-functions.rs:181:10
|
LL | asm!(invalid_syntax)
| ^^^^^^^^^^^^^^
@ -249,42 +249,6 @@ warning: Rust ABI is unsupported in naked functions
LL | pub unsafe fn rust_abi() {
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: naked functions cannot be inlined
--> $DIR/naked-functions.rs:171:1
|
LL | #[inline]
| ^^^^^^^^^
error: naked functions cannot be inlined
--> $DIR/naked-functions.rs:178:1
|
LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^
error: naked functions cannot be inlined
--> $DIR/naked-functions.rs:185:1
|
LL | #[inline(never)]
| ^^^^^^^^^^^^^^^^
error: naked functions cannot be inlined
--> $DIR/naked-functions.rs:192:1
|
LL | #[inline]
| ^^^^^^^^^
error: naked functions cannot be inlined
--> $DIR/naked-functions.rs:194:1
|
LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^
error: naked functions cannot be inlined
--> $DIR/naked-functions.rs:196:1
|
LL | #[inline(never)]
| ^^^^^^^^^^^^^^^^
error: aborting due to 33 previous errors; 2 warnings emitted
error: aborting due to 27 previous errors; 2 warnings emitted
For more information about this error, try `rustc --explain E0787`.

View File

@ -1,13 +0,0 @@
fn main() {
// Assert `Iterator` methods are unstable
assert!([1, 2, 2, 9].iter().is_sorted());
//~^ ERROR: use of unstable library feature 'is_sorted': new API
assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
//~^ ERROR: use of unstable library feature 'is_sorted': new API
// Assert `[T]` methods are unstable
assert!([1, 2, 2, 9].is_sorted());
//~^ ERROR: use of unstable library feature 'is_sorted': new API
assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
//~^ ERROR: use of unstable library feature 'is_sorted': new API
}

View File

@ -1,43 +0,0 @@
error[E0658]: use of unstable library feature 'is_sorted': new API
--> $DIR/feature-gate-is_sorted.rs:3:33
|
LL | assert!([1, 2, 2, 9].iter().is_sorted());
| ^^^^^^^^^
|
= note: see issue #53485 <https://github.com/rust-lang/rust/issues/53485> for more information
= help: add `#![feature(is_sorted)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: use of unstable library feature 'is_sorted': new API
--> $DIR/feature-gate-is_sorted.rs:5:39
|
LL | assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
| ^^^^^^^^^^^^^^^^
|
= note: see issue #53485 <https://github.com/rust-lang/rust/issues/53485> for more information
= help: add `#![feature(is_sorted)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: use of unstable library feature 'is_sorted': new API
--> $DIR/feature-gate-is_sorted.rs:9:26
|
LL | assert!([1, 2, 2, 9].is_sorted());
| ^^^^^^^^^
|
= note: see issue #53485 <https://github.com/rust-lang/rust/issues/53485> for more information
= help: add `#![feature(is_sorted)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: use of unstable library feature 'is_sorted': new API
--> $DIR/feature-gate-is_sorted.rs:11:32
|
LL | assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
| ^^^^^^^^^^^^^^^^
|
= note: see issue #53485 <https://github.com/rust-lang/rust/issues/53485> for more information
= help: add `#![feature(is_sorted)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -3,7 +3,7 @@
use std::arch::asm;
#[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]`
#[track_caller] //~ ERROR [E0736]
//~^ ERROR `#[track_caller]` requires Rust ABI
#[naked]
extern "C" fn f() {
@ -15,7 +15,7 @@ extern "C" fn f() {
struct S;
impl S {
#[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]`
#[track_caller] //~ ERROR [E0736]
//~^ ERROR `#[track_caller]` requires Rust ABI
#[naked]
extern "C" fn g() {

View File

@ -1,14 +1,20 @@
error[E0736]: cannot use `#[track_caller]` with `#[naked]`
error[E0736]: attribute incompatible with `#[naked]`
--> $DIR/error-with-naked.rs:6:1
|
LL | #[track_caller]
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ the `track_caller` attribute is incompatible with `#[naked]`
LL |
LL | #[naked]
| -------- function marked with `#[naked]` here
error[E0736]: cannot use `#[track_caller]` with `#[naked]`
error[E0736]: attribute incompatible with `#[naked]`
--> $DIR/error-with-naked.rs:18:5
|
LL | #[track_caller]
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ the `track_caller` attribute is incompatible with `#[naked]`
LL |
LL | #[naked]
| -------- function marked with `#[naked]` here
error[E0737]: `#[track_caller]` requires Rust ABI
--> $DIR/error-with-naked.rs:6:1