Auto merge of #145334 - Kobzol:rollup-fs5a133, r=Kobzol

Rollup of 11 pull requests

Successful merges:

 - rust-lang/rust#143467 (Add ASCII-related methods from `u8` and `MIN`/`MAX` to `core::ascii::Char`)
 - rust-lang/rust#144519 (Constify `SystemTime` methods)
 - rust-lang/rust#144642 (editorconfig: don't trim trailing whitespace in tests)
 - rust-lang/rust#144870 (Stabilize `path_file_prefix` feature)
 - rust-lang/rust#145269 (Deprecate RUST_TEST_* env variables)
 - rust-lang/rust#145274 (Remove unused `#[must_use]`)
 - rust-lang/rust#145289 (chore(ci): upgrade checkout to v5)
 - rust-lang/rust#145303 (Docs: Link to payload_as_str() from payload().)
 - rust-lang/rust#145308 (Adjust documentation of `dangling`)
 - rust-lang/rust#145320 (Allow cross-compiling the Cranelift dist component)
 - rust-lang/rust#145325 (Add `cast_init` and `cast_uninit` methods for pointers)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors
2025-08-13 07:27:12 +00:00
48 changed files with 1276 additions and 330 deletions

View File

@@ -7,9 +7,18 @@ root = true
[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
# some tests need trailing whitespace in output snapshots
[!tests/]
trim_trailing_whitespace = true
# for actual source code files of test, we still don't want trailing whitespace
[tests/**.{rs,js}]
trim_trailing_whitespace = true
# these specific source files need to have trailing whitespace.
[tests/ui/{frontmatter/frontmatter-whitespace-3.rs,parser/shebang/shebang-space.rs}]
trim_trailing_whitespace = false
[!src/llvm-project]
indent_style = space
indent_size = 4

View File

@@ -52,7 +52,7 @@ jobs:
run_type: ${{ steps.jobs.outputs.run_type }}
steps:
- name: Checkout the source code
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Test citool
# Only test citool on the auto branch, to reduce latency of the calculate matrix job
# on PR/try builds.
@@ -113,7 +113,7 @@ jobs:
run: git config --global core.autocrlf false
- name: checkout the source code
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 2
@@ -313,7 +313,7 @@ jobs:
if: ${{ !cancelled() && contains(fromJSON('["auto", "try"]'), needs.calculate_matrix.outputs.run_type) }}
steps:
- name: checkout the source code
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 2
# Calculate the exit status of the whole CI workflow.

View File

@@ -51,7 +51,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: checkout the source code
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
submodules: recursive
- name: install the bootstrap toolchain
@@ -101,7 +101,7 @@ jobs:
pull-requests: write
steps:
- name: checkout the source code
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: download Cargo.lock from update job
uses: actions/download-artifact@v4

View File

@@ -29,7 +29,7 @@ jobs:
# Needed to write to the ghcr.io registry
packages: write
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
persist-credentials: false

View File

@@ -15,7 +15,7 @@ jobs:
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
# Make sure that we have enough commits to find the parent merge commit.
# Since all merges should be through merge commits, fetching two commits

View File

@@ -2155,6 +2155,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
attr_name,
macro_name: pprust::path_to_string(&call.path),
invoc_span: call.path.span,
attr_span: attr.span,
},
);
}

View File

@@ -983,6 +983,7 @@ lint_unused_allocation_mut = unnecessary allocation, use `&mut` instead
lint_unused_builtin_attribute = unused attribute `{$attr_name}`
.note = the built-in attribute `{$attr_name}` will be ignored, since it's applied to the macro invocation `{$macro_name}`
.suggestion = remove the attribute
lint_unused_closure =
unused {$pre}{$count ->

View File

@@ -205,8 +205,14 @@ pub fn decorate_builtin_lint(
}
.decorate_lint(diag);
}
BuiltinLintDiag::UnusedBuiltinAttribute { attr_name, macro_name, invoc_span } => {
lints::UnusedBuiltinAttribute { invoc_span, attr_name, macro_name }.decorate_lint(diag);
BuiltinLintDiag::UnusedBuiltinAttribute {
attr_name,
macro_name,
invoc_span,
attr_span,
} => {
lints::UnusedBuiltinAttribute { invoc_span, attr_name, macro_name, attr_span }
.decorate_lint(diag);
}
BuiltinLintDiag::TrailingMacro(is_trailing, name) => {
lints::TrailingMacro { is_trailing, name }.decorate_lint(diag);

View File

@@ -2938,9 +2938,10 @@ pub(crate) struct RawPrefix {
pub(crate) struct UnusedBuiltinAttribute {
#[note]
pub invoc_span: Span,
pub attr_name: Symbol,
pub macro_name: String,
#[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
pub attr_span: Span,
}
#[derive(LintDiagnostic)]

View File

@@ -647,6 +647,7 @@ pub enum BuiltinLintDiag {
attr_name: Symbol,
macro_name: String,
invoc_span: Span,
attr_span: Span,
},
PatternsInFnsWithoutBody {
span: Span,

View File

@@ -510,6 +510,7 @@ passes_must_not_suspend =
passes_must_use_no_effect =
`#[must_use]` has no effect when applied to {$article} {$target}
.suggestion = remove the attribute
passes_no_link =
attribute should be applied to an `extern crate` item

View File

@@ -1622,7 +1622,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
UNUSED_ATTRIBUTES,
hir_id,
attr_span,
errors::MustUseNoEffect { article, target },
errors::MustUseNoEffect { article, target, attr_span },
);
}

View File

@@ -469,6 +469,8 @@ pub(crate) struct FfiConstInvalidTarget {
pub(crate) struct MustUseNoEffect {
pub article: &'static str,
pub target: rustc_hir::Target,
#[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
pub attr_span: Span,
}
#[derive(Diagnostic)]

View File

@@ -102,6 +102,7 @@
#![feature(async_iterator)]
#![feature(bstr)]
#![feature(bstr_internals)]
#![feature(cast_maybe_uninit)]
#![feature(char_internals)]
#![feature(char_max_len)]
#![feature(clone_to_uninit)]

View File

@@ -3176,7 +3176,7 @@ impl<T, A: Allocator> Vec<T, A> {
// - but the allocation extends out to `self.buf.capacity()` elements, possibly
// uninitialized
let spare_ptr = unsafe { ptr.add(self.len) };
let spare_ptr = spare_ptr.cast::<MaybeUninit<T>>();
let spare_ptr = spare_ptr.cast_uninit();
let spare_len = self.buf.capacity() - self.len;
// SAFETY:

View File

@@ -226,10 +226,10 @@ impl Layout {
/// Creates a `NonNull` that is dangling, but well-aligned for this Layout.
///
/// Note that the pointer value may potentially represent a valid pointer,
/// which means this must not be used as a "not yet initialized"
/// sentinel value. Types that lazily allocate must track initialization by
/// some other means.
/// Note that the address of the returned pointer may potentially
/// be that of a valid pointer, which means this must not be used
/// as a "not yet initialized" sentinel value.
/// Types that lazily allocate must track initialization by some other means.
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[must_use]
#[inline]

View File

@@ -445,7 +445,15 @@ pub enum AsciiChar {
}
impl AsciiChar {
/// Creates an ascii character from the byte `b`,
/// The character with the lowest ASCII code.
#[unstable(feature = "ascii_char", issue = "110998")]
pub const MIN: Self = Self::Null;
/// The character with the highest ASCII code.
#[unstable(feature = "ascii_char", issue = "110998")]
pub const MAX: Self = Self::Delete;
/// Creates an ASCII character from the byte `b`,
/// or returns `None` if it's too large.
#[unstable(feature = "ascii_char", issue = "110998")]
#[inline]
@@ -540,6 +548,608 @@ impl AsciiChar {
pub const fn as_str(&self) -> &str {
crate::slice::from_ref(self).as_str()
}
/// Makes a copy of the value in its upper case equivalent.
///
/// Letters 'a' to 'z' are mapped to 'A' to 'Z'.
///
/// To uppercase the value in-place, use [`make_uppercase`].
///
/// # Examples
///
/// ```
/// #![feature(ascii_char, ascii_char_variants)]
/// use std::ascii;
///
/// let lowercase_a = ascii::Char::SmallA;
///
/// assert_eq!(
/// ascii::Char::CapitalA,
/// lowercase_a.to_uppercase(),
/// );
/// ```
///
/// [`make_uppercase`]: Self::make_uppercase
#[must_use = "to uppercase the value in-place, use `make_uppercase()`"]
#[unstable(feature = "ascii_char", issue = "110998")]
#[inline]
pub const fn to_uppercase(self) -> Self {
let uppercase_byte = self.to_u8().to_ascii_uppercase();
// SAFETY: Toggling the 6th bit won't convert ASCII to non-ASCII.
unsafe { Self::from_u8_unchecked(uppercase_byte) }
}
/// Makes a copy of the value in its lower case equivalent.
///
/// Letters 'A' to 'Z' are mapped to 'a' to 'z'.
///
/// To lowercase the value in-place, use [`make_lowercase`].
///
/// # Examples
///
/// ```
/// #![feature(ascii_char, ascii_char_variants)]
/// use std::ascii;
///
/// let uppercase_a = ascii::Char::CapitalA;
///
/// assert_eq!(
/// ascii::Char::SmallA,
/// uppercase_a.to_lowercase(),
/// );
/// ```
///
/// [`make_lowercase`]: Self::make_lowercase
#[must_use = "to lowercase the value in-place, use `make_lowercase()`"]
#[unstable(feature = "ascii_char", issue = "110998")]
#[inline]
pub const fn to_lowercase(self) -> Self {
let lowercase_byte = self.to_u8().to_ascii_lowercase();
// SAFETY: Setting the 6th bit won't convert ASCII to non-ASCII.
unsafe { Self::from_u8_unchecked(lowercase_byte) }
}
/// Checks that two values are a case-insensitive match.
///
/// This is equivalent to `to_lowercase(a) == to_lowercase(b)`.
///
/// # Examples
///
/// ```
/// #![feature(ascii_char, ascii_char_variants)]
/// use std::ascii;
///
/// let lowercase_a = ascii::Char::SmallA;
/// let uppercase_a = ascii::Char::CapitalA;
///
/// assert!(lowercase_a.eq_ignore_case(uppercase_a));
/// ```
#[unstable(feature = "ascii_char", issue = "110998")]
#[inline]
pub const fn eq_ignore_case(self, other: Self) -> bool {
// FIXME(const-hack) `arg.to_u8().to_ascii_lowercase()` -> `arg.to_lowercase()`
// once `PartialEq` is const for `Self`.
self.to_u8().to_ascii_lowercase() == other.to_u8().to_ascii_lowercase()
}
/// Converts this value to its upper case equivalent in-place.
///
/// Letters 'a' to 'z' are mapped to 'A' to 'Z'.
///
/// To return a new uppercased value without modifying the existing one, use
/// [`to_uppercase`].
///
/// # Examples
///
/// ```
/// #![feature(ascii_char, ascii_char_variants)]
/// use std::ascii;
///
/// let mut letter_a = ascii::Char::SmallA;
///
/// letter_a.make_uppercase();
///
/// assert_eq!(ascii::Char::CapitalA, letter_a);
/// ```
///
/// [`to_uppercase`]: Self::to_uppercase
#[unstable(feature = "ascii_char", issue = "110998")]
#[inline]
pub const fn make_uppercase(&mut self) {
*self = self.to_uppercase();
}
/// Converts this value to its lower case equivalent in-place.
///
/// Letters 'A' to 'Z' are mapped to 'a' to 'z'.
///
/// To return a new lowercased value without modifying the existing one, use
/// [`to_lowercase`].
///
/// # Examples
///
/// ```
/// #![feature(ascii_char, ascii_char_variants)]
/// use std::ascii;
///
/// let mut letter_a = ascii::Char::CapitalA;
///
/// letter_a.make_lowercase();
///
/// assert_eq!(ascii::Char::SmallA, letter_a);
/// ```
///
/// [`to_lowercase`]: Self::to_lowercase
#[unstable(feature = "ascii_char", issue = "110998")]
#[inline]
pub const fn make_lowercase(&mut self) {
*self = self.to_lowercase();
}
/// Checks if the value is an alphabetic character:
///
/// - 0x41 'A' ..= 0x5A 'Z', or
/// - 0x61 'a' ..= 0x7A 'z'.
///
/// # Examples
///
/// ```
/// #![feature(ascii_char, ascii_char_variants)]
/// use std::ascii;
///
/// let uppercase_a = ascii::Char::CapitalA;
/// let uppercase_g = ascii::Char::CapitalG;
/// let a = ascii::Char::SmallA;
/// let g = ascii::Char::SmallG;
/// let zero = ascii::Char::Digit0;
/// let percent = ascii::Char::PercentSign;
/// let space = ascii::Char::Space;
/// let lf = ascii::Char::LineFeed;
/// let esc = ascii::Char::Escape;
///
/// assert!(uppercase_a.is_alphabetic());
/// assert!(uppercase_g.is_alphabetic());
/// assert!(a.is_alphabetic());
/// assert!(g.is_alphabetic());
/// assert!(!zero.is_alphabetic());
/// assert!(!percent.is_alphabetic());
/// assert!(!space.is_alphabetic());
/// assert!(!lf.is_alphabetic());
/// assert!(!esc.is_alphabetic());
/// ```
#[must_use]
#[unstable(feature = "ascii_char", issue = "110998")]
#[inline]
pub const fn is_alphabetic(self) -> bool {
self.to_u8().is_ascii_alphabetic()
}
/// Checks if the value is an uppercase character:
/// 0x41 'A' ..= 0x5A 'Z'.
///
/// # Examples
///
/// ```
/// #![feature(ascii_char, ascii_char_variants)]
/// use std::ascii;
///
/// let uppercase_a = ascii::Char::CapitalA;
/// let uppercase_g = ascii::Char::CapitalG;
/// let a = ascii::Char::SmallA;
/// let g = ascii::Char::SmallG;
/// let zero = ascii::Char::Digit0;
/// let percent = ascii::Char::PercentSign;
/// let space = ascii::Char::Space;
/// let lf = ascii::Char::LineFeed;
/// let esc = ascii::Char::Escape;
///
/// assert!(uppercase_a.is_uppercase());
/// assert!(uppercase_g.is_uppercase());
/// assert!(!a.is_uppercase());
/// assert!(!g.is_uppercase());
/// assert!(!zero.is_uppercase());
/// assert!(!percent.is_uppercase());
/// assert!(!space.is_uppercase());
/// assert!(!lf.is_uppercase());
/// assert!(!esc.is_uppercase());
/// ```
#[must_use]
#[unstable(feature = "ascii_char", issue = "110998")]
#[inline]
pub const fn is_uppercase(self) -> bool {
self.to_u8().is_ascii_uppercase()
}
/// Checks if the value is a lowercase character:
/// 0x61 'a' ..= 0x7A 'z'.
///
/// # Examples
///
/// ```
/// #![feature(ascii_char, ascii_char_variants)]
/// use std::ascii;
///
/// let uppercase_a = ascii::Char::CapitalA;
/// let uppercase_g = ascii::Char::CapitalG;
/// let a = ascii::Char::SmallA;
/// let g = ascii::Char::SmallG;
/// let zero = ascii::Char::Digit0;
/// let percent = ascii::Char::PercentSign;
/// let space = ascii::Char::Space;
/// let lf = ascii::Char::LineFeed;
/// let esc = ascii::Char::Escape;
///
/// assert!(!uppercase_a.is_lowercase());
/// assert!(!uppercase_g.is_lowercase());
/// assert!(a.is_lowercase());
/// assert!(g.is_lowercase());
/// assert!(!zero.is_lowercase());
/// assert!(!percent.is_lowercase());
/// assert!(!space.is_lowercase());
/// assert!(!lf.is_lowercase());
/// assert!(!esc.is_lowercase());
/// ```
#[must_use]
#[unstable(feature = "ascii_char", issue = "110998")]
#[inline]
pub const fn is_lowercase(self) -> bool {
self.to_u8().is_ascii_lowercase()
}
/// Checks if the value is an alphanumeric character:
///
/// - 0x41 'A' ..= 0x5A 'Z', or
/// - 0x61 'a' ..= 0x7A 'z', or
/// - 0x30 '0' ..= 0x39 '9'.
///
/// # Examples
///
/// ```
/// #![feature(ascii_char, ascii_char_variants)]
/// use std::ascii;
///
/// let uppercase_a = ascii::Char::CapitalA;
/// let uppercase_g = ascii::Char::CapitalG;
/// let a = ascii::Char::SmallA;
/// let g = ascii::Char::SmallG;
/// let zero = ascii::Char::Digit0;
/// let percent = ascii::Char::PercentSign;
/// let space = ascii::Char::Space;
/// let lf = ascii::Char::LineFeed;
/// let esc = ascii::Char::Escape;
///
/// assert!(uppercase_a.is_alphanumeric());
/// assert!(uppercase_g.is_alphanumeric());
/// assert!(a.is_alphanumeric());
/// assert!(g.is_alphanumeric());
/// assert!(zero.is_alphanumeric());
/// assert!(!percent.is_alphanumeric());
/// assert!(!space.is_alphanumeric());
/// assert!(!lf.is_alphanumeric());
/// assert!(!esc.is_alphanumeric());
/// ```
#[must_use]
#[unstable(feature = "ascii_char", issue = "110998")]
#[inline]
pub const fn is_alphanumeric(self) -> bool {
self.to_u8().is_ascii_alphanumeric()
}
/// Checks if the value is a decimal digit:
/// 0x30 '0' ..= 0x39 '9'.
///
/// # Examples
///
/// ```
/// #![feature(ascii_char, ascii_char_variants)]
/// use std::ascii;
///
/// let uppercase_a = ascii::Char::CapitalA;
/// let uppercase_g = ascii::Char::CapitalG;
/// let a = ascii::Char::SmallA;
/// let g = ascii::Char::SmallG;
/// let zero = ascii::Char::Digit0;
/// let percent = ascii::Char::PercentSign;
/// let space = ascii::Char::Space;
/// let lf = ascii::Char::LineFeed;
/// let esc = ascii::Char::Escape;
///
/// assert!(!uppercase_a.is_digit());
/// assert!(!uppercase_g.is_digit());
/// assert!(!a.is_digit());
/// assert!(!g.is_digit());
/// assert!(zero.is_digit());
/// assert!(!percent.is_digit());
/// assert!(!space.is_digit());
/// assert!(!lf.is_digit());
/// assert!(!esc.is_digit());
/// ```
#[must_use]
#[unstable(feature = "ascii_char", issue = "110998")]
#[inline]
pub const fn is_digit(self) -> bool {
self.to_u8().is_ascii_digit()
}
/// Checks if the value is an octal digit:
/// 0x30 '0' ..= 0x37 '7'.
///
/// # Examples
///
/// ```
/// #![feature(ascii_char, ascii_char_variants, is_ascii_octdigit)]
///
/// use std::ascii;
///
/// let uppercase_a = ascii::Char::CapitalA;
/// let a = ascii::Char::SmallA;
/// let zero = ascii::Char::Digit0;
/// let seven = ascii::Char::Digit7;
/// let eight = ascii::Char::Digit8;
/// let percent = ascii::Char::PercentSign;
/// let lf = ascii::Char::LineFeed;
/// let esc = ascii::Char::Escape;
///
/// assert!(!uppercase_a.is_octdigit());
/// assert!(!a.is_octdigit());
/// assert!(zero.is_octdigit());
/// assert!(seven.is_octdigit());
/// assert!(!eight.is_octdigit());
/// assert!(!percent.is_octdigit());
/// assert!(!lf.is_octdigit());
/// assert!(!esc.is_octdigit());
/// ```
#[must_use]
// This is blocked on two unstable features. Please ensure both are
// stabilized before marking this method as stable.
#[unstable(feature = "ascii_char", issue = "110998")]
// #[unstable(feature = "is_ascii_octdigit", issue = "101288")]
#[inline]
pub const fn is_octdigit(self) -> bool {
self.to_u8().is_ascii_octdigit()
}
/// Checks if the value is a hexadecimal digit:
///
/// - 0x30 '0' ..= 0x39 '9', or
/// - 0x41 'A' ..= 0x46 'F', or
/// - 0x61 'a' ..= 0x66 'f'.
///
/// # Examples
///
/// ```
/// #![feature(ascii_char, ascii_char_variants)]
/// use std::ascii;
///
/// let uppercase_a = ascii::Char::CapitalA;
/// let uppercase_g = ascii::Char::CapitalG;
/// let a = ascii::Char::SmallA;
/// let g = ascii::Char::SmallG;
/// let zero = ascii::Char::Digit0;
/// let percent = ascii::Char::PercentSign;
/// let space = ascii::Char::Space;
/// let lf = ascii::Char::LineFeed;
/// let esc = ascii::Char::Escape;
///
/// assert!(uppercase_a.is_hexdigit());
/// assert!(!uppercase_g.is_hexdigit());
/// assert!(a.is_hexdigit());
/// assert!(!g.is_hexdigit());
/// assert!(zero.is_hexdigit());
/// assert!(!percent.is_hexdigit());
/// assert!(!space.is_hexdigit());
/// assert!(!lf.is_hexdigit());
/// assert!(!esc.is_hexdigit());
/// ```
#[must_use]
#[unstable(feature = "ascii_char", issue = "110998")]
#[inline]
pub const fn is_hexdigit(self) -> bool {
self.to_u8().is_ascii_hexdigit()
}
/// Checks if the value is a punctuation character:
///
/// - 0x21 ..= 0x2F `! " # $ % & ' ( ) * + , - . /`, or
/// - 0x3A ..= 0x40 `: ; < = > ? @`, or
/// - 0x5B ..= 0x60 `` [ \ ] ^ _ ` ``, or
/// - 0x7B ..= 0x7E `{ | } ~`
///
/// # Examples
///
/// ```
/// #![feature(ascii_char, ascii_char_variants)]
/// use std::ascii;
///
/// let uppercase_a = ascii::Char::CapitalA;
/// let uppercase_g = ascii::Char::CapitalG;
/// let a = ascii::Char::SmallA;
/// let g = ascii::Char::SmallG;
/// let zero = ascii::Char::Digit0;
/// let percent = ascii::Char::PercentSign;
/// let space = ascii::Char::Space;
/// let lf = ascii::Char::LineFeed;
/// let esc = ascii::Char::Escape;
///
/// assert!(!uppercase_a.is_punctuation());
/// assert!(!uppercase_g.is_punctuation());
/// assert!(!a.is_punctuation());
/// assert!(!g.is_punctuation());
/// assert!(!zero.is_punctuation());
/// assert!(percent.is_punctuation());
/// assert!(!space.is_punctuation());
/// assert!(!lf.is_punctuation());
/// assert!(!esc.is_punctuation());
/// ```
#[must_use]
#[unstable(feature = "ascii_char", issue = "110998")]
#[inline]
pub const fn is_punctuation(self) -> bool {
self.to_u8().is_ascii_punctuation()
}
/// Checks if the value is a graphic character:
/// 0x21 '!' ..= 0x7E '~'.
///
/// # Examples
///
/// ```
/// #![feature(ascii_char, ascii_char_variants)]
/// use std::ascii;
///
/// let uppercase_a = ascii::Char::CapitalA;
/// let uppercase_g = ascii::Char::CapitalG;
/// let a = ascii::Char::SmallA;
/// let g = ascii::Char::SmallG;
/// let zero = ascii::Char::Digit0;
/// let percent = ascii::Char::PercentSign;
/// let space = ascii::Char::Space;
/// let lf = ascii::Char::LineFeed;
/// let esc = ascii::Char::Escape;
///
/// assert!(uppercase_a.is_graphic());
/// assert!(uppercase_g.is_graphic());
/// assert!(a.is_graphic());
/// assert!(g.is_graphic());
/// assert!(zero.is_graphic());
/// assert!(percent.is_graphic());
/// assert!(!space.is_graphic());
/// assert!(!lf.is_graphic());
/// assert!(!esc.is_graphic());
/// ```
#[must_use]
#[unstable(feature = "ascii_char", issue = "110998")]
#[inline]
pub const fn is_graphic(self) -> bool {
self.to_u8().is_ascii_graphic()
}
/// Checks if the value is a whitespace character:
/// 0x20 SPACE, 0x09 HORIZONTAL TAB, 0x0A LINE FEED,
/// 0x0C FORM FEED, or 0x0D CARRIAGE RETURN.
///
/// Rust uses the WhatWG Infra Standard's [definition of ASCII
/// whitespace][infra-aw]. There are several other definitions in
/// wide use. For instance, [the POSIX locale][pct] includes
/// 0x0B VERTICAL TAB as well as all the above characters,
/// but—from the very same specification—[the default rule for
/// "field splitting" in the Bourne shell][bfs] considers *only*
/// SPACE, HORIZONTAL TAB, and LINE FEED as whitespace.
///
/// If you are writing a program that will process an existing
/// file format, check what that format's definition of whitespace is
/// before using this function.
///
/// [infra-aw]: https://infra.spec.whatwg.org/#ascii-whitespace
/// [pct]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01
/// [bfs]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05
///
/// # Examples
///
/// ```
/// #![feature(ascii_char, ascii_char_variants)]
/// use std::ascii;
///
/// let uppercase_a = ascii::Char::CapitalA;
/// let uppercase_g = ascii::Char::CapitalG;
/// let a = ascii::Char::SmallA;
/// let g = ascii::Char::SmallG;
/// let zero = ascii::Char::Digit0;
/// let percent = ascii::Char::PercentSign;
/// let space = ascii::Char::Space;
/// let lf = ascii::Char::LineFeed;
/// let esc = ascii::Char::Escape;
///
/// assert!(!uppercase_a.is_whitespace());
/// assert!(!uppercase_g.is_whitespace());
/// assert!(!a.is_whitespace());
/// assert!(!g.is_whitespace());
/// assert!(!zero.is_whitespace());
/// assert!(!percent.is_whitespace());
/// assert!(space.is_whitespace());
/// assert!(lf.is_whitespace());
/// assert!(!esc.is_whitespace());
/// ```
#[must_use]
#[unstable(feature = "ascii_char", issue = "110998")]
#[inline]
pub const fn is_whitespace(self) -> bool {
self.to_u8().is_ascii_whitespace()
}
/// Checks if the value is a control character:
/// 0x00 NUL ..= 0x1F UNIT SEPARATOR, or 0x7F DELETE.
/// Note that most whitespace characters are control
/// characters, but SPACE is not.
///
/// # Examples
///
/// ```
/// #![feature(ascii_char, ascii_char_variants)]
/// use std::ascii;
///
/// let uppercase_a = ascii::Char::CapitalA;
/// let uppercase_g = ascii::Char::CapitalG;
/// let a = ascii::Char::SmallA;
/// let g = ascii::Char::SmallG;
/// let zero = ascii::Char::Digit0;
/// let percent = ascii::Char::PercentSign;
/// let space = ascii::Char::Space;
/// let lf = ascii::Char::LineFeed;
/// let esc = ascii::Char::Escape;
///
/// assert!(!uppercase_a.is_control());
/// assert!(!uppercase_g.is_control());
/// assert!(!a.is_control());
/// assert!(!g.is_control());
/// assert!(!zero.is_control());
/// assert!(!percent.is_control());
/// assert!(!space.is_control());
/// assert!(lf.is_control());
/// assert!(esc.is_control());
/// ```
#[must_use]
#[unstable(feature = "ascii_char", issue = "110998")]
#[inline]
pub const fn is_control(self) -> bool {
self.to_u8().is_ascii_control()
}
/// Returns an iterator that produces an escaped version of a
/// character.
///
/// The behavior is identical to
/// [`ascii::escape_default`](crate::ascii::escape_default).
///
/// # Examples
///
/// ```
/// #![feature(ascii_char, ascii_char_variants)]
/// use std::ascii;
///
/// let zero = ascii::Char::Digit0;
/// let tab = ascii::Char::CharacterTabulation;
/// let cr = ascii::Char::CarriageReturn;
/// let lf = ascii::Char::LineFeed;
/// let apostrophe = ascii::Char::Apostrophe;
/// let double_quote = ascii::Char::QuotationMark;
/// let backslash = ascii::Char::ReverseSolidus;
///
/// assert_eq!("0", zero.escape_ascii().to_string());
/// assert_eq!("\\t", tab.escape_ascii().to_string());
/// assert_eq!("\\r", cr.escape_ascii().to_string());
/// assert_eq!("\\n", lf.escape_ascii().to_string());
/// assert_eq!("\\'", apostrophe.escape_ascii().to_string());
/// assert_eq!("\\\"", double_quote.escape_ascii().to_string());
/// assert_eq!("\\\\", backslash.escape_ascii().to_string());
/// ```
#[must_use = "this returns the escaped character as an iterator, \
without modifying the original"]
#[unstable(feature = "ascii_char", issue = "110998")]
#[inline]
pub fn escape_ascii(self) -> super::EscapeDefault {
super::escape_default(self.to_u8())
}
}
macro_rules! into_int_impl {

View File

@@ -195,7 +195,7 @@ impl<T, const N: usize> Buffer<T, N> {
// SAFETY: the index is valid and this is element `a` in the
// diagram above and has not been dropped yet.
unsafe { ptr::drop_in_place(to_drop.cast::<T>()) };
unsafe { ptr::drop_in_place(to_drop.cast_init()) };
}
}

View File

@@ -1430,6 +1430,28 @@ impl<T: PointeeSized> *const T {
}
}
impl<T> *const T {
/// Casts from a type to its maybe-uninitialized version.
#[must_use]
#[inline(always)]
#[unstable(feature = "cast_maybe_uninit", issue = "145036")]
pub const fn cast_uninit(self) -> *const MaybeUninit<T> {
self as _
}
}
impl<T> *const MaybeUninit<T> {
/// Casts from a maybe-uninitialized type to its initialized version.
///
/// This is always safe, since UB can only occur if the pointer is read
/// before being initialized.
#[must_use]
#[inline(always)]
#[unstable(feature = "cast_maybe_uninit", issue = "145036")]
pub const fn cast_init(self) -> *const T {
self as _
}
}
impl<T> *const [T] {
/// Returns the length of a raw slice.
///

View File

@@ -885,10 +885,10 @@ pub const fn without_provenance<T>(addr: usize) -> *const T {
/// This is useful for initializing types which lazily allocate, like
/// `Vec::new` does.
///
/// Note that the pointer value may potentially represent a valid pointer to
/// a `T`, which means this must not be used as a "not yet initialized"
/// sentinel value. Types that lazily allocate must track initialization by
/// some other means.
/// Note that the address of the returned pointer may potentially
/// be that of a valid pointer, which means this must not be used
/// as a "not yet initialized" sentinel value.
/// Types that lazily allocate must track initialization by some other means.
#[inline(always)]
#[must_use]
#[stable(feature = "strict_provenance", since = "1.84.0")]
@@ -928,10 +928,10 @@ pub const fn without_provenance_mut<T>(addr: usize) -> *mut T {
/// This is useful for initializing types which lazily allocate, like
/// `Vec::new` does.
///
/// Note that the pointer value may potentially represent a valid pointer to
/// a `T`, which means this must not be used as a "not yet initialized"
/// sentinel value. Types that lazily allocate must track initialization by
/// some other means.
/// Note that the address of the returned pointer may potentially
/// be that of a valid pointer, which means this must not be used
/// as a "not yet initialized" sentinel value.
/// Types that lazily allocate must track initialization by some other means.
#[inline(always)]
#[must_use]
#[stable(feature = "strict_provenance", since = "1.84.0")]

View File

@@ -1687,6 +1687,31 @@ impl<T: PointeeSized> *mut T {
}
}
impl<T> *mut T {
/// Casts from a type to its maybe-uninitialized version.
///
/// This is always safe, since UB can only occur if the pointer is read
/// before being initialized.
#[must_use]
#[inline(always)]
#[unstable(feature = "cast_maybe_uninit", issue = "145036")]
pub const fn cast_uninit(self) -> *mut MaybeUninit<T> {
self as _
}
}
impl<T> *mut MaybeUninit<T> {
/// Casts from a maybe-uninitialized type to its initialized version.
///
/// This is always safe, since UB can only occur if the pointer is read
/// before being initialized.
#[must_use]
#[inline(always)]
#[unstable(feature = "cast_maybe_uninit", issue = "145036")]
pub const fn cast_init(self) -> *mut T {
self as _
}
}
impl<T> *mut [T] {
/// Returns the length of a raw slice.
///

View File

@@ -109,10 +109,10 @@ impl<T: Sized> NonNull<T> {
/// This is useful for initializing types which lazily allocate, like
/// `Vec::new` does.
///
/// Note that the pointer value may potentially represent a valid pointer to
/// a `T`, which means this must not be used as a "not yet initialized"
/// sentinel value. Types that lazily allocate must track initialization by
/// some other means.
/// Note that the address of the returned pointer may potentially
/// be that of a valid pointer, which means this must not be used
/// as a "not yet initialized" sentinel value.
/// Types that lazily allocate must track initialization by some other means.
///
/// # Examples
///
@@ -1357,6 +1357,28 @@ impl<T: PointeeSized> NonNull<T> {
}
}
impl<T> NonNull<T> {
/// Casts from a type to its maybe-uninitialized version.
#[must_use]
#[inline(always)]
#[unstable(feature = "cast_maybe_uninit", issue = "145036")]
pub const fn cast_uninit(self) -> NonNull<MaybeUninit<T>> {
self.cast()
}
}
impl<T> NonNull<MaybeUninit<T>> {
/// Casts from a maybe-uninitialized type to its initialized version.
///
/// This is always safe, since UB can only occur if the pointer is read
/// before being initialized.
#[must_use]
#[inline(always)]
#[unstable(feature = "cast_maybe_uninit", issue = "145036")]
pub const fn cast_init(self) -> NonNull<T> {
self.cast()
}
}
impl<T> NonNull<[T]> {
/// Creates a non-null raw slice from a thin pointer and a length.
///

View File

@@ -63,10 +63,10 @@ impl<T: Sized> Unique<T> {
/// This is useful for initializing types which lazily allocate, like
/// `Vec::new` does.
///
/// Note that the pointer value may potentially represent a valid pointer to
/// a `T`, which means this must not be used as a "not yet initialized"
/// sentinel value. Types that lazily allocate must track initialization by
/// some other means.
/// Note that the address of the returned pointer may potentially
/// be that of a valid pointer, which means this must not be used
/// as a "not yet initialized" sentinel value.
/// Types that lazily allocate must track initialization by some other means.
#[must_use]
#[inline]
pub const fn dangling() -> Self {

View File

@@ -281,9 +281,11 @@
#![feature(cfg_target_thread_local)]
#![feature(cfi_encoding)]
#![feature(char_max_len)]
#![feature(const_trait_impl)]
#![feature(core_float_math)]
#![feature(decl_macro)]
#![feature(deprecated_suggestion)]
#![feature(derive_const)]
#![feature(doc_cfg)]
#![feature(doc_cfg_hide)]
#![feature(doc_masked)]
@@ -327,8 +329,13 @@
// tidy-alphabetical-start
#![feature(bstr)]
#![feature(bstr_internals)]
#![feature(cast_maybe_uninit)]
#![feature(char_internals)]
#![feature(clone_to_uninit)]
#![feature(const_cmp)]
#![feature(const_ops)]
#![feature(const_option_ops)]
#![feature(const_try)]
#![feature(core_intrinsics)]
#![feature(core_io_borrowed_buf)]
#![feature(drop_guard)]

View File

@@ -60,6 +60,7 @@ impl<'a> PanicHookInfo<'a> {
/// Returns the payload associated with the panic.
///
/// This will commonly, but not always, be a `&'static str` or [`String`].
/// If you only care about such payloads, use [`payload_as_str`] instead.
///
/// A invocation of the `panic!()` macro in Rust 2021 or later will always result in a
/// panic payload of type `&'static str` or `String`.
@@ -69,6 +70,7 @@ impl<'a> PanicHookInfo<'a> {
/// can result in a panic payload other than a `&'static str` or `String`.
///
/// [`String`]: ../../std/string/struct.String.html
/// [`payload_as_str`]: PanicHookInfo::payload_as_str
///
/// # Examples
///

View File

@@ -2678,7 +2678,6 @@ impl Path {
/// # Examples
///
/// ```
/// # #![feature(path_file_prefix)]
/// use std::path::Path;
///
/// assert_eq!("foo", Path::new("foo.rs").file_prefix().unwrap());
@@ -2693,7 +2692,7 @@ impl Path {
///
/// [`Path::file_stem`]: Path::file_stem
///
#[unstable(feature = "path_file_prefix", issue = "86319")]
#[stable(feature = "path_file_prefix", since = "CURRENT_RUSTC_VERSION")]
#[must_use]
pub fn file_prefix(&self) -> Option<&OsStr> {
self.file_name().map(split_file_at_dot).and_then(|(before, _after)| Some(before))

View File

@@ -1606,7 +1606,7 @@ pub fn junction_point(original: &Path, link: &Path) -> io::Result<()> {
};
unsafe {
let ptr = header.PathBuffer.as_mut_ptr();
ptr.copy_from(abs_path.as_ptr().cast::<MaybeUninit<u16>>(), abs_path.len());
ptr.copy_from(abs_path.as_ptr().cast_uninit(), abs_path.len());
let mut ret = 0;
cvt(c::DeviceIoControl(

View File

@@ -25,8 +25,15 @@ impl Timespec {
Timespec { t: timespec { tv_sec, tv_nsec } }
}
fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
if self >= other {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
const fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
// FIXME: const PartialOrd
let mut cmp = self.t.tv_sec - other.t.tv_sec;
if cmp == 0 {
cmp = self.t.tv_nsec as i64 - other.t.tv_nsec as i64;
}
if cmp >= 0 {
Ok(if self.t.tv_nsec >= other.t.tv_nsec {
Duration::new(
(self.t.tv_sec - other.t.tv_sec) as u64,
@@ -46,20 +53,22 @@ impl Timespec {
}
}
fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
const fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
let mut secs = self.t.tv_sec.checked_add_unsigned(other.as_secs())?;
// Nano calculations can't overflow because nanos are <1B which fit
// in a u32.
let mut nsec = other.subsec_nanos() + u32::try_from(self.t.tv_nsec).unwrap();
if nsec >= NSEC_PER_SEC.try_into().unwrap() {
nsec -= u32::try_from(NSEC_PER_SEC).unwrap();
let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
if nsec >= NSEC_PER_SEC as u32 {
nsec -= NSEC_PER_SEC as u32;
secs = secs.checked_add(1)?;
}
Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } })
}
fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
const fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
let mut secs = self.t.tv_sec.checked_sub_unsigned(other.as_secs())?;
// Similar to above, nanos can't overflow.
@@ -213,15 +222,18 @@ impl SystemTime {
SystemTime(time)
}
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
self.0.sub_timespec(&other.0)
}
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_add_duration(other)?))
}
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_sub_duration(other)?))
}
}

View File

@@ -32,15 +32,22 @@ impl SystemTime {
SystemTime(usercalls::insecure_time())
}
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
// FIXME: ok_or_else with const closures
match self.0.checked_sub(other.0) {
Some(duration) => Ok(duration),
None => Err(other.0 - self.0),
}
}
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_add(*other)?))
}
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_sub(*other)?))
}
}

View File

@@ -39,7 +39,8 @@ impl SystemTime {
Self(t)
}
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
if self.0 >= other.0 {
Ok(Duration::from_secs((self.0 as u64).wrapping_sub(other.0 as u64)))
} else {
@@ -47,11 +48,13 @@ impl SystemTime {
}
}
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_add_unsigned(other.as_secs())?))
}
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_sub_unsigned(other.as_secs())?))
}
}

View File

@@ -80,19 +80,32 @@ impl SystemTime {
.unwrap_or_else(|| panic!("time not implemented on this platform"))
}
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
// FIXME: ok_or_else with const closures
match self.0.checked_sub(other.0) {
Some(duration) => Ok(duration),
None => Err(other.0 - self.0),
}
}
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
let temp = Self(self.0.checked_add(*other)?);
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
let temp = self.0.checked_add(*other)?;
// Check if can be represented in UEFI
if temp <= MAX_UEFI_TIME { Some(temp) } else { None }
// FIXME: const PartialOrd
let mut cmp = temp.as_secs() - MAX_UEFI_TIME.0.as_secs();
if cmp == 0 {
cmp = temp.subsec_nanos() as u64 - MAX_UEFI_TIME.0.subsec_nanos() as u64;
}
if cmp <= 0 { Some(SystemTime(temp)) } else { None }
}
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
self.0.checked_sub(*other).map(Self)
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_sub(*other)?))
}
}

View File

@@ -38,15 +38,18 @@ impl SystemTime {
SystemTime { t: Timespec::now(libc::CLOCK_REALTIME) }
}
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
self.t.sub_timespec(&other.t)
}
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime { t: self.t.checked_add_duration(other)? })
}
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime { t: self.t.checked_sub_duration(other)? })
}
}
@@ -133,8 +136,15 @@ impl Timespec {
Timespec::new(t.tv_sec as i64, t.tv_nsec as i64).unwrap()
}
pub fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
if self >= other {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
// FIXME: const PartialOrd
let mut cmp = self.tv_sec - other.tv_sec;
if cmp == 0 {
cmp = self.tv_nsec.as_inner() as i64 - other.tv_nsec.as_inner() as i64;
}
if cmp >= 0 {
// NOTE(eddyb) two aspects of this `if`-`else` are required for LLVM
// to optimize it into a branchless form (see also #75545):
//
@@ -169,7 +179,8 @@ impl Timespec {
}
}
pub fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
let mut secs = self.tv_sec.checked_add_unsigned(other.as_secs())?;
// Nano calculations can't overflow because nanos are <1B which fit
@@ -179,10 +190,11 @@ impl Timespec {
nsec -= NSEC_PER_SEC as u32;
secs = secs.checked_add(1)?;
}
Some(unsafe { Timespec::new_unchecked(secs, nsec.into()) })
Some(unsafe { Timespec::new_unchecked(secs, nsec as i64) })
}
pub fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
let mut secs = self.tv_sec.checked_sub_unsigned(other.as_secs())?;
// Similar to above, nanos can't overflow.
@@ -191,7 +203,7 @@ impl Timespec {
nsec += NSEC_PER_SEC as i32;
secs = secs.checked_sub(1)?;
}
Some(unsafe { Timespec::new_unchecked(secs, nsec.into()) })
Some(unsafe { Timespec::new_unchecked(secs, nsec as i64) })
}
#[allow(dead_code)]

View File

@@ -31,15 +31,22 @@ impl SystemTime {
panic!("time not implemented on this platform")
}
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
// FIXME: ok_or_else with const closures
match self.0.checked_sub(other.0) {
Some(duration) => Ok(duration),
None => Err(other.0 - self.0),
}
}
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_add(*other)?))
}
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_sub(*other)?))
}
}

View File

@@ -43,23 +43,34 @@ impl SystemTime {
SystemTime(current_time(wasi::CLOCKID_REALTIME))
}
pub fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime {
SystemTime(Duration::from_nanos(ts))
}
pub fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> {
self.0.as_nanos().try_into().ok()
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> {
// FIXME: const TryInto
let ns = self.0.as_nanos();
if ns <= u64::MAX as u128 { Some(ns as u64) } else { None }
}
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
// FIXME: ok_or_else with const closures
match self.0.checked_sub(other.0) {
Some(duration) => Ok(duration),
None => Err(other.0 - self.0),
}
}
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_add(*other)?))
}
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_sub(*other)?))
}
}

View File

@@ -72,7 +72,8 @@ impl SystemTime {
}
}
fn from_intervals(intervals: i64) -> SystemTime {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
const fn from_intervals(intervals: i64) -> SystemTime {
SystemTime {
t: c::FILETIME {
dwLowDateTime: intervals as u32,
@@ -81,11 +82,13 @@ impl SystemTime {
}
}
fn intervals(&self) -> i64 {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
const fn intervals(&self) -> i64 {
(self.t.dwLowDateTime as i64) | ((self.t.dwHighDateTime as i64) << 32)
}
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
let me = self.intervals();
let other = other.intervals();
if me >= other {
@@ -95,12 +98,14 @@ impl SystemTime {
}
}
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
let intervals = self.intervals().checked_add(checked_dur2intervals(other)?)?;
Some(SystemTime::from_intervals(intervals))
}
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
let intervals = self.intervals().checked_sub(checked_dur2intervals(other)?)?;
Some(SystemTime::from_intervals(intervals))
}
@@ -150,15 +155,18 @@ impl Hash for SystemTime {
}
}
fn checked_dur2intervals(dur: &Duration) -> Option<i64> {
dur.as_secs()
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
const fn checked_dur2intervals(dur: &Duration) -> Option<i64> {
// FIXME: const TryInto
let secs = dur
.as_secs()
.checked_mul(INTERVALS_PER_SEC)?
.checked_add(dur.subsec_nanos() as u64 / 100)?
.try_into()
.ok()
.checked_add(dur.subsec_nanos() as u64 / 100)?;
if secs <= i64::MAX as u64 { Some(secs.cast_signed()) } else { None }
}
fn intervals2dur(intervals: u64) -> Duration {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
const fn intervals2dur(intervals: u64) -> Duration {
Duration::new(intervals / INTERVALS_PER_SEC, ((intervals % INTERVALS_PER_SEC) * 100) as u32)
}

View File

@@ -43,15 +43,22 @@ impl SystemTime {
SystemTime { 0: Duration::from_millis((upper as u64) << 32 | lower as u64) }
}
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
// FIXME: ok_or_else with const closures
match self.0.checked_sub(other.0) {
Some(duration) => Ok(duration),
None => Err(other.0 - self.0),
}
}
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_add(*other)?))
}
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_sub(*other)?))
}
}

View File

@@ -551,8 +551,13 @@ impl SystemTime {
/// println!("{difference:?}");
/// ```
#[stable(feature = "time2", since = "1.8.0")]
pub fn duration_since(&self, earlier: SystemTime) -> Result<Duration, SystemTimeError> {
self.0.sub_time(&earlier.0).map_err(SystemTimeError)
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn duration_since(&self, earlier: SystemTime) -> Result<Duration, SystemTimeError> {
// FIXME: map_err in const
match self.0.sub_time(&earlier.0) {
Ok(time) => Ok(time),
Err(err) => Err(SystemTimeError(err)),
}
}
/// Returns the difference from this system time to the
@@ -589,7 +594,8 @@ impl SystemTime {
/// `SystemTime` (which means it's inside the bounds of the underlying data structure), `None`
/// otherwise.
#[stable(feature = "time_checked_add", since = "1.34.0")]
pub fn checked_add(&self, duration: Duration) -> Option<SystemTime> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_add(&self, duration: Duration) -> Option<SystemTime> {
self.0.checked_add_duration(&duration).map(SystemTime)
}
@@ -597,13 +603,15 @@ impl SystemTime {
/// `SystemTime` (which means it's inside the bounds of the underlying data structure), `None`
/// otherwise.
#[stable(feature = "time_checked_add", since = "1.34.0")]
pub fn checked_sub(&self, duration: Duration) -> Option<SystemTime> {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_sub(&self, duration: Duration) -> Option<SystemTime> {
self.0.checked_sub_duration(&duration).map(SystemTime)
}
}
#[stable(feature = "time2", since = "1.8.0")]
impl Add<Duration> for SystemTime {
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl const Add<Duration> for SystemTime {
type Output = SystemTime;
/// # Panics
@@ -616,14 +624,16 @@ impl Add<Duration> for SystemTime {
}
#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
impl AddAssign<Duration> for SystemTime {
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl const AddAssign<Duration> for SystemTime {
fn add_assign(&mut self, other: Duration) {
*self = *self + other;
}
}
#[stable(feature = "time2", since = "1.8.0")]
impl Sub<Duration> for SystemTime {
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl const Sub<Duration> for SystemTime {
type Output = SystemTime;
fn sub(self, dur: Duration) -> SystemTime {
@@ -632,7 +642,8 @@ impl Sub<Duration> for SystemTime {
}
#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
impl SubAssign<Duration> for SystemTime {
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl const SubAssign<Duration> for SystemTime {
fn sub_assign(&mut self, other: Duration) {
*self = *self - other;
}
@@ -699,7 +710,8 @@ impl SystemTimeError {
/// ```
#[must_use]
#[stable(feature = "time2", since = "1.8.0")]
pub fn duration(&self) -> Duration {
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn duration(&self) -> Duration {
self.0
}
}

View File

@@ -1,10 +1,4 @@
#![feature(
clone_to_uninit,
path_add_extension,
path_file_prefix,
maybe_uninit_slice,
normalize_lexically
)]
#![feature(clone_to_uninit, path_add_extension, maybe_uninit_slice, normalize_lexically)]
use std::clone::CloneToUninit;
use std::ffi::OsStr;

View File

@@ -162,18 +162,17 @@ tests whose names contain the filter are run. Multiple filter strings may
be passed, which will run all tests matching any of the filters.
By default, all tests are run in parallel. This can be altered with the
--test-threads flag or the RUST_TEST_THREADS environment variable when running
tests (set it to 1).
--test-threads flag when running tests (set it to 1).
By default, the tests are run in alphabetical order. Use --shuffle or set
RUST_TEST_SHUFFLE to run the tests in random order. Pass the generated
"shuffle seed" to --shuffle-seed (or set RUST_TEST_SHUFFLE_SEED) to run the
tests in the same order again. Note that --shuffle and --shuffle-seed do not
affect whether the tests are run in parallel.
By default, the tests are run in alphabetical order. Use --shuffle to run
the tests in random order. Pass the generated "shuffle seed" to
--shuffle-seed to run the tests in the same order again. Note that
--shuffle and --shuffle-seed do not affect whether the tests are run in
parallel.
All tests have their standard output and standard error captured by default.
This can be overridden with the --no-capture flag or setting RUST_TEST_NOCAPTURE
environment variable to a value other than "0". Logging is not captured by default.
This can be overridden with the --no-capture flag to a value other than "0".
Logging is not captured by default.
Test Attributes:

View File

@@ -1410,6 +1410,7 @@ impl Step for Miri {
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct CraneliftCodegenBackend {
pub build_compiler: Compiler,
pub target: TargetSelection,
}
impl Step for CraneliftCodegenBackend {
@@ -1437,6 +1438,7 @@ impl Step for CraneliftCodegenBackend {
run.builder.config.host_target,
run.target,
),
target: run.target,
});
}
@@ -1448,7 +1450,7 @@ impl Step for CraneliftCodegenBackend {
return None;
}
let target = self.build_compiler.host;
let target = self.target;
let compilers =
RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, target);
if !target_supports_cranelift_backend(target) {
@@ -1608,6 +1610,7 @@ impl Step for Extended {
add_component!("analysis" => Analysis { compiler, target });
add_component!("rustc-codegen-cranelift" => CraneliftCodegenBackend {
build_compiler: compiler,
target
});
add_component!("llvm-bitcode-linker" => LlvmBitcodeLinker {
build_compiler: compiler,

View File

@@ -282,6 +282,7 @@ install!((self, builder, _config),
RustcCodegenCranelift, alias = "rustc-codegen-cranelift", Self::should_build(_config), only_hosts: true, {
if let Some(tarball) = builder.ensure(dist::CraneliftCodegenBackend {
build_compiler: self.compiler,
target: self.target
}) {
install_sh(builder, "rustc-codegen-cranelift", self.compiler.stage, Some(self.target), &tarball);
} else {

View File

@@ -164,7 +164,7 @@ Sets the number of threads to use for running tests in parallel. By default,
uses the amount of concurrency available on the hardware as indicated by
[`available_parallelism`].
This can also be specified with the `RUST_TEST_THREADS` environment variable.
Deprecated: this can also be specified with the `RUST_TEST_THREADS` environment variable.
#### `--force-run-in-process`
@@ -186,7 +186,7 @@ docs](../../unstable-book/compiler-flags/report-time.html) for more information.
Runs the tests in random order, as opposed to the default alphabetical order.
This may also be specified by setting the `RUST_TEST_SHUFFLE` environment
Deprecated: this may also be specified by setting the `RUST_TEST_SHUFFLE` environment
variable to anything but `0`.
The random number generator seed that is output can be passed to
@@ -209,7 +209,7 @@ the tests in the same order both times.
_SEED_ is any 64-bit unsigned integer, for example, one produced by
[`--shuffle`](#--shuffle).
This can also be specified with the `RUST_TEST_SHUFFLE_SEED` environment
Deprecated: this can also be specified with the `RUST_TEST_SHUFFLE_SEED` environment
variable.
⚠️ 🚧 This option is [unstable](#unstable-options), and requires the `-Z
@@ -231,7 +231,7 @@ Does not capture the stdout and stderr of the test, and allows tests to print
to the console. Usually the output is captured, and only displayed if the test
fails.
This may also be specified by setting the `RUST_TEST_NOCAPTURE` environment
Deprecated: this may also be specified by setting the `RUST_TEST_NOCAPTURE` environment
variable to anything but `0`.
`--nocapture` is a deprecated alias for `--no-capture`.

View File

@@ -1,6 +1,6 @@
#![warn(rust_2018_idioms, unused_lifetimes)]
#![allow(clippy::assertions_on_constants)]
#![feature(path_file_prefix)]
#![cfg_attr(bootstrap, feature(path_file_prefix))]
use std::cmp::Ordering;
use std::ffi::OsStr;

View File

@@ -71,6 +71,7 @@
//~^^ WARN this was previously accepted by the compiler
#![must_use]
//~^ WARN `#[must_use]` has no effect
//~| HELP remove the attribute
// see issue-43106-gating-of-stable.rs
// see issue-43106-gating-of-unstable.rs
// see issue-43106-gating-of-deprecated.rs
@@ -599,16 +600,20 @@ mod deprecated {
}
#[must_use] //~ WARN `#[must_use]` has no effect
//~^ HELP remove the attribute
mod must_use {
mod inner { #![must_use] } //~ WARN `#[must_use]` has no effect
//~^ HELP remove the attribute
#[must_use] fn f() { }
#[must_use] struct S;
#[must_use] type T = S; //~ WARN `#[must_use]` has no effect
//~^ HELP remove the attribute
#[must_use] impl S { } //~ WARN `#[must_use]` has no effect
//~^ HELP remove the attribute
}
#[windows_subsystem = "windows"]

View File

@@ -0,0 +1,139 @@
//@ run-rustfix
#![allow(dead_code, path_statements)]
#![deny(unused_attributes, unused_must_use)]
#![feature(asm_experimental_arch, stmt_expr_attributes, trait_alias)]
//~ ERROR `#[must_use]` has no effect
extern crate std as std2;
//~ ERROR `#[must_use]` has no effect
mod test_mod {}
//~ ERROR `#[must_use]` has no effect
use std::arch::global_asm;
//~ ERROR `#[must_use]` has no effect
const CONST: usize = 4;
//~ ERROR `#[must_use]` has no effect
#[no_mangle]
static STATIC: usize = 4;
#[must_use]
struct X;
#[must_use]
enum Y {
Z,
}
#[must_use]
union U {
unit: (),
}
//~ ERROR `#[must_use]` has no effect
impl U {
#[must_use]
fn method() -> i32 {
4
}
}
#[must_use]
#[no_mangle]
fn foo() -> i64 {
4
}
//~ ERROR `#[must_use]` has no effect
extern "Rust" {
#[link_name = "STATIC"]
//~ ERROR `#[must_use]` has no effect
static FOREIGN_STATIC: usize;
#[link_name = "foo"]
#[must_use]
fn foreign_foo() -> i64;
}
//~ ERROR unused attribute
global_asm!("");
//~ ERROR `#[must_use]` has no effect
type UseMe = ();
fn qux< T>(_: T) {} //~ ERROR `#[must_use]` has no effect
#[must_use]
trait Use {
//~ ERROR `#[must_use]` has no effect
const ASSOC_CONST: usize = 4;
//~ ERROR `#[must_use]` has no effect
type AssocTy;
#[must_use]
fn get_four(&self) -> usize {
4
}
}
//~ ERROR `#[must_use]` has no effect
impl Use for () {
type AssocTy = ();
//~ ERROR `#[must_use]` has no effect
fn get_four(&self) -> usize {
4
}
}
//~ ERROR `#[must_use]` has no effect
trait Alias = Use;
//~ ERROR `#[must_use]` has no effect
macro_rules! cool_macro {
() => {
4
};
}
fn main() {
//~ ERROR `#[must_use]` has no effect
let x = || {};
x();
let x = //~ ERROR `#[must_use]` has no effect
|| {};
x();
let _ = X; //~ ERROR that must be used
let _ = Y::Z; //~ ERROR that must be used
let _ = U { unit: () }; //~ ERROR that must be used
let _ = U::method(); //~ ERROR that must be used
let _ = foo(); //~ ERROR that must be used
unsafe {
let _ = foreign_foo(); //~ ERROR that must be used
};
CONST;
STATIC;
unsafe { FOREIGN_STATIC };
cool_macro!();
qux(4);
let _ = ().get_four(); //~ ERROR that must be used
match Some(4) {
//~ ERROR `#[must_use]` has no effect
Some(res) => res,
None => 0,
};
struct PatternField {
foo: i32,
}
let s = PatternField { foo: 123 }; //~ ERROR `#[must_use]` has no effect
let PatternField { foo } = s; //~ ERROR `#[must_use]` has no effect
let _ = foo;
}

View File

@@ -1,3 +1,5 @@
//@ run-rustfix
#![allow(dead_code, path_statements)]
#![deny(unused_attributes, unused_must_use)]
#![feature(asm_experimental_arch, stmt_expr_attributes, trait_alias)]
@@ -133,4 +135,5 @@ fn main() {
}
let s = PatternField { #[must_use] foo: 123 }; //~ ERROR `#[must_use]` has no effect
let PatternField { #[must_use] foo } = s; //~ ERROR `#[must_use]` has no effect
let _ = foo;
}

View File

@@ -1,154 +1,154 @@
error: unused attribute `must_use`
--> $DIR/unused_attributes-must_use.rs:58:1
--> $DIR/unused_attributes-must_use.rs:60:1
|
LL | #[must_use]
| ^^^^^^^^^^^
|
note: the built-in attribute `must_use` will be ignored, since it's applied to the macro invocation `global_asm`
--> $DIR/unused_attributes-must_use.rs:59:1
--> $DIR/unused_attributes-must_use.rs:61:1
|
LL | global_asm!("");
| ^^^^^^^^^^
note: the lint level is defined here
--> $DIR/unused_attributes-must_use.rs:2:9
--> $DIR/unused_attributes-must_use.rs:4:9
|
LL | #![deny(unused_attributes, unused_must_use)]
| ^^^^^^^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to an extern crate
--> $DIR/unused_attributes-must_use.rs:5:1
--> $DIR/unused_attributes-must_use.rs:7:1
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a module
--> $DIR/unused_attributes-must_use.rs:8:1
--> $DIR/unused_attributes-must_use.rs:10:1
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a use
--> $DIR/unused_attributes-must_use.rs:11:1
--> $DIR/unused_attributes-must_use.rs:13:1
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a constant item
--> $DIR/unused_attributes-must_use.rs:14:1
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a static item
--> $DIR/unused_attributes-must_use.rs:16:1
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a static item
--> $DIR/unused_attributes-must_use.rs:18:1
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to an inherent implementation block
--> $DIR/unused_attributes-must_use.rs:33:1
--> $DIR/unused_attributes-must_use.rs:35:1
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a foreign module
--> $DIR/unused_attributes-must_use.rs:47:1
--> $DIR/unused_attributes-must_use.rs:49:1
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a type alias
--> $DIR/unused_attributes-must_use.rs:61:1
--> $DIR/unused_attributes-must_use.rs:63:1
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a type parameter
--> $DIR/unused_attributes-must_use.rs:64:8
--> $DIR/unused_attributes-must_use.rs:66:8
|
LL | fn qux<#[must_use] T>(_: T) {}
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to an trait implementation block
--> $DIR/unused_attributes-must_use.rs:79:1
--> $DIR/unused_attributes-must_use.rs:81:1
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a trait alias
--> $DIR/unused_attributes-must_use.rs:89:1
--> $DIR/unused_attributes-must_use.rs:91:1
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a macro def
--> $DIR/unused_attributes-must_use.rs:92:1
--> $DIR/unused_attributes-must_use.rs:94:1
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a statement
--> $DIR/unused_attributes-must_use.rs:100:5
--> $DIR/unused_attributes-must_use.rs:102:5
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a closure
--> $DIR/unused_attributes-must_use.rs:104:13
--> $DIR/unused_attributes-must_use.rs:106:13
|
LL | let x = #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to an match arm
--> $DIR/unused_attributes-must_use.rs:126:9
--> $DIR/unused_attributes-must_use.rs:128:9
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a struct field
--> $DIR/unused_attributes-must_use.rs:134:28
--> $DIR/unused_attributes-must_use.rs:136:28
|
LL | let s = PatternField { #[must_use] foo: 123 };
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a pattern field
--> $DIR/unused_attributes-must_use.rs:135:24
--> $DIR/unused_attributes-must_use.rs:137:24
|
LL | let PatternField { #[must_use] foo } = s;
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to an associated const
--> $DIR/unused_attributes-must_use.rs:68:5
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to an associated type
--> $DIR/unused_attributes-must_use.rs:70:5
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to an associated type
--> $DIR/unused_attributes-must_use.rs:72:5
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a provided trait method
--> $DIR/unused_attributes-must_use.rs:83:5
--> $DIR/unused_attributes-must_use.rs:85:5
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a foreign static item
--> $DIR/unused_attributes-must_use.rs:50:5
--> $DIR/unused_attributes-must_use.rs:52:5
|
LL | #[must_use]
| ^^^^^^^^^^^
error: unused `X` that must be used
--> $DIR/unused_attributes-must_use.rs:108:5
--> $DIR/unused_attributes-must_use.rs:110:5
|
LL | X;
| ^
|
note: the lint level is defined here
--> $DIR/unused_attributes-must_use.rs:2:28
--> $DIR/unused_attributes-must_use.rs:4:28
|
LL | #![deny(unused_attributes, unused_must_use)]
| ^^^^^^^^^^^^^^^
@@ -158,7 +158,7 @@ LL | let _ = X;
| +++++++
error: unused `Y` that must be used
--> $DIR/unused_attributes-must_use.rs:109:5
--> $DIR/unused_attributes-must_use.rs:111:5
|
LL | Y::Z;
| ^^^^
@@ -169,7 +169,7 @@ LL | let _ = Y::Z;
| +++++++
error: unused `U` that must be used
--> $DIR/unused_attributes-must_use.rs:110:5
--> $DIR/unused_attributes-must_use.rs:112:5
|
LL | U { unit: () };
| ^^^^^^^^^^^^^^
@@ -180,7 +180,7 @@ LL | let _ = U { unit: () };
| +++++++
error: unused return value of `U::method` that must be used
--> $DIR/unused_attributes-must_use.rs:111:5
--> $DIR/unused_attributes-must_use.rs:113:5
|
LL | U::method();
| ^^^^^^^^^^^
@@ -191,7 +191,7 @@ LL | let _ = U::method();
| +++++++
error: unused return value of `foo` that must be used
--> $DIR/unused_attributes-must_use.rs:112:5
--> $DIR/unused_attributes-must_use.rs:114:5
|
LL | foo();
| ^^^^^
@@ -202,7 +202,7 @@ LL | let _ = foo();
| +++++++
error: unused return value of `foreign_foo` that must be used
--> $DIR/unused_attributes-must_use.rs:115:9
--> $DIR/unused_attributes-must_use.rs:117:9
|
LL | foreign_foo();
| ^^^^^^^^^^^^^
@@ -213,7 +213,7 @@ LL | let _ = foreign_foo();
| +++++++
error: unused return value of `Use::get_four` that must be used
--> $DIR/unused_attributes-must_use.rs:123:5
--> $DIR/unused_attributes-must_use.rs:125:5
|
LL | ().get_four();
| ^^^^^^^^^^^^^