Auto merge of #143919 - Kobzol:rollup-acyaygs, r=Kobzol

Rollup of 10 pull requests

Successful merges:

 - rust-lang/rust#143217 (Port #[link_ordinal] to the new attribute parsing infrastructure)
 - rust-lang/rust#143681 (bootstrap/miri: avoid rebuilds for test builds)
 - rust-lang/rust#143724 (Tidy cleanup)
 - rust-lang/rust#143733 (Change bootstrap's `tool.TOOL_NAME.features` to work on any subcommand)
 - rust-lang/rust#143850 (Compiletest: Simplify {Html,Json}DocCk directive handling)
 - rust-lang/rust#143875 (update issue number for `const_trait_impl`)
 - rust-lang/rust#143881 (Use zero for initialized Once state)
 - rust-lang/rust#143887 (Run bootstrap tests sooner in the `x test` pipeline)
 - rust-lang/rust#143917 (Change "allocated object" to "allocation".)
 - rust-lang/rust#143918 (Tier check cleanup)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-07-14 12:17:15 +00:00
commit cccf075eba
98 changed files with 665 additions and 725 deletions

View file

@ -392,7 +392,8 @@
# For example, to build Miri with tracing support, use `tool.miri.features = ["tracing"]`
#
# The default value for the `features` array is `[]`. However, please note that other flags in
# `bootstrap.toml` might influence the features enabled for some tools.
# `bootstrap.toml` might influence the features enabled for some tools. Also, enabling features
# in tools which are not part of the internal "extra-features" preset might not always work.
#build.tool.TOOL_NAME.features = [FEATURE1, FEATURE2]
# Verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose, 3 == print environment variables on each rustc invocation

View file

@ -297,6 +297,9 @@ pub enum AttributeKind {
/// Represents `#[link_name]`.
LinkName { name: Symbol, span: Span },
/// Represents `#[link_ordinal]`.
LinkOrdinal { ordinal: u16, span: Span },
/// Represents [`#[link_section]`](https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute)
LinkSection { name: Symbol, span: Span },

View file

@ -41,6 +41,7 @@ impl AttributeKind {
Ignore { .. } => No,
Inline(..) => No,
LinkName { .. } => Yes,
LinkOrdinal { .. } => No,
LinkSection { .. } => No,
LoopMatch(..) => No,
MacroTransparency(..) => Yes,

View file

@ -78,6 +78,9 @@ attr_parsing_invalid_repr_hint_no_value =
attr_parsing_invalid_since =
'since' must be a Rust version number, such as "1.31.0"
attr_parsing_link_ordinal_out_of_range = ordinal value in `link_ordinal` is too large: `{$ordinal}`
.note = the value may not exceed `u16::MAX`
attr_parsing_missing_feature =
missing 'feature'

View file

@ -1,14 +1,14 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_attr_data_structures::AttributeKind::{LinkName, LinkSection};
use rustc_attr_data_structures::AttributeKind::{LinkName, LinkOrdinal, LinkSection};
use rustc_feature::{AttributeTemplate, template};
use rustc_span::{Span, Symbol, sym};
use crate::attributes::{
AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser,
};
use crate::context::{AcceptContext, Stage};
use crate::context::{AcceptContext, Stage, parse_single_integer};
use crate::parser::ArgParser;
use crate::session_diagnostics::NullOnLinkSection;
use crate::session_diagnostics::{LinkOrdinalOutOfRange, NullOnLinkSection};
pub(crate) struct LinkNameParser;
@ -87,3 +87,36 @@ impl<S: Stage> NoArgsAttributeParser<S> for StdInternalSymbolParser {
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const CREATE: fn(Span) -> AttributeKind = AttributeKind::StdInternalSymbol;
}
pub(crate) struct LinkOrdinalParser;
impl<S: Stage> SingleAttributeParser<S> for LinkOrdinalParser {
const PATH: &[Symbol] = &[sym::link_ordinal];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const TEMPLATE: AttributeTemplate = template!(List: "ordinal");
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
let ordinal = parse_single_integer(cx, args)?;
// According to the table at
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header, the
// ordinal must fit into 16 bits. Similarly, the Ordinal field in COFFShortExport (defined
// in llvm/include/llvm/Object/COFFImportFile.h), which we use to communicate import
// information to LLVM for `#[link(kind = "raw-dylib"_])`, is also defined to be uint16_t.
//
// FIXME: should we allow an ordinal of 0? The MSVC toolchain has inconsistent support for
// this: both LINK.EXE and LIB.EXE signal errors and abort when given a .DEF file that
// specifies a zero ordinal. However, llvm-dlltool is perfectly happy to generate an import
// library for such a .DEF file, and MSVC's LINK.EXE is also perfectly happy to consume an
// import library produced by LLVM with an ordinal of 0, and it generates an .EXE. (I
// don't know yet if the resulting EXE runs, as I haven't yet built the necessary DLL --
// see earlier comment about LINK.EXE failing.)
let Ok(ordinal) = ordinal.try_into() else {
cx.emit_err(LinkOrdinalOutOfRange { span: cx.attr_span, ordinal });
return None;
};
Some(LinkOrdinal { ordinal, span: cx.attr_span })
}
}

View file

@ -1,10 +1,9 @@
use rustc_ast::LitKind;
use rustc_attr_data_structures::AttributeKind;
use rustc_feature::{AttributeTemplate, template};
use rustc_span::{Symbol, sym};
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
use crate::context::{AcceptContext, Stage};
use crate::context::{AcceptContext, Stage, parse_single_integer};
use crate::parser::ArgParser;
pub(crate) struct RustcLayoutScalarValidRangeStart;
@ -16,8 +15,8 @@ impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeStart {
const TEMPLATE: AttributeTemplate = template!(List: "start");
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
parse_rustc_layout_scalar_valid_range(cx, args)
.map(|n| AttributeKind::RustcLayoutScalarValidRangeStart(n, cx.attr_span))
parse_single_integer(cx, args)
.map(|n| AttributeKind::RustcLayoutScalarValidRangeStart(Box::new(n), cx.attr_span))
}
}
@ -30,34 +29,11 @@ impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeEnd {
const TEMPLATE: AttributeTemplate = template!(List: "end");
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
parse_rustc_layout_scalar_valid_range(cx, args)
.map(|n| AttributeKind::RustcLayoutScalarValidRangeEnd(n, cx.attr_span))
parse_single_integer(cx, args)
.map(|n| AttributeKind::RustcLayoutScalarValidRangeEnd(Box::new(n), cx.attr_span))
}
}
fn parse_rustc_layout_scalar_valid_range<S: Stage>(
cx: &mut AcceptContext<'_, '_, S>,
args: &ArgParser<'_>,
) -> Option<Box<u128>> {
let Some(list) = args.list() else {
cx.expected_list(cx.attr_span);
return None;
};
let Some(single) = list.single() else {
cx.expected_single_argument(list.span);
return None;
};
let Some(lit) = single.lit() else {
cx.expected_integer_literal(single.span());
return None;
};
let LitKind::Int(num, _ty) = lit.kind else {
cx.expected_integer_literal(single.span());
return None;
};
Some(Box::new(num.0))
}
pub(crate) struct RustcObjectLifetimeDefaultParser;
impl<S: Stage> SingleAttributeParser<S> for RustcObjectLifetimeDefaultParser {

View file

@ -5,7 +5,7 @@ use std::ops::{Deref, DerefMut};
use std::sync::LazyLock;
use private::Sealed;
use rustc_ast::{self as ast, MetaItemLit, NodeId};
use rustc_ast::{self as ast, LitKind, MetaItemLit, NodeId};
use rustc_attr_data_structures::AttributeKind;
use rustc_attr_data_structures::lints::{AttributeLint, AttributeLintKind};
use rustc_errors::{DiagCtxtHandle, Diagnostic};
@ -24,8 +24,8 @@ use crate::attributes::deprecation::DeprecationParser;
use crate::attributes::dummy::DummyParser;
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
use crate::attributes::link_attrs::{
ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkSectionParser,
StdInternalSymbolParser,
ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkOrdinalParser,
LinkSectionParser, StdInternalSymbolParser,
};
use crate::attributes::lint_helpers::{
AsPtrParser, AutomaticallyDerivedParser, PassByValueParser, PubTransparentParser,
@ -143,6 +143,7 @@ attribute_parsers!(
Single<IgnoreParser>,
Single<InlineParser>,
Single<LinkNameParser>,
Single<LinkOrdinalParser>,
Single<LinkSectionParser>,
Single<MustUseParser>,
Single<OptimizeParser>,
@ -775,3 +776,32 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
}
}
}
/// Parse a single integer.
///
/// Used by attributes that take a single integer as argument, such as
/// `#[link_ordinal]` and `#[rustc_layout_scalar_valid_range_start]`.
/// `cx` is the context given to the attribute.
/// `args` is the parser for the attribute arguments.
pub(crate) fn parse_single_integer<S: Stage>(
cx: &mut AcceptContext<'_, '_, S>,
args: &ArgParser<'_>,
) -> Option<u128> {
let Some(list) = args.list() else {
cx.expected_list(cx.attr_span);
return None;
};
let Some(single) = list.single() else {
cx.expected_single_argument(list.span);
return None;
};
let Some(lit) = single.lit() else {
cx.expected_integer_literal(single.span());
return None;
};
let LitKind::Int(num, _ty) = lit.kind else {
cx.expected_integer_literal(single.span());
return None;
};
Some(num.0)
}

View file

@ -514,6 +514,15 @@ pub(crate) struct NakedFunctionIncompatibleAttribute {
pub attr: String,
}
#[derive(Diagnostic)]
#[diag(attr_parsing_link_ordinal_out_of_range)]
#[note]
pub(crate) struct LinkOrdinalOutOfRange {
#[primary_span]
pub span: Span,
pub ordinal: u128,
}
pub(crate) enum AttributeParseErrorReason {
ExpectedNoArgs,
ExpectedStringLiteral { byte_string: Option<Span> },

View file

@ -80,9 +80,6 @@ codegen_ssa_ignoring_emit_path = ignoring emit path because multiple .{$extensio
codegen_ssa_ignoring_output = ignoring -o because multiple .{$extension} files were produced
codegen_ssa_illegal_link_ordinal_format = illegal ordinal format in `link_ordinal`
.note = an unsuffixed integer value, e.g., `1`, is expected
codegen_ssa_incorrect_cgu_reuse_type =
CGU-reuse for `{$cgu_user_name}` is `{$actual_reuse}` but should be {$at_least ->
[one] {"at least "}
@ -93,9 +90,6 @@ codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and i
codegen_ssa_invalid_instruction_set = invalid instruction set specified
codegen_ssa_invalid_link_ordinal_nargs = incorrect number of arguments to `#[link_ordinal]`
.note = the attribute requires exactly one argument
codegen_ssa_invalid_literal_value = invalid literal value
.label = value must be an integer between `0` and `255`

View file

@ -116,6 +116,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
AttributeKind::Naked(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
AttributeKind::Align { align, .. } => codegen_fn_attrs.alignment = Some(*align),
AttributeKind::LinkName { name, .. } => codegen_fn_attrs.link_name = Some(*name),
AttributeKind::LinkOrdinal { ordinal, span } => {
codegen_fn_attrs.link_ordinal = Some(*ordinal);
link_ordinal_span = Some(*span);
}
AttributeKind::LinkSection { name, .. } => {
codegen_fn_attrs.link_section = Some(*name)
}
@ -250,12 +254,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
}
}
}
sym::link_ordinal => {
link_ordinal_span = Some(attr.span());
if let ordinal @ Some(_) = check_link_ordinal(tcx, attr) {
codegen_fn_attrs.link_ordinal = ordinal;
}
}
sym::no_sanitize => {
no_sanitize_span = Some(attr.span());
if let Some(list) = attr.meta_item_list() {
@ -568,45 +566,6 @@ fn inherited_align<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Align> {
tcx.codegen_fn_attrs(opt_trait_item(tcx, def_id)?).alignment
}
fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &hir::Attribute) -> Option<u16> {
use rustc_ast::{LitIntType, LitKind, MetaItemLit};
let meta_item_list = attr.meta_item_list()?;
let [sole_meta_list] = &meta_item_list[..] else {
tcx.dcx().emit_err(errors::InvalidLinkOrdinalNargs { span: attr.span() });
return None;
};
if let Some(MetaItemLit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) =
sole_meta_list.lit()
{
// According to the table at
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header, the
// ordinal must fit into 16 bits. Similarly, the Ordinal field in COFFShortExport (defined
// in llvm/include/llvm/Object/COFFImportFile.h), which we use to communicate import
// information to LLVM for `#[link(kind = "raw-dylib"_])`, is also defined to be uint16_t.
//
// FIXME: should we allow an ordinal of 0? The MSVC toolchain has inconsistent support for
// this: both LINK.EXE and LIB.EXE signal errors and abort when given a .DEF file that
// specifies a zero ordinal. However, llvm-dlltool is perfectly happy to generate an import
// library for such a .DEF file, and MSVC's LINK.EXE is also perfectly happy to consume an
// import library produced by LLVM with an ordinal of 0, and it generates an .EXE. (I
// don't know yet if the resulting EXE runs, as I haven't yet built the necessary DLL --
// see earlier comment about LINK.EXE failing.)
if *ordinal <= u16::MAX as u128 {
Some(ordinal.get() as u16)
} else {
let msg = format!("ordinal value in `link_ordinal` is too large: `{ordinal}`");
tcx.dcx()
.struct_span_err(attr.span(), msg)
.with_note("the value may not exceed `u16::MAX`")
.emit();
None
}
} else {
tcx.dcx().emit_err(errors::InvalidLinkOrdinalFormat { span: attr.span() });
None
}
}
fn check_link_name_xor_ordinal(
tcx: TyCtxt<'_>,
codegen_fn_attrs: &CodegenFnAttrs,

View file

@ -1108,22 +1108,6 @@ pub(crate) struct InvalidNoSanitize {
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_invalid_link_ordinal_nargs)]
#[note]
pub(crate) struct InvalidLinkOrdinalNargs {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_illegal_link_ordinal_format)]
#[note]
pub(crate) struct InvalidLinkOrdinalFormat {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_target_feature_safe_trait)]
pub(crate) struct TargetFeatureSafeTrait {

View file

@ -444,7 +444,7 @@ declare_features! (
/// Be more precise when looking for live drops in a const context.
(unstable, const_precise_live_drops, "1.46.0", Some(73255)),
/// Allows `impl const Trait for T` syntax.
(unstable, const_trait_impl, "1.42.0", Some(67792)),
(unstable, const_trait_impl, "1.42.0", Some(143874)),
/// Allows the `?` operator in const contexts.
(unstable, const_try, "1.56.0", Some(74935)),
/// Allows use of contracts attributes.

View file

@ -3,6 +3,7 @@ use std::path::{Path, PathBuf};
use rustc_abi::ExternAbi;
use rustc_ast::CRATE_NODE_ID;
use rustc_attr_data_structures::{AttributeKind, find_attr};
use rustc_attr_parsing as attr;
use rustc_data_structures::fx::FxHashSet;
use rustc_middle::query::LocalCrate;
@ -496,14 +497,9 @@ impl<'tcx> Collector<'tcx> {
}
_ => {
for &child_item in foreign_items {
if self.tcx.def_kind(child_item).has_codegen_attrs()
&& self.tcx.codegen_fn_attrs(child_item).link_ordinal.is_some()
if let Some(span) = find_attr!(self.tcx.get_all_attrs(child_item), AttributeKind::LinkOrdinal {span, ..} => *span)
{
let link_ordinal_attr =
self.tcx.get_attr(child_item, sym::link_ordinal).unwrap();
sess.dcx().emit_err(errors::LinkOrdinalRawDylib {
span: link_ordinal_attr.span(),
});
sess.dcx().emit_err(errors::LinkOrdinalRawDylib { span });
}
}

View file

@ -310,6 +310,7 @@ pub fn check_builtin_meta_item(
| sym::must_use
| sym::track_caller
| sym::link_name
| sym::link_ordinal
| sym::export_name
| sym::rustc_macro_transparency
| sym::link_section

View file

@ -700,7 +700,7 @@ passes_trait_impl_const_stability_mismatch_trait_unstable = ...but the trait is
passes_trait_impl_const_stable =
trait implementations cannot be const stable yet
.note = see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
.note = see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
passes_transparent_incompatible =
transparent {$target} cannot have other repr hints

View file

@ -258,6 +258,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
Attribute::Parsed(AttributeKind::LinkName { span: attr_span, name }) => {
self.check_link_name(hir_id, *attr_span, *name, span, target)
}
Attribute::Parsed(AttributeKind::LinkOrdinal { span: attr_span, .. }) => {
self.check_link_ordinal(*attr_span, span, target)
}
Attribute::Parsed(AttributeKind::MayDangle(attr_span)) => {
self.check_may_dangle(hir_id, *attr_span)
}
@ -335,7 +338,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
[sym::rustc_has_incoherent_inherent_impls, ..] => {
self.check_has_incoherent_inherent_impls(attr, span, target)
}
[sym::link_ordinal, ..] => self.check_link_ordinal(attr, span, target),
[sym::ffi_pure, ..] => self.check_ffi_pure(attr.span(), attrs, target),
[sym::ffi_const, ..] => self.check_ffi_const(attr.span(), target),
[sym::link, ..] => self.check_link(hir_id, attr, span, target),
[sym::macro_use, ..] | [sym::macro_escape, ..] => {
self.check_macro_use(hir_id, attr, target)
@ -2265,11 +2269,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}
fn check_link_ordinal(&self, attr: &Attribute, _span: Span, target: Target) {
fn check_link_ordinal(&self, attr_span: Span, _span: Span, target: Target) {
match target {
Target::ForeignFn | Target::ForeignStatic => {}
_ => {
self.dcx().emit_err(errors::LinkOrdinal { attr_span: attr.span() });
self.dcx().emit_err(errors::LinkOrdinal { attr_span });
}
}
}

View file

@ -2611,7 +2611,7 @@ impl_eq! { Cow<'a, str>, &'b str }
impl_eq! { Cow<'a, str>, String }
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
impl const Default for String {
/// Creates an empty `String`.
#[inline]

View file

@ -3895,7 +3895,7 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for Vec<T, A> {
}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
impl<T> const Default for Vec<T> {
/// Creates an empty `Vec<T>`.
///

View file

@ -333,7 +333,7 @@ impl<T: Copy> Clone for Cell<T> {
}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
impl<T: ~const Default> const Default for Cell<T> {
/// Creates a `Cell<T>`, with the `Default` value for T.
#[inline]
@ -1324,7 +1324,7 @@ impl<T: Clone> Clone for RefCell<T> {
}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
impl<T: ~const Default> const Default for RefCell<T> {
/// Creates a `RefCell<T>`, with the `Default` value for T.
#[inline]
@ -2332,7 +2332,7 @@ impl<T: ?Sized> UnsafeCell<T> {
}
#[stable(feature = "unsafe_cell_default", since = "1.10.0")]
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
impl<T: ~const Default> const Default for UnsafeCell<T> {
/// Creates an `UnsafeCell`, with the `Default` value for T.
fn default() -> UnsafeCell<T> {
@ -2437,7 +2437,7 @@ impl<T: ?Sized> SyncUnsafeCell<T> {
}
#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
impl<T: ~const Default> const Default for SyncUnsafeCell<T> {
/// Creates an `SyncUnsafeCell`, with the `Default` value for T.
fn default() -> SyncUnsafeCell<T> {

View file

@ -104,7 +104,7 @@ use crate::ascii::Char as AsciiChar;
#[rustc_diagnostic_item = "Default"]
#[stable(feature = "rust1", since = "1.0.0")]
#[const_trait]
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
pub trait Default: Sized {
/// Returns the "default value" for a type.
///
@ -151,7 +151,7 @@ pub macro Default($item:item) {
macro_rules! default_impl {
($t:ty, $v:expr, $doc:tt) => {
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
impl const Default for $t {
#[inline(always)]
#[doc = $doc]

View file

@ -910,7 +910,7 @@ pub const unsafe fn arith_offset<T>(dst: *const T, offset: isize) -> *const T;
/// # Safety
///
/// - `index < PtrMetadata(slice_ptr)`, so the indexing is in-bounds for the slice
/// - the resulting offsetting is in-bounds of the allocated object, which is
/// - the resulting offsetting is in-bounds of the allocation, which is
/// always the case for references, but needs to be upheld manually for pointers
#[rustc_nounwind]
#[rustc_intrinsic]

View file

@ -81,7 +81,7 @@ impl<T> Clone for Empty<T> {
// not #[derive] because that adds a Default bound on T,
// which isn't necessary.
#[stable(feature = "iter_empty", since = "1.2.0")]
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
impl<T> const Default for Empty<T> {
fn default() -> Empty<T> {
Empty(marker::PhantomData)

View file

@ -863,7 +863,7 @@ impl<T: PointeeSized> Clone for PhantomData<T> {
}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
impl<T: PointeeSized> const Default for PhantomData<T> {
fn default() -> Self {
Self

View file

@ -73,7 +73,7 @@ use crate::marker::Tuple;
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
#[const_trait]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
pub trait Fn<Args: Tuple>: FnMut<Args> {
/// Performs the call operation.
#[unstable(feature = "fn_traits", issue = "29625")]
@ -161,7 +161,7 @@ pub trait Fn<Args: Tuple>: FnMut<Args> {
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
#[const_trait]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
pub trait FnMut<Args: Tuple>: FnOnce<Args> {
/// Performs the call operation.
#[unstable(feature = "fn_traits", issue = "29625")]
@ -241,7 +241,7 @@ pub trait FnMut<Args: Tuple>: FnOnce<Args> {
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
#[const_trait]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
pub trait FnOnce<Args: Tuple> {
/// The returned type after the call operator is used.
#[lang = "fn_once_output"]
@ -257,7 +257,7 @@ mod impls {
use crate::marker::Tuple;
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
impl<A: Tuple, F: ?Sized> const Fn<A> for &F
where
F: ~const Fn<A>,
@ -268,7 +268,7 @@ mod impls {
}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
impl<A: Tuple, F: ?Sized> const FnMut<A> for &F
where
F: ~const Fn<A>,
@ -279,7 +279,7 @@ mod impls {
}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
impl<A: Tuple, F: ?Sized> const FnOnce<A> for &F
where
F: ~const Fn<A>,
@ -292,7 +292,7 @@ mod impls {
}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
impl<A: Tuple, F: ?Sized> const FnMut<A> for &mut F
where
F: ~const FnMut<A>,
@ -303,7 +303,7 @@ mod impls {
}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
impl<A: Tuple, F: ?Sized> const FnOnce<A> for &mut F
where
F: ~const FnMut<A>,

View file

@ -2112,7 +2112,7 @@ where
impl<T> crate::clone::UseCloned for Option<T> where T: crate::clone::UseCloned {}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
impl<T> const Default for Option<T> {
/// Returns [`None`][Option::None].
///

View file

@ -230,7 +230,7 @@ impl hash::Hash for Alignment {
/// Returns [`Alignment::MIN`], which is valid for any type.
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
impl const Default for Alignment {
fn default() -> Alignment {
Alignment::MIN

View file

@ -19,7 +19,7 @@ If any of the following conditions are violated, the result is Undefined Behavio
bounds of that allocation. In particular, this range must not "wrap around" the edge
of the address space.
Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset
Allocations can never be larger than `isize::MAX` bytes, so if the computed offset
stays in bounds of the allocation, it is guaranteed to satisfy the first requirement.
This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec<T>`) is always
safe.

View file

@ -16,7 +16,7 @@ bounds of that allocation. In particular, this range must not "wrap around" the
of the address space. Note that "range" here refers to a half-open range as usual in Rust,
i.e., `self..result` for non-negative offsets and `result..self` for negative offsets.
Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset
Allocations can never be larger than `isize::MAX` bytes, so if the computed offset
stays in bounds of the allocation, it is guaranteed to satisfy the first requirement.
This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec<T>`) is always
safe.

View file

@ -5192,7 +5192,7 @@ where
}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
impl<T> const Default for &[T] {
/// Creates an empty slice.
fn default() -> Self {
@ -5201,7 +5201,7 @@ impl<T> const Default for &[T] {
}
#[stable(feature = "mut_slice_default", since = "1.5.0")]
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
impl<T> const Default for &mut [T] {
/// Creates a mutable empty slice.
fn default() -> Self {

View file

@ -3072,7 +3072,7 @@ impl AsRef<[u8]> for str {
}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
impl const Default for &str {
/// Creates an empty str
#[inline]
@ -3082,7 +3082,7 @@ impl const Default for &str {
}
#[stable(feature = "default_mut_str", since = "1.28.0")]
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
impl const Default for &mut str {
/// Creates an empty mutable str
#[inline]

View file

@ -8,16 +8,18 @@ use crate::sys::futex::{Futex, Primitive, futex_wait, futex_wake_all};
// This means we only need one atomic value with 4 states:
/// No initialization has run yet, and no thread is currently using the Once.
const INCOMPLETE: Primitive = 0;
const INCOMPLETE: Primitive = 3;
/// Some thread has previously attempted to initialize the Once, but it panicked,
/// so the Once is now poisoned. There are no other threads currently accessing
/// this Once.
const POISONED: Primitive = 1;
const POISONED: Primitive = 2;
/// Some thread is currently attempting to run initialization. It may succeed,
/// so all future threads need to wait for it to finish.
const RUNNING: Primitive = 2;
const RUNNING: Primitive = 1;
/// Initialization has completed and all future calls should finish immediately.
const COMPLETE: Primitive = 3;
/// By choosing this state as the all-zero state the `is_completed` check can be
/// a bit faster on some platforms.
const COMPLETE: Primitive = 0;
// An additional bit indicates whether there are waiting threads:

View file

@ -74,11 +74,12 @@ pub struct OnceState {
}
// Four states that a Once can be in, encoded into the lower bits of
// `state_and_queue` in the Once structure.
const INCOMPLETE: usize = 0x0;
const POISONED: usize = 0x1;
const RUNNING: usize = 0x2;
const COMPLETE: usize = 0x3;
// `state_and_queue` in the Once structure. By choosing COMPLETE as the all-zero
// state the `is_completed` check can be a bit faster on some platforms.
const INCOMPLETE: usize = 0x3;
const POISONED: usize = 0x2;
const RUNNING: usize = 0x1;
const COMPLETE: usize = 0x0;
// Mask to learn about the state. All other bits are the queue of waiters if
// this is in the RUNNING state.

View file

@ -9,6 +9,7 @@
//! Each Rust tool **MUST** utilize `ToolBuild` inside their `Step` logic,
//! return `ToolBuildResult` and should never prepare `cargo` invocations manually.
use std::ffi::OsStr;
use std::path::PathBuf;
use std::{env, fs};
@ -136,19 +137,6 @@ impl Step for ToolBuild {
_ => panic!("unexpected Mode for tool build"),
}
// build.tool.TOOL_NAME.features in bootstrap.toml allows specifying which features to
// enable for a specific tool. `extra_features` instead is not controlled by the toml and
// provides features that are always enabled for a specific tool (e.g. "in-rust-tree" for
// rust-analyzer). Finally, `prepare_tool_cargo` might add more features to adapt the build
// to the chosen flags (e.g. "all-static" for cargo if `cargo_native_static` is true).
let mut features = builder
.config
.tool
.get(self.tool)
.and_then(|tool| tool.features.clone())
.unwrap_or_default();
features.extend(self.extra_features.clone());
let mut cargo = prepare_tool_cargo(
builder,
self.compiler,
@ -157,7 +145,7 @@ impl Step for ToolBuild {
Kind::Build,
path,
self.source_type,
&features,
&self.extra_features,
);
// The stage0 compiler changes infrequently and does not directly depend on code
@ -244,7 +232,8 @@ pub fn prepare_tool_cargo(
) -> CargoCommand {
let mut cargo = builder::Cargo::new(builder, compiler, mode, source_type, target, cmd_kind);
let dir = builder.src.join(path);
let path = PathBuf::from(path);
let dir = builder.src.join(&path);
cargo.arg("--manifest-path").arg(dir.join("Cargo.toml"));
let mut features = extra_features.to_vec();
@ -261,6 +250,18 @@ pub fn prepare_tool_cargo(
}
}
// build.tool.TOOL_NAME.features in bootstrap.toml allows specifying which features to enable
// for a specific tool. `extra_features` instead is not controlled by the toml and provides
// features that are always enabled for a specific tool (e.g. "in-rust-tree" for rust-analyzer).
// Finally, `prepare_tool_cargo` above here might add more features to adapt the build
// to the chosen flags (e.g. "all-static" for cargo if `cargo_native_static` is true).
builder
.config
.tool
.iter()
.filter(|(tool_name, _)| path.file_name().and_then(OsStr::to_str) == Some(tool_name))
.for_each(|(_, tool)| features.extend(tool.features.clone().unwrap_or_default()));
// clippy tests need to know about the stage sysroot. Set them consistently while building to
// avoid rebuilding when running tests.
cargo.env("SYSROOT", builder.sysroot(compiler));
@ -1140,6 +1141,7 @@ macro_rules! tool_extended {
stable: $stable:expr
$( , add_bins_to_sysroot: $add_bins_to_sysroot:expr )?
$( , add_features: $add_features:expr )?
$( , cargo_args: $cargo_args:expr )?
$( , )?
}
) => {
@ -1180,6 +1182,7 @@ macro_rules! tool_extended {
$path,
None $( .or(Some(&$add_bins_to_sysroot)) )?,
None $( .or(Some($add_features)) )?,
None $( .or(Some($cargo_args)) )?,
)
}
@ -1219,6 +1222,7 @@ fn should_run_tool_build_step<'a>(
)
}
#[expect(clippy::too_many_arguments)] // silence overeager clippy lint
fn run_tool_build_step(
builder: &Builder<'_>,
compiler: Compiler,
@ -1227,6 +1231,7 @@ fn run_tool_build_step(
path: &'static str,
add_bins_to_sysroot: Option<&[&str]>,
add_features: Option<fn(&Builder<'_>, TargetSelection, &mut Vec<String>)>,
cargo_args: Option<&[&'static str]>,
) -> ToolBuildResult {
let mut extra_features = Vec::new();
if let Some(func) = add_features {
@ -1243,7 +1248,7 @@ fn run_tool_build_step(
extra_features,
source_type: SourceType::InTree,
allow_features: "",
cargo_args: vec![],
cargo_args: cargo_args.unwrap_or_default().iter().map(|s| String::from(*s)).collect(),
artifact_kind: ToolArtifactKind::Binary,
});
@ -1294,7 +1299,9 @@ tool_extended!(Miri {
path: "src/tools/miri",
tool_name: "miri",
stable: false,
add_bins_to_sysroot: ["miri"]
add_bins_to_sysroot: ["miri"],
// Always compile also tests when building miri. Otherwise feature unification can cause rebuilds between building and testing miri.
cargo_args: &["--all-targets"],
});
tool_extended!(CargoMiri {
path: "src/tools/miri/cargo-miri",

View file

@ -1044,6 +1044,7 @@ impl<'a> Builder<'a> {
Kind::Test => describe!(
crate::core::build_steps::toolstate::ToolStateCheck,
test::Tidy,
test::Bootstrap,
test::Ui,
test::Crashes,
test::Coverage,
@ -1098,8 +1099,6 @@ impl<'a> Builder<'a> {
test::RustInstaller,
test::TestFloatParse,
test::CollectLicenseMetadata,
// Run bootstrap close to the end as it's unlikely to fail
test::Bootstrap,
// Run run-make last, since these won't pass without make on Windows
test::RunMake,
),

View file

@ -471,4 +471,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
severity: ChangeSeverity::Info,
summary: "A --compile-time-deps flag has been added to reduce the time it takes rust-analyzer to start",
},
ChangeInfo {
change_id: 143733,
severity: ChangeSeverity::Info,
summary: "Option `tool.TOOL_NAME.features` now works on any subcommand, not just `build`.",
},
];

View file

@ -55,6 +55,9 @@ Similar to shell commands,
directives can extend across multiple lines if their last char is `\`.
In this case, the start of the next line should be `//`, with no `@`.
Similar to compiletest directives, besides a space you can also use a colon `:` to separate
the directive name and the arguments, however a space is preferred for HtmlDocCk directives.
Use the special string `{{channel}}` in XPaths, `PATTERN` arguments and [snapshot files](#snapshot)
if you'd like to refer to the URL `https://doc.rust-lang.org/CHANNEL` where `CHANNEL` refers to the
current release channel (e.g, `stable` or `nightly`).

View file

@ -147,48 +147,17 @@ def concat_multi_lines(f):
print_err(lineno, line, "Trailing backslash at the end of the file")
def get_known_directive_names():
def filter_line(line):
line = line.strip()
return line.startswith('"') and (line.endswith('",') or line.endswith('"'))
# Equivalent to `src/tools/compiletest/src/header.rs` constant of the same name.
with open(
os.path.join(
# We go back to `src`.
os.path.dirname(os.path.dirname(__file__)),
"tools/compiletest/src/directive-list.rs",
),
"r",
encoding="utf8",
) as fd:
content = fd.read()
return [
line.strip().replace('",', "").replace('"', "")
for line in content.split("\n")
if filter_line(line)
]
# To prevent duplicating the list of commmands between `compiletest` and `htmldocck`, we put
# it into a common file which is included in rust code and parsed here.
# FIXME: This setup is temporary until we figure out how to improve this situation.
# See <https://github.com/rust-lang/rust/issues/125813#issuecomment-2141953780>.
KNOWN_DIRECTIVE_NAMES = get_known_directive_names()
LINE_PATTERN = re.compile(
r"""
//@\s+
(?P<negated>!?)(?P<cmd>[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*)
(?P<args>.*)$
(?P<negated>!?)(?P<cmd>.+?)
(?:[\s:](?P<args>.*))?$
""",
re.X | re.UNICODE,
)
DEPRECATED_LINE_PATTERN = re.compile(
r"""
//\s+@
""",
r"//\s+@",
re.X | re.UNICODE,
)
@ -209,12 +178,7 @@ def get_commands(template):
cmd = m.group("cmd")
negated = m.group("negated") == "!"
if not negated and cmd in KNOWN_DIRECTIVE_NAMES:
continue
args = m.group("args")
if args and not args[:1].isspace():
print_err(lineno, line, "Invalid template syntax")
continue
args = m.group("args") or ""
try:
args = shlex.split(args)
except UnicodeEncodeError:
@ -636,14 +600,11 @@ def check_command(c, cache):
else:
raise InvalidCheck("Invalid number of {} arguments".format(c.cmd))
elif c.cmd == "valid-html":
raise InvalidCheck("Unimplemented valid-html")
elif c.cmd == "valid-links":
raise InvalidCheck("Unimplemented valid-links")
else:
raise InvalidCheck("Unrecognized {}".format(c.cmd))
# Ignore unknown directives as they might be compiletest directives
# since they share the same `//@` prefix by convention. In any case,
# compiletest rejects unknown directives for us.
return
if ret == c.negated:
raise FailedCheck(cerr)

View file

@ -980,7 +980,7 @@ fn assoc_method(
let name = meth.name.as_ref().unwrap();
let vis = visibility_print_with_space(meth, cx).to_string();
let defaultness = print_default_space(meth.is_default());
// FIXME: Once https://github.com/rust-lang/rust/issues/67792 is implemented, we can remove
// FIXME: Once https://github.com/rust-lang/rust/issues/143874 is implemented, we can remove
// this condition.
let constness = match render_mode {
RenderMode::Normal => print_constness_with_space(
@ -2152,7 +2152,7 @@ fn render_rightside(
let tcx = cx.tcx();
fmt::from_fn(move |w| {
// FIXME: Once https://github.com/rust-lang/rust/issues/67792 is implemented, we can remove
// FIXME: Once https://github.com/rust-lang/rust/issues/143874 is implemented, we can remove
// this condition.
let const_stability = match render_mode {
RenderMode::Normal => item.const_stability(tcx),

View file

@ -1,260 +0,0 @@
/// This was originally generated by collecting directives from ui tests and then extracting their
/// directive names. This is **not** an exhaustive list of all possible directives. Instead, this is
/// a best-effort approximation for diagnostics. Add new directives to this list when needed.
const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
// tidy-alphabetical-start
"add-core-stubs",
"assembly-output",
"aux-bin",
"aux-build",
"aux-codegen-backend",
"aux-crate",
"build-aux-docs",
"build-fail",
"build-pass",
"check-fail",
"check-pass",
"check-run-results",
"check-stdout",
"check-test-line-numbers-match",
"compile-flags",
"doc-flags",
"dont-check-compiler-stderr",
"dont-check-compiler-stdout",
"dont-check-failure-status",
"dont-require-annotations",
"edition",
"error-pattern",
"exact-llvm-major-version",
"exec-env",
"failure-status",
"filecheck-flags",
"forbid-output",
"force-host",
"ignore-16bit",
"ignore-32bit",
"ignore-64bit",
"ignore-aarch64",
"ignore-aarch64-pc-windows-msvc",
"ignore-aarch64-unknown-linux-gnu",
"ignore-aix",
"ignore-android",
"ignore-apple",
"ignore-arm",
"ignore-arm-unknown-linux-gnueabi",
"ignore-arm-unknown-linux-gnueabihf",
"ignore-arm-unknown-linux-musleabi",
"ignore-arm-unknown-linux-musleabihf",
"ignore-auxiliary",
"ignore-avr",
"ignore-beta",
"ignore-cdb",
"ignore-compare-mode-next-solver",
"ignore-compare-mode-polonius",
"ignore-coverage-map",
"ignore-coverage-run",
"ignore-cross-compile",
"ignore-eabi",
"ignore-elf",
"ignore-emscripten",
"ignore-endian-big",
"ignore-enzyme",
"ignore-freebsd",
"ignore-fuchsia",
"ignore-gdb",
"ignore-gdb-version",
"ignore-gnu",
"ignore-haiku",
"ignore-horizon",
"ignore-i686-pc-windows-gnu",
"ignore-i686-pc-windows-msvc",
"ignore-illumos",
"ignore-ios",
"ignore-linux",
"ignore-lldb",
"ignore-llvm-version",
"ignore-loongarch32",
"ignore-loongarch64",
"ignore-macabi",
"ignore-macos",
"ignore-msp430",
"ignore-msvc",
"ignore-musl",
"ignore-netbsd",
"ignore-nightly",
"ignore-none",
"ignore-nto",
"ignore-nvptx64",
"ignore-nvptx64-nvidia-cuda",
"ignore-openbsd",
"ignore-pass",
"ignore-powerpc",
"ignore-remote",
"ignore-riscv64",
"ignore-rustc-debug-assertions",
"ignore-rustc_abi-x86-sse2",
"ignore-s390x",
"ignore-sgx",
"ignore-sparc64",
"ignore-spirv",
"ignore-stable",
"ignore-stage1",
"ignore-stage2",
"ignore-std-debug-assertions",
"ignore-test",
"ignore-thumb",
"ignore-thumbv8m.base-none-eabi",
"ignore-thumbv8m.main-none-eabi",
"ignore-tvos",
"ignore-unix",
"ignore-unknown",
"ignore-uwp",
"ignore-visionos",
"ignore-vxworks",
"ignore-wasi",
"ignore-wasm",
"ignore-wasm32",
"ignore-wasm32-bare",
"ignore-wasm64",
"ignore-watchos",
"ignore-windows",
"ignore-windows-gnu",
"ignore-windows-msvc",
"ignore-x32",
"ignore-x86",
"ignore-x86_64",
"ignore-x86_64-apple-darwin",
"ignore-x86_64-pc-windows-gnu",
"ignore-x86_64-unknown-linux-gnu",
"incremental",
"known-bug",
"llvm-cov-flags",
"max-llvm-major-version",
"min-cdb-version",
"min-gdb-version",
"min-lldb-version",
"min-llvm-version",
"min-system-llvm-version",
"needs-asm-support",
"needs-crate-type",
"needs-deterministic-layouts",
"needs-dlltool",
"needs-dynamic-linking",
"needs-enzyme",
"needs-force-clang-based-tests",
"needs-git-hash",
"needs-llvm-components",
"needs-llvm-zstd",
"needs-profiler-runtime",
"needs-relocation-model-pic",
"needs-run-enabled",
"needs-rust-lld",
"needs-rustc-debug-assertions",
"needs-sanitizer-address",
"needs-sanitizer-cfi",
"needs-sanitizer-dataflow",
"needs-sanitizer-hwaddress",
"needs-sanitizer-kcfi",
"needs-sanitizer-leak",
"needs-sanitizer-memory",
"needs-sanitizer-memtag",
"needs-sanitizer-safestack",
"needs-sanitizer-shadow-call-stack",
"needs-sanitizer-support",
"needs-sanitizer-thread",
"needs-std-debug-assertions",
"needs-subprocess",
"needs-symlink",
"needs-target-has-atomic",
"needs-target-std",
"needs-threads",
"needs-unwind",
"needs-wasmtime",
"needs-xray",
"no-auto-check-cfg",
"no-prefer-dynamic",
"normalize-stderr",
"normalize-stderr-32bit",
"normalize-stderr-64bit",
"normalize-stdout",
"only-16bit",
"only-32bit",
"only-64bit",
"only-aarch64",
"only-aarch64-apple-darwin",
"only-aarch64-unknown-linux-gnu",
"only-apple",
"only-arm",
"only-avr",
"only-beta",
"only-bpf",
"only-cdb",
"only-dist",
"only-elf",
"only-emscripten",
"only-gnu",
"only-i686-pc-windows-gnu",
"only-i686-pc-windows-msvc",
"only-i686-unknown-linux-gnu",
"only-ios",
"only-linux",
"only-loongarch32",
"only-loongarch64",
"only-loongarch64-unknown-linux-gnu",
"only-macos",
"only-mips",
"only-mips64",
"only-msp430",
"only-msvc",
"only-nightly",
"only-nvptx64",
"only-powerpc",
"only-riscv64",
"only-rustc_abi-x86-sse2",
"only-s390x",
"only-sparc",
"only-sparc64",
"only-stable",
"only-thumb",
"only-tvos",
"only-unix",
"only-visionos",
"only-wasm32",
"only-wasm32-bare",
"only-wasm32-wasip1",
"only-watchos",
"only-windows",
"only-windows-gnu",
"only-windows-msvc",
"only-x86",
"only-x86_64",
"only-x86_64-apple-darwin",
"only-x86_64-fortanix-unknown-sgx",
"only-x86_64-pc-windows-gnu",
"only-x86_64-pc-windows-msvc",
"only-x86_64-unknown-linux-gnu",
"pp-exact",
"pretty-compare-only",
"pretty-mode",
"proc-macro",
"reference",
"regex-error-pattern",
"remap-src-base",
"revisions",
"run-fail",
"run-flags",
"run-pass",
"run-rustfix",
"rustc-env",
"rustfix-only-machine-applicable",
"should-fail",
"should-ice",
"stderr-per-bitwidth",
"test-mir-pass",
"unique-doc-out-dir",
"unset-exec-env",
"unset-rustc-env",
// Used by the tidy check `unknown_revision`.
"unused-revision-names",
// tidy-alphabetical-end
];

View file

@ -765,11 +765,266 @@ fn line_directive<'line>(
Some(DirectiveLine { line_number, revision, raw_directive })
}
// To prevent duplicating the list of directives between `compiletest`,`htmldocck` and `jsondocck`,
// we put it into a common file which is included in rust code and parsed here.
// FIXME: This setup is temporary until we figure out how to improve this situation.
// See <https://github.com/rust-lang/rust/issues/125813#issuecomment-2141953780>.
include!("directive-list.rs");
/// This was originally generated by collecting directives from ui tests and then extracting their
/// directive names. This is **not** an exhaustive list of all possible directives. Instead, this is
/// a best-effort approximation for diagnostics. Add new directives to this list when needed.
const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
// tidy-alphabetical-start
"add-core-stubs",
"assembly-output",
"aux-bin",
"aux-build",
"aux-codegen-backend",
"aux-crate",
"build-aux-docs",
"build-fail",
"build-pass",
"check-fail",
"check-pass",
"check-run-results",
"check-stdout",
"check-test-line-numbers-match",
"compile-flags",
"doc-flags",
"dont-check-compiler-stderr",
"dont-check-compiler-stdout",
"dont-check-failure-status",
"dont-require-annotations",
"edition",
"error-pattern",
"exact-llvm-major-version",
"exec-env",
"failure-status",
"filecheck-flags",
"forbid-output",
"force-host",
"ignore-16bit",
"ignore-32bit",
"ignore-64bit",
"ignore-aarch64",
"ignore-aarch64-pc-windows-msvc",
"ignore-aarch64-unknown-linux-gnu",
"ignore-aix",
"ignore-android",
"ignore-apple",
"ignore-arm",
"ignore-arm-unknown-linux-gnueabi",
"ignore-arm-unknown-linux-gnueabihf",
"ignore-arm-unknown-linux-musleabi",
"ignore-arm-unknown-linux-musleabihf",
"ignore-auxiliary",
"ignore-avr",
"ignore-beta",
"ignore-cdb",
"ignore-compare-mode-next-solver",
"ignore-compare-mode-polonius",
"ignore-coverage-map",
"ignore-coverage-run",
"ignore-cross-compile",
"ignore-eabi",
"ignore-elf",
"ignore-emscripten",
"ignore-endian-big",
"ignore-enzyme",
"ignore-freebsd",
"ignore-fuchsia",
"ignore-gdb",
"ignore-gdb-version",
"ignore-gnu",
"ignore-haiku",
"ignore-horizon",
"ignore-i686-pc-windows-gnu",
"ignore-i686-pc-windows-msvc",
"ignore-illumos",
"ignore-ios",
"ignore-linux",
"ignore-lldb",
"ignore-llvm-version",
"ignore-loongarch32",
"ignore-loongarch64",
"ignore-macabi",
"ignore-macos",
"ignore-msp430",
"ignore-msvc",
"ignore-musl",
"ignore-netbsd",
"ignore-nightly",
"ignore-none",
"ignore-nto",
"ignore-nvptx64",
"ignore-nvptx64-nvidia-cuda",
"ignore-openbsd",
"ignore-pass",
"ignore-powerpc",
"ignore-remote",
"ignore-riscv64",
"ignore-rustc-debug-assertions",
"ignore-rustc_abi-x86-sse2",
"ignore-s390x",
"ignore-sgx",
"ignore-sparc64",
"ignore-spirv",
"ignore-stable",
"ignore-stage1",
"ignore-stage2",
"ignore-std-debug-assertions",
"ignore-test",
"ignore-thumb",
"ignore-thumbv8m.base-none-eabi",
"ignore-thumbv8m.main-none-eabi",
"ignore-tvos",
"ignore-unix",
"ignore-unknown",
"ignore-uwp",
"ignore-visionos",
"ignore-vxworks",
"ignore-wasi",
"ignore-wasm",
"ignore-wasm32",
"ignore-wasm32-bare",
"ignore-wasm64",
"ignore-watchos",
"ignore-windows",
"ignore-windows-gnu",
"ignore-windows-msvc",
"ignore-x32",
"ignore-x86",
"ignore-x86_64",
"ignore-x86_64-apple-darwin",
"ignore-x86_64-pc-windows-gnu",
"ignore-x86_64-unknown-linux-gnu",
"incremental",
"known-bug",
"llvm-cov-flags",
"max-llvm-major-version",
"min-cdb-version",
"min-gdb-version",
"min-lldb-version",
"min-llvm-version",
"min-system-llvm-version",
"needs-asm-support",
"needs-crate-type",
"needs-deterministic-layouts",
"needs-dlltool",
"needs-dynamic-linking",
"needs-enzyme",
"needs-force-clang-based-tests",
"needs-git-hash",
"needs-llvm-components",
"needs-llvm-zstd",
"needs-profiler-runtime",
"needs-relocation-model-pic",
"needs-run-enabled",
"needs-rust-lld",
"needs-rustc-debug-assertions",
"needs-sanitizer-address",
"needs-sanitizer-cfi",
"needs-sanitizer-dataflow",
"needs-sanitizer-hwaddress",
"needs-sanitizer-kcfi",
"needs-sanitizer-leak",
"needs-sanitizer-memory",
"needs-sanitizer-memtag",
"needs-sanitizer-safestack",
"needs-sanitizer-shadow-call-stack",
"needs-sanitizer-support",
"needs-sanitizer-thread",
"needs-std-debug-assertions",
"needs-subprocess",
"needs-symlink",
"needs-target-has-atomic",
"needs-target-std",
"needs-threads",
"needs-unwind",
"needs-wasmtime",
"needs-xray",
"no-auto-check-cfg",
"no-prefer-dynamic",
"normalize-stderr",
"normalize-stderr-32bit",
"normalize-stderr-64bit",
"normalize-stdout",
"only-16bit",
"only-32bit",
"only-64bit",
"only-aarch64",
"only-aarch64-apple-darwin",
"only-aarch64-unknown-linux-gnu",
"only-apple",
"only-arm",
"only-avr",
"only-beta",
"only-bpf",
"only-cdb",
"only-dist",
"only-elf",
"only-emscripten",
"only-gnu",
"only-i686-pc-windows-gnu",
"only-i686-pc-windows-msvc",
"only-i686-unknown-linux-gnu",
"only-ios",
"only-linux",
"only-loongarch32",
"only-loongarch64",
"only-loongarch64-unknown-linux-gnu",
"only-macos",
"only-mips",
"only-mips64",
"only-msp430",
"only-msvc",
"only-nightly",
"only-nvptx64",
"only-powerpc",
"only-riscv64",
"only-rustc_abi-x86-sse2",
"only-s390x",
"only-sparc",
"only-sparc64",
"only-stable",
"only-thumb",
"only-tvos",
"only-unix",
"only-visionos",
"only-wasm32",
"only-wasm32-bare",
"only-wasm32-wasip1",
"only-watchos",
"only-windows",
"only-windows-gnu",
"only-windows-msvc",
"only-x86",
"only-x86_64",
"only-x86_64-apple-darwin",
"only-x86_64-fortanix-unknown-sgx",
"only-x86_64-pc-windows-gnu",
"only-x86_64-pc-windows-msvc",
"only-x86_64-unknown-linux-gnu",
"pp-exact",
"pretty-compare-only",
"pretty-mode",
"proc-macro",
"reference",
"regex-error-pattern",
"remap-src-base",
"revisions",
"run-fail",
"run-flags",
"run-pass",
"run-rustfix",
"rustc-env",
"rustfix-only-machine-applicable",
"should-fail",
"should-ice",
"stderr-per-bitwidth",
"test-mir-pass",
"unique-doc-out-dir",
"unset-exec-env",
"unset-rustc-env",
// Used by the tidy check `unknown_revision`.
"unused-revision-names",
// tidy-alphabetical-end
];
const KNOWN_HTMLDOCCK_DIRECTIVE_NAMES: &[&str] = &[
"count",
@ -834,35 +1089,26 @@ pub(crate) struct CheckDirectiveResult<'ln> {
pub(crate) fn check_directive<'a>(
directive_ln: &'a str,
mode: TestMode,
original_line: &str,
) -> CheckDirectiveResult<'a> {
let (directive_name, post) = directive_ln.split_once([':', ' ']).unwrap_or((directive_ln, ""));
let is_known_directive = KNOWN_DIRECTIVE_NAMES.contains(&directive_name)
|| match mode {
TestMode::Rustdoc => KNOWN_HTMLDOCCK_DIRECTIVE_NAMES.contains(&directive_name),
TestMode::RustdocJson => KNOWN_JSONDOCCK_DIRECTIVE_NAMES.contains(&directive_name),
_ => false,
};
let trailing = post.trim().split_once(' ').map(|(pre, _)| pre).unwrap_or(post);
let is_known = |s: &str| {
KNOWN_DIRECTIVE_NAMES.contains(&s)
|| match mode {
TestMode::Rustdoc | TestMode::RustdocJson => {
original_line.starts_with("//@")
&& match mode {
TestMode::Rustdoc => KNOWN_HTMLDOCCK_DIRECTIVE_NAMES,
TestMode::RustdocJson => KNOWN_JSONDOCCK_DIRECTIVE_NAMES,
_ => unreachable!(),
}
.contains(&s)
}
_ => false,
}
};
let trailing_directive = {
// 1. is the directive name followed by a space? (to exclude `:`)
matches!(directive_ln.get(directive_name.len()..), Some(s) if s.starts_with(' '))
directive_ln.get(directive_name.len()..).is_some_and(|s| s.starts_with(' '))
// 2. is what is after that directive also a directive (ex: "only-x86 only-arm")
&& is_known(trailing)
&& KNOWN_DIRECTIVE_NAMES.contains(&trailing)
}
.then_some(trailing);
CheckDirectiveResult { is_known_directive: is_known(&directive_name), trailing_directive }
CheckDirectiveResult { is_known_directive, trailing_directive }
}
const COMPILETEST_DIRECTIVE_PREFIX: &str = "//@";
@ -914,9 +1160,9 @@ fn iter_directives(
};
// Perform unknown directive check on Rust files.
if testfile.extension().map(|e| e == "rs").unwrap_or(false) {
if testfile.extension() == Some("rs") {
let CheckDirectiveResult { is_known_directive, trailing_directive } =
check_directive(directive_line.raw_directive, mode, ln);
check_directive(directive_line.raw_directive, mode);
if !is_known_directive {
*poisoned = true;
@ -936,7 +1182,7 @@ fn iter_directives(
"{testfile}:{line_number}: detected trailing compiletest test directive `{}`",
trailing_directive,
);
help!("put the trailing directive in it's own line: `//@ {}`", trailing_directive);
help!("put the trailing directive in its own line: `//@ {}`", trailing_directive);
return;
}

View file

@ -4,7 +4,7 @@ use super::{TestCx, remove_and_create_dir_all};
impl TestCx<'_> {
pub(super) fn run_rustdoc_test(&self) {
assert!(self.revision.is_none(), "revisions not relevant here");
assert!(self.revision.is_none(), "revisions not supported in this test suite");
let out_dir = self.output_base_dir();
remove_and_create_dir_all(&out_dir).unwrap_or_else(|e| {

View file

@ -6,7 +6,7 @@ impl TestCx<'_> {
pub(super) fn run_rustdoc_json_test(&self) {
//FIXME: Add bless option.
assert!(self.revision.is_none(), "revisions not relevant here");
assert!(self.revision.is_none(), "revisions not supported in this test suite");
let out_dir = self.output_base_dir();
remove_and_create_dir_all(&out_dir).unwrap_or_else(|e| {

View file

@ -105,13 +105,10 @@ impl DirectiveKind {
[_path, value] => Self::HasNotValue { value: value.clone() },
_ => panic!("`//@ !has` must have 2 or 3 arguments, but got {args:?}"),
},
// Ignore compiletest directives, like //@ edition
(_, false) if KNOWN_DIRECTIVE_NAMES.contains(&directive_name) => {
return None;
}
_ => {
panic!("Invalid directive `//@ {}{directive_name}`", if negated { "!" } else { "" })
}
// Ignore unknown directives as they might be compiletest directives
// since they share the same `//@` prefix by convention. In any case,
// compiletest rejects unknown directives for us.
_ => return None,
};
Some((kind, &args[0]))
@ -216,10 +213,6 @@ fn get_one<'a>(matches: &[&'a Value]) -> Result<&'a Value, String> {
}
}
// FIXME: This setup is temporary until we figure out how to improve this situation.
// See <https://github.com/rust-lang/rust/issues/125813#issuecomment-2141953780>.
include!(concat!(env!("CARGO_MANIFEST_DIR"), "/../compiletest/src/directive-list.rs"));
fn string_to_value<'a>(s: &str, cache: &'a Cache) -> Cow<'a, Value> {
if s.starts_with("$") {
Cow::Borrowed(&cache.variables.get(&s[1..]).unwrap_or_else(|| {

View file

@ -47,8 +47,8 @@ static LINE_PATTERN: LazyLock<Regex> = LazyLock::new(|| {
^\s*
//@\s+
(?P<negated>!?)
(?P<directive>[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*)
(?P<args>.*)$
(?P<directive>.+?)
(?:[\s:](?P<args>.*))?$
"#,
)
.ignore_whitespace(true)
@ -58,15 +58,7 @@ static LINE_PATTERN: LazyLock<Regex> = LazyLock::new(|| {
});
static DEPRECATED_LINE_PATTERN: LazyLock<Regex> = LazyLock::new(|| {
RegexBuilder::new(
r#"
//\s+@
"#,
)
.ignore_whitespace(true)
.unicode(true)
.build()
.unwrap()
RegexBuilder::new(r"//\s+@").ignore_whitespace(true).unicode(true).build().unwrap()
});
fn print_err(msg: &str, lineno: usize) {
@ -94,7 +86,7 @@ fn get_directives(template: &str) -> Result<Vec<Directive>, ()> {
let negated = &cap["negated"] == "!";
let args_str = &cap["args"];
let args_str = cap.name("args").map(|m| m.as_str()).unwrap_or_default();
let Some(args) = shlex::split(args_str) else {
print_err(&format!("Invalid arguments to shlex::split: `{args_str}`",), lineno);
errors = true;

View file

@ -4711,9 +4711,9 @@ The tracking issue for this feature is: [#133668]
label: "const_trait_impl",
description: r##"# `const_trait_impl`
The tracking issue for this feature is: [#67792]
The tracking issue for this feature is: [#143874]
[#67792]: https://github.com/rust-lang/rust/issues/67792
[#143874]: https://github.com/rust-lang/rust/issues/143874
------------------------
"##,

View file

@ -1,7 +1,7 @@
[package]
name = "tidy"
version = "0.1.0"
edition = "2021"
edition = "2024"
autobins = false
[dependencies]

View file

@ -103,7 +103,7 @@ fn check_section<'a>(
let prev_line_trimmed_lowercase = prev_line.trim_start_matches(' ');
if version_sort(&trimmed_line, &prev_line_trimmed_lowercase).is_lt() {
if version_sort(trimmed_line, prev_line_trimmed_lowercase).is_lt() {
tidy_error_ext!(err, bad, "{file}:{}: line not in alphabetical order", idx + 1);
}

View file

@ -75,7 +75,7 @@ mod os_impl {
return ReadOnlyFs;
}
panic!("unable to create temporary file `{:?}`: {:?}", path, e);
panic!("unable to create temporary file `{path:?}`: {e:?}");
}
}
}
@ -83,12 +83,7 @@ mod os_impl {
for &source_dir in sources {
match check_dir(source_dir) {
Unsupported => return false,
ReadOnlyFs => {
return match check_dir(output) {
Supported => true,
_ => false,
};
}
ReadOnlyFs => return matches!(check_dir(output), Supported),
_ => {}
}
}
@ -139,7 +134,7 @@ mod os_impl {
return;
}
if t!(is_executable(&file), file) {
if t!(is_executable(file), file) {
let rel_path = file.strip_prefix(path).unwrap();
let git_friendly_path = rel_path.to_str().unwrap().replace("\\", "/");

View file

@ -624,7 +624,7 @@ fn check_proc_macro_dep_list(root: &Path, cargo: &Path, bless: bool, bad: &mut b
let is_proc_macro_pkg = |pkg: &Package| pkg.targets.iter().any(|target| target.is_proc_macro());
let mut proc_macro_deps = HashSet::new();
for pkg in metadata.packages.iter().filter(|pkg| is_proc_macro_pkg(*pkg)) {
for pkg in metadata.packages.iter().filter(|pkg| is_proc_macro_pkg(pkg)) {
deps_of(&metadata, &pkg.id, &mut proc_macro_deps);
}
// Remove the proc-macro crates themselves

View file

@ -119,8 +119,7 @@ fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>) -> Vec<String
let Some(split_line) = split_line else {
errors.push(format!(
"{path}:{line_index}: Expected a line with the format `Eabcd: abcd, \
but got \"{}\" without a `:` delimiter",
line,
but got \"{line}\" without a `:` delimiter",
));
continue;
};
@ -129,10 +128,8 @@ fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>) -> Vec<String
// If this is a duplicate of another error code, emit a fatal error.
if error_codes.contains(&err_code) {
errors.push(format!(
"{path}:{line_index}: Found duplicate error code: `{}`",
err_code
));
errors
.push(format!("{path}:{line_index}: Found duplicate error code: `{err_code}`"));
continue;
}
@ -145,8 +142,7 @@ fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>) -> Vec<String
let Some(rest) = rest else {
errors.push(format!(
"{path}:{line_index}: Expected a line with the format `Eabcd: abcd, \
but got \"{}\" without a `,` delimiter",
line,
but got \"{line}\" without a `,` delimiter",
));
continue;
};
@ -209,7 +205,7 @@ fn check_error_codes_docs(
}
let (found_code_example, found_proper_doctest, emit_ignore_warning, no_longer_emitted) =
check_explanation_has_doctest(&contents, &err_code);
check_explanation_has_doctest(contents, err_code);
if emit_ignore_warning {
verbose_print!(
@ -232,7 +228,7 @@ fn check_error_codes_docs(
return;
}
let test_ignored = IGNORE_DOCTEST_CHECK.contains(&&err_code);
let test_ignored = IGNORE_DOCTEST_CHECK.contains(&err_code);
// Check that the explanation has a doctest, and if it shouldn't, that it doesn't
if !found_proper_doctest && !test_ignored {
@ -300,7 +296,7 @@ fn check_error_codes_tests(
let tests_path = root_path.join(Path::new(ERROR_TESTS_PATH));
for code in error_codes {
let test_path = tests_path.join(format!("{}.stderr", code));
let test_path = tests_path.join(format!("{code}.stderr"));
if !test_path.exists() && !IGNORE_UI_TEST_CHECK.contains(&code.as_str()) {
verbose_print!(
@ -388,7 +384,7 @@ fn check_error_codes_used(
if !error_codes.contains(&error_code) {
// This error code isn't properly defined, we must error.
errors.push(format!("Error code `{}` is used in the compiler but not defined and documented in `compiler/rustc_error_codes/src/lib.rs`.", error_code));
errors.push(format!("Error code `{error_code}` is used in the compiler but not defined and documented in `compiler/rustc_error_codes/src/lib.rs`."));
continue;
}

View file

@ -64,8 +64,8 @@ fn check_impl(
extra_checks: Option<&str>,
pos_args: &[String],
) -> Result<(), Error> {
let show_diff = std::env::var("TIDY_PRINT_DIFF")
.map_or(false, |v| v.eq_ignore_ascii_case("true") || v == "1");
let show_diff =
std::env::var("TIDY_PRINT_DIFF").is_ok_and(|v| v.eq_ignore_ascii_case("true") || v == "1");
// Split comma-separated args up
let lint_args = match extra_checks {
@ -141,7 +141,7 @@ fn check_impl(
);
}
// Rethrow error
let _ = res?;
res?;
}
if python_fmt {
@ -173,7 +173,7 @@ fn check_impl(
}
// Rethrow error
let _ = res?;
res?;
}
if cpp_fmt {
@ -244,7 +244,7 @@ fn check_impl(
}
}
// Rethrow error
let _ = res?;
res?;
}
if shell_lint {
@ -286,8 +286,8 @@ fn run_ruff(
file_args: &[&OsStr],
ruff_args: &[&OsStr],
) -> Result<(), Error> {
let mut cfg_args_ruff = cfg_args.into_iter().copied().collect::<Vec<_>>();
let mut file_args_ruff = file_args.into_iter().copied().collect::<Vec<_>>();
let mut cfg_args_ruff = cfg_args.to_vec();
let mut file_args_ruff = file_args.to_vec();
let mut cfg_path = root_path.to_owned();
cfg_path.extend(RUFF_CONFIG_PATH);
@ -305,7 +305,7 @@ fn run_ruff(
file_args_ruff.push(root_path.as_os_str());
}
let mut args: Vec<&OsStr> = ruff_args.into_iter().copied().collect();
let mut args: Vec<&OsStr> = ruff_args.to_vec();
args.extend(merge_args(&cfg_args_ruff, &file_args_ruff));
py_runner(py_path, true, None, "ruff", &args)
}

View file

@ -41,7 +41,7 @@ pub fn check(root: &Path, bad: &mut bool) {
let source = line.split_once('=').unwrap().1.trim();
// Ensure source is allowed.
if !ALLOWED_SOURCES.contains(&&*source) {
if !ALLOWED_SOURCES.contains(&source) {
tidy_error!(bad, "invalid source: {}", source);
}
}

View file

@ -125,8 +125,8 @@ pub fn check(
let gate_test_str = "gate-test-";
let feature_name = match line.find(gate_test_str) {
// NB: the `splitn` always succeeds, even if the delimiter is not present.
Some(i) => line[i + gate_test_str.len()..].splitn(2, ' ').next().unwrap(),
// `split` always contains at least 1 element, even if the delimiter is not present.
Some(i) => line[i + gate_test_str.len()..].split(' ').next().unwrap(),
None => continue,
};
match features.get_mut(feature_name) {
@ -135,16 +135,14 @@ pub fn check(
err(&format!(
"The file is already marked as gate test \
through its name, no need for a \
'gate-test-{}' comment",
feature_name
'gate-test-{feature_name}' comment"
));
}
f.has_gate_test = true;
}
None => {
err(&format!(
"gate-test test found referencing a nonexistent feature '{}'",
feature_name
"gate-test test found referencing a nonexistent feature '{feature_name}'"
));
}
}
@ -170,8 +168,7 @@ pub fn check(
);
println!(
"Hint: If you already have such a test and don't want to rename it,\
\n you can also add a // gate-test-{} line to the test file.",
name
\n you can also add a // gate-test-{name} line to the test file."
);
}
@ -231,7 +228,7 @@ pub fn check(
fn get_version_and_channel(src_path: &Path) -> (Version, String) {
let version_str = t!(std::fs::read_to_string(src_path.join("version")));
let version_str = version_str.trim();
let version = t!(std::str::FromStr::from_str(&version_str).map_err(|e| format!("{e:?}")));
let version = t!(std::str::FromStr::from_str(version_str).map_err(|e| format!("{e:?}")));
let channel_str = t!(std::fs::read_to_string(src_path.join("ci").join("channel")));
(version, channel_str.trim().to_owned())
}
@ -468,7 +465,7 @@ fn get_and_check_lib_features(
map_lib_features(base_src_path, &mut |res, file, line| match res {
Ok((name, f)) => {
let mut check_features = |f: &Feature, list: &Features, display: &str| {
if let Some(ref s) = list.get(name) {
if let Some(s) = list.get(name) {
if f.tracking_issue != s.tracking_issue && f.level != Status::Accepted {
tidy_error!(
bad,
@ -483,7 +480,7 @@ fn get_and_check_lib_features(
}
}
};
check_features(&f, &lang_features, "corresponding lang feature");
check_features(&f, lang_features, "corresponding lang feature");
check_features(&f, &lib_features, "previous");
lib_features.insert(name.to_owned(), f);
}
@ -543,7 +540,7 @@ fn map_lib_features(
continue;
}
if let Some((ref name, ref mut f)) = becoming_feature {
if let Some((name, ref mut f)) = becoming_feature {
if f.tracking_issue.is_none() {
f.tracking_issue = find_attr_val(line, "issue").and_then(handle_issue_none);
}

View file

@ -20,7 +20,7 @@ impl fmt::Display for Version {
Version::Explicit { parts } => {
f.pad(&format!("{}.{}.{}", parts[0], parts[1], parts[2]))
}
Version::CurrentPlaceholder => f.pad(&format!("CURRENT")),
Version::CurrentPlaceholder => f.pad("CURRENT"),
}
}
}

View file

@ -33,6 +33,6 @@ fn test_to_string() {
assert_eq!(v_1_0_0.to_string(), "1.0.0");
assert_eq!(v_1_32_1.to_string(), "1.32.1");
assert_eq!(format!("{:<8}", v_1_32_1), "1.32.1 ");
assert_eq!(format!("{:>8}", v_1_32_1), " 1.32.1");
assert_eq!(format!("{v_1_32_1:<8}"), "1.32.1 ");
assert_eq!(format!("{v_1_32_1:>8}"), " 1.32.1");
}

View file

@ -13,8 +13,8 @@ fn message() -> &'static Regex {
static_regex!(r#"(?m)^([a-zA-Z0-9_]+)\s*=\s*"#)
}
fn filter_fluent(path: &Path) -> bool {
if let Some(ext) = path.extension() { ext.to_str() != Some("ftl") } else { true }
fn is_fluent(path: &Path) -> bool {
path.extension().is_some_and(|ext| ext == "flt")
}
fn check_alphabetic(
@ -92,7 +92,7 @@ pub fn check(path: &Path, bless: bool, bad: &mut bool) {
let mut all_defined_msgs = HashMap::new();
walk(
path,
|path, is_dir| filter_dirs(path) || (!is_dir && filter_fluent(path)),
|path, is_dir| filter_dirs(path) || (!is_dir && !is_fluent(path)),
&mut |ent, contents| {
if bless {
let sorted = sort_messages(
@ -104,7 +104,7 @@ pub fn check(path: &Path, bless: bool, bad: &mut bool) {
if sorted != contents {
let mut f =
OpenOptions::new().write(true).truncate(true).open(ent.path()).unwrap();
f.write(sorted.as_bytes()).unwrap();
f.write_all(sorted.as_bytes()).unwrap();
}
} else {
check_alphabetic(

View file

@ -37,7 +37,7 @@ fn check_period(filename: &str, contents: &str, bad: &mut bool) {
if let Some(PatternElement::TextElement { value }) = pat.elements.last() {
// We don't care about ellipses.
if value.ends_with(".") && !value.ends_with("...") {
let ll = find_line(contents, *value);
let ll = find_line(contents, value);
let name = m.id.name;
tidy_error!(bad, "{filename}:{ll}: message `{name}` ends in a period");
}
@ -52,7 +52,7 @@ fn check_period(filename: &str, contents: &str, bad: &mut bool) {
if let Some(PatternElement::TextElement { value }) = attr.value.elements.last() {
if value.ends_with(".") && !value.ends_with("...") {
let ll = find_line(contents, *value);
let ll = find_line(contents, value);
let name = attr.id.name;
tidy_error!(bad, "{filename}:{ll}: attr `{name}` ends in a period");
}

View file

@ -13,8 +13,8 @@ fn filter_used_messages(
// we don't just check messages never appear in Rust files,
// because messages can be used as parts of other fluent messages in Fluent files,
// so we do checking messages appear only once in all Rust and Fluent files.
let mut matches = static_regex!(r"\w+").find_iter(contents);
while let Some(name) = matches.next() {
let matches = static_regex!(r"\w+").find_iter(contents);
for name in matches {
if let Some((name, filename)) = msgs_not_appeared_yet.remove_entry(name.as_str()) {
// if one msg appears for the first time,
// remove it from `msgs_not_appeared_yet` and insert it into `msgs_appeared_only_once`.

View file

@ -7,7 +7,9 @@ use std::process::Command;
pub fn check(root_path: &Path, compiler_path: &Path, bad: &mut bool) {
let cg_gcc_version_path = compiler_path.join("rustc_codegen_gcc/libgccjit.version");
let cg_gcc_version = std::fs::read_to_string(&cg_gcc_version_path)
.expect(&format!("Cannot read GCC version from {}", cg_gcc_version_path.display()))
.unwrap_or_else(|_| {
panic!("Cannot read GCC version from {}", cg_gcc_version_path.display())
})
.trim()
.to_string();
@ -27,14 +29,13 @@ pub fn check(root_path: &Path, compiler_path: &Path, bad: &mut bool) {
// e607be166673a8de9fc07f6f02c60426e556c5f2 src/gcc (master-e607be166673a8de9fc07f6f02c60426e556c5f2.e607be)
// +e607be166673a8de9fc07f6f02c60426e556c5f2 src/gcc (master-e607be166673a8de9fc07f6f02c60426e556c5f2.e607be)
let git_output = String::from_utf8_lossy(&git_output.stdout)
.trim()
.split_whitespace()
.next()
.unwrap_or_default()
.to_string();
// The SHA can start with + if the submodule is modified or - if it is not checked out.
let gcc_submodule_sha = git_output.trim_start_matches(&['+', '-']);
let gcc_submodule_sha = git_output.trim_start_matches(['+', '-']);
if gcc_submodule_sha != cg_gcc_version {
*bad = true;
eprintln!(

View file

@ -15,11 +15,12 @@ use std::{env, process};
use tidy::*;
fn main() {
// Running Cargo will read the libstd Cargo.toml
// Enable nightly, because Cargo will read the libstd Cargo.toml
// which uses the unstable `public-dependency` feature.
//
// `setenv` might not be thread safe, so run it before using multiple threads.
env::set_var("RUSTC_BOOTSTRAP", "1");
// SAFETY: no other threads have been spawned
unsafe {
env::set_var("RUSTC_BOOTSTRAP", "1");
}
let root_path: PathBuf = env::args_os().nth(1).expect("need path to root of repo").into();
let cargo: PathBuf = env::args_os().nth(2).expect("need path to cargo").into();

View file

@ -49,7 +49,7 @@ fn check_unused_files(path: &Path, bless: bool, bad: &mut bool) {
}
fn check_dash_files(path: &Path, bless: bool, bad: &mut bool) {
for file in walkdir::WalkDir::new(&path.join("mir-opt"))
for file in walkdir::WalkDir::new(path.join("mir-opt"))
.into_iter()
.filter_map(Result::ok)
.filter(|e| e.file_type().is_file())

View file

@ -86,7 +86,7 @@ pub fn check(path: &Path, bad: &mut bool) {
return;
}
check_cfgs(contents, &file, bad, &mut saw_target_arch, &mut saw_cfg_bang);
check_cfgs(contents, file, bad, &mut saw_target_arch, &mut saw_cfg_bang);
});
assert!(saw_target_arch);

View file

@ -5,7 +5,7 @@ use std::path::Path;
pub fn check(path: &Path, bad: &mut bool) {
crate::walk::walk(
&path.join("rustdoc-gui"),
|p, is_dir| !is_dir && p.extension().map_or(true, |e| e != "goml"),
|p, is_dir| !is_dir && p.extension().is_none_or(|e| e != "goml"),
&mut |entry, content| {
for line in content.lines() {
if !line.starts_with("// ") {

View file

@ -88,7 +88,7 @@ pub fn check(librustdoc_path: &Path, tools_path: &Path, src_path: &Path, bad: &m
let mut files_to_check = Vec::new();
walk_no_read(
&[&librustdoc_path.join("html/static/js")],
|path, is_dir| is_dir || !path.extension().is_some_and(|ext| ext == OsStr::new("js")),
|path, is_dir| is_dir || path.extension().is_none_or(|ext| ext != OsStr::new("js")),
&mut |path: &DirEntry| {
files_to_check.push(path.path().into());
},

View file

@ -20,7 +20,7 @@ pub fn check(src_path: &Path, ci_info: &crate::CiInfo, bad: &mut bool) {
return;
}
// Then we check that if `FORMAT_VERSION` was updated, the `Latest feature:` was also updated.
match crate::git_diff(&base_commit, src_path.join("rustdoc-json-types")) {
match crate::git_diff(base_commit, src_path.join("rustdoc-json-types")) {
Some(output) => {
let mut format_version_updated = false;
let mut latest_feature_comment_updated = false;

View file

@ -14,7 +14,7 @@ const TAGS: &[(&str, &str)] = &[("{#", "#}"), ("{%", "%}"), ("{{", "}}")];
pub fn check(librustdoc_path: &Path, bad: &mut bool) {
walk(
&librustdoc_path.join("html/templates"),
|path, is_dir| is_dir || !path.extension().is_some_and(|ext| ext == OsStr::new("html")),
|path, is_dir| is_dir || path.extension().is_none_or(|ext| ext != OsStr::new("html")),
&mut |path: &DirEntry, file_content: &str| {
let mut lines = file_content.lines().enumerate().peekable();
@ -23,7 +23,7 @@ pub fn check(librustdoc_path: &Path, bad: &mut bool) {
if let Some(need_next_line_check) = TAGS.iter().find_map(|(tag, end_tag)| {
// We first check if the line ends with a jinja tag.
if !line.ends_with(end_tag) {
return None;
None
// Then we check if this a comment tag.
} else if *tag != "{#" {
return Some(false);

View file

@ -94,10 +94,9 @@ fn generate_problems<'a>(
letter_digit: &'a FxHashMap<char, char>,
) -> impl Iterator<Item = u32> + 'a {
consts.iter().flat_map(move |const_value| {
let problem =
letter_digit.iter().fold(format!("{:X}", const_value), |acc, (key, value)| {
acc.replace(&value.to_string(), &key.to_string())
});
let problem = letter_digit.iter().fold(format!("{const_value:X}"), |acc, (key, value)| {
acc.replace(&value.to_string(), &key.to_string())
});
let indexes: Vec<usize> = problem
.chars()
.enumerate()
@ -341,7 +340,7 @@ fn is_unexplained_ignore(extension: &str, line: &str) -> bool {
pub fn check(path: &Path, bad: &mut bool) {
fn skip(path: &Path, is_dir: bool) -> bool {
if path.file_name().map_or(false, |name| name.to_string_lossy().starts_with(".#")) {
if path.file_name().is_some_and(|name| name.to_string_lossy().starts_with(".#")) {
// vim or emacs temporary file
return true;
}
@ -358,12 +357,12 @@ pub fn check(path: &Path, bad: &mut bool) {
let extensions = ["rs", "py", "js", "sh", "c", "cpp", "h", "md", "css", "ftl", "goml"];
// NB: don't skip paths without extensions (or else we'll skip all directories and will only check top level files)
if path.extension().map_or(true, |ext| !extensions.iter().any(|e| ext == OsStr::new(e))) {
if path.extension().is_none_or(|ext| !extensions.iter().any(|e| ext == OsStr::new(e))) {
return true;
}
// We only check CSS files in rustdoc.
path.extension().map_or(false, |e| e == "css") && !is_in(path, "src", "librustdoc")
path.extension().is_some_and(|e| e == "css") && !is_in(path, "src", "librustdoc")
}
// This creates a RegexSet as regex contains performance optimizations to be able to deal with these over
@ -435,7 +434,7 @@ pub fn check(path: &Path, bad: &mut bool) {
mut skip_copyright,
mut skip_dbg,
mut skip_odd_backticks,
] = contains_ignore_directives(&path_str, can_contain, &contents, CONFIGURABLE_CHECKS);
] = contains_ignore_directives(&path_str, can_contain, contents, CONFIGURABLE_CHECKS);
let mut leading_new_lines = false;
let mut trailing_new_lines = 0;
let mut lines = 0;

View file

@ -30,10 +30,9 @@ pub fn check(tests_path: &Path, bad: &mut bool) {
comp_vec.push(component);
}
}
} else if directive.starts_with(COMPILE_FLAGS_HEADER) {
let compile_flags = &directive[COMPILE_FLAGS_HEADER.len()..];
} else if let Some(compile_flags) = directive.strip_prefix(COMPILE_FLAGS_HEADER) {
if let Some((_, v)) = compile_flags.split_once("--target") {
let v = v.trim_start_matches(|c| c == ' ' || c == '=');
let v = v.trim_start_matches([' ', '=']);
let v = if v == "{{target}}" { Some((v, v)) } else { v.split_once("-") };
if let Some((arch, _)) = v {
let info = header_map.entry(revision).or_insert(RevisionInfo::default());
@ -57,15 +56,13 @@ pub fn check(tests_path: &Path, bad: &mut bool) {
(None, None) => {}
(Some(_), None) => {
eprintln!(
"{}: revision {} should specify `{}` as it has `--target` set",
file, rev, LLVM_COMPONENTS_HEADER
"{file}: revision {rev} should specify `{LLVM_COMPONENTS_HEADER}` as it has `--target` set"
);
*bad = true;
}
(None, Some(_)) => {
eprintln!(
"{}: revision {} should not specify `{}` as it doesn't need `--target`",
file, rev, LLVM_COMPONENTS_HEADER
"{file}: revision {rev} should not specify `{LLVM_COMPONENTS_HEADER}` as it doesn't need `--target`"
);
*bad = true;
}

View file

@ -38,7 +38,7 @@ pub fn check(tests_path: impl AsRef<Path>, bad: &mut bool) {
let sibling_path = sibling.path();
let Some(ext) = sibling_path.extension().map(OsStr::to_str).flatten() else {
let Some(ext) = sibling_path.extension().and_then(OsStr::to_str) else {
continue;
};
@ -84,7 +84,7 @@ pub fn check(tests_path: impl AsRef<Path>, bad: &mut bool) {
}
});
let Some(test_name) = test.file_stem().map(OsStr::to_str).flatten() else {
let Some(test_name) = test.file_stem().and_then(OsStr::to_str) else {
continue;
};
@ -102,9 +102,9 @@ pub fn check(tests_path: impl AsRef<Path>, bad: &mut bool) {
// of the form: `test-name.revision.compare_mode.extension`, but our only concern is
// `test-name.revision` and `extension`.
for sibling in files_under_inspection.iter().filter(|f| {
f.extension().map(OsStr::to_str).flatten().is_some_and(|ext| EXTENSIONS.contains(&ext))
f.extension().and_then(OsStr::to_str).is_some_and(|ext| EXTENSIONS.contains(&ext))
}) {
let Some(filename) = sibling.file_name().map(OsStr::to_str).flatten() else {
let Some(filename) = sibling.file_name().and_then(OsStr::to_str) else {
continue;
};
@ -131,10 +131,10 @@ pub fn check(tests_path: impl AsRef<Path>, bad: &mut bool) {
}
[_, _] => return,
[_, found_revision, .., extension] => {
if !IGNORES.contains(&found_revision)
if !IGNORES.contains(found_revision)
&& !expected_revisions.contains(*found_revision)
// This is from `//@ stderr-per-bitwidth`
&& !(*extension == "stderr" && ["32bit", "64bit"].contains(&found_revision))
&& !(*extension == "stderr" && ["32bit", "64bit"].contains(found_revision))
{
// Found some unexpected revision-esque component that is not a known
// compare-mode or expected revision.

View file

@ -57,11 +57,9 @@ const EXTENSION_EXCEPTION_PATHS: &[&str] = &[
fn check_entries(tests_path: &Path, bad: &mut bool) {
let mut directories: HashMap<PathBuf, u32> = HashMap::new();
for dir in Walk::new(&tests_path.join("ui")) {
if let Ok(entry) = dir {
let parent = entry.path().parent().unwrap().to_path_buf();
*directories.entry(parent).or_default() += 1;
}
for entry in Walk::new(tests_path.join("ui")).flatten() {
let parent = entry.path().parent().unwrap().to_path_buf();
*directories.entry(parent).or_default() += 1;
}
let (mut max, mut max_issues) = (0, 0);
@ -99,7 +97,7 @@ pub fn check(root_path: &Path, bless: bool, bad: &mut bool) {
"#;
let path = &root_path.join("tests");
check_entries(&path, bad);
check_entries(path, bad);
// the list of files in ui tests that are allowed to start with `issue-XXXX`
// BTreeSet because we would like a stable ordering so --bless works
@ -109,13 +107,12 @@ pub fn check(root_path: &Path, bless: bool, bad: &mut bool) {
.strip_prefix(issues_txt_header)
.unwrap()
.lines()
.map(|line| {
.inspect(|&line| {
if prev_line > line {
is_sorted = false;
}
prev_line = line;
line
})
.collect();
@ -203,7 +200,7 @@ pub fn check(root_path: &Path, bless: bool, bad: &mut bool) {
// so we don't bork things on panic or a contributor using Ctrl+C
let blessed_issues_path = tidy_src.join("issues_blessed.txt");
let mut blessed_issues_txt = fs::File::create(&blessed_issues_path).unwrap();
blessed_issues_txt.write(issues_txt_header.as_bytes()).unwrap();
blessed_issues_txt.write_all(issues_txt_header.as_bytes()).unwrap();
// If we changed paths to use the OS separator, reassert Unix chauvinism for blessing.
for filename in allowed_issue_names.difference(&remaining_issue_names) {
writeln!(blessed_issues_txt, "{filename}").unwrap();

View file

@ -38,7 +38,7 @@ fn dir_entry_is_file(dir_entry: &fs::DirEntry) -> bool {
pub fn collect_unstable_feature_names(features: &Features) -> BTreeSet<String> {
features
.iter()
.filter(|&(_, ref f)| f.level == Status::Unstable)
.filter(|&(_, f)| f.level == Status::Unstable)
.map(|(name, _)| name.replace('_', "-"))
.collect()
}
@ -90,7 +90,7 @@ pub fn check(path: &Path, features: CollectedFeatures, bad: &mut bool) {
let lib_features = features
.lib
.into_iter()
.filter(|&(ref name, _)| !lang_features.contains_key(name))
.filter(|(name, _)| !lang_features.contains_key(name))
.collect::<Features>();
// Library features

View file

@ -66,7 +66,7 @@ pub fn walk_many(
Ok(s) => s,
Err(_) => return, // skip this file
};
f(&entry, &contents_str);
f(entry, contents_str);
});
}
@ -83,7 +83,7 @@ pub(crate) fn walk_no_read(
!skip(e.path(), e.file_type().map(|ft| ft.is_dir()).unwrap_or(false))
});
for entry in walker.build().flatten() {
if entry.file_type().map_or(true, |kind| kind.is_dir() || kind.is_symlink()) {
if entry.file_type().is_none_or(|kind| kind.is_dir() || kind.is_symlink()) {
continue;
}
f(&entry);

View file

@ -26,7 +26,7 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) {
// Check this is the rust-lang/rust x tool installation since it should be
// installed at a path containing `src/tools/x`.
if let Some(path) = iter.next() {
if path.contains(&"src/tools/x") {
if path.contains("src/tools/x") {
let version = version.strip_prefix("v").unwrap();
installed = Some(Version::parse(version).unwrap());
break;
@ -42,15 +42,15 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) {
if let Some(expected) = get_x_wrapper_version(root, cargo) {
if installed < expected {
return println!(
println!(
"Current version of x is {installed}, but the latest version is {expected}\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`"
);
)
}
} else {
return tidy_error!(
tidy_error!(
bad,
"Unable to parse the latest version of `x` at `src/tools/x/Cargo.toml`"
);
)
}
} else {
tidy_error!(bad, "failed to check version of `x`: {}", cargo_list.status)

View file

@ -1,7 +1,7 @@
[package]
name = "tier-check"
version = "0.1.0"
edition = "2021"
edition = "2024"
license = "MIT OR Apache-2.0"
[dependencies]

View file

@ -25,29 +25,27 @@ fn main() {
let doc_targets: HashSet<_> = doc_targets_md
.lines()
.filter(|line| line.starts_with(&['`', '['][..]) && line.contains('|'))
.map(|line| line.split('`').skip(1).next().expect("expected target code span"))
.map(|line| line.split('`').nth(1).expect("expected target code span"))
.collect();
let missing: Vec<_> = target_list.difference(&doc_targets).collect();
let extra: Vec<_> = doc_targets.difference(&target_list).collect();
for target in &missing {
eprintln!(
"error: target `{}` is missing from {}\n\
If this is a new target, please add it to {}.",
target, filename, src
"error: target `{target}` is missing from {filename}\n\
If this is a new target, please add it to {src}."
);
}
for target in &extra {
eprintln!(
"error: target `{}` is in {}, but does not appear in the rustc target list\n\
If the target has been removed, please edit {} and remove the target.",
target, filename, src
"error: target `{target}` is in {filename}, but does not appear in the rustc target list\n\
If the target has been removed, please edit {src} and remove the target."
);
}
// Check target names for unwanted characters like `.` that can cause problems e.g. in Cargo.
// See also Tier 3 target policy.
// If desired, target names can ignore this check.
let ignore_target_names = vec![
let ignore_target_names = [
"thumbv8m.base-none-eabi",
"thumbv8m.main-none-eabi",
"thumbv8m.main-none-eabihf",

View file

@ -16,7 +16,7 @@ error[E0658]: const trait impls are experimental
LL | trait Bar: ~const Foo {}
| ^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -26,7 +26,7 @@ error[E0658]: const trait impls are experimental
LL | const fn foo<T: ~const Bar>(x: &T) {
| ^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

View file

@ -16,7 +16,7 @@ error[E0658]: const trait impls are experimental
7 | trait Bar: ~const Foo {}
| ^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
error[E0658]: const trait impls are experimental
--> const-super-trait.rs:9:17
@ -24,7 +24,7 @@ error[E0658]: const trait impls are experimental
9 | const fn foo<T: ~const Bar>(x: &T) {
| ^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
error: `[const]` can only be applied to `#[const_trait]` traits
--> const-super-trait.rs:7:12

View file

@ -116,12 +116,6 @@ error: malformed `cfi_encoding` attribute input
LL | #[cfi_encoding]
| ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]`
error: malformed `link_ordinal` attribute input
--> $DIR/malformed-attrs.rs:167:5
|
LL | #[link_ordinal]
| ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_ordinal(ordinal)]`
error: malformed `linkage` attribute input
--> $DIR/malformed-attrs.rs:173:5
|
@ -531,6 +525,15 @@ LL | #[unsafe(ffi_pure = 1)]
| | didn't expect any arguments here
| help: must be of the form: `#[ffi_pure]`
error[E0539]: malformed `link_ordinal` attribute input
--> $DIR/malformed-attrs.rs:167:5
|
LL | #[link_ordinal]
| ^^^^^^^^^^^^^^^
| |
| expected this to be a list
| help: must be of the form: `#[link_ordinal(ordinal)]`
error[E0565]: malformed `ffi_const` attribute input
--> $DIR/malformed-attrs.rs:171:5
|

View file

@ -5,7 +5,7 @@ LL | a == b
| ^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
help: consider dereferencing here
@ -31,7 +31,7 @@ LL | a == b
| ^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
help: consider dereferencing here
@ -57,7 +57,7 @@ LL | if l == r {
| ^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
help: consider dereferencing here

View file

@ -63,7 +63,7 @@ error[E0658]: const trait impls are experimental
LL | fn constness() -> impl Sized + const use<> {}
| ^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

View file

@ -1,10 +1,10 @@
#[link(name = "foo")]
extern "C" {
#[link_ordinal("JustMonika")]
//~^ ERROR illegal ordinal format in `link_ordinal`
//~^ ERROR malformed `link_ordinal` attribute input
fn foo();
#[link_ordinal("JustMonika")]
//~^ ERROR illegal ordinal format in `link_ordinal`
//~^ ERROR malformed `link_ordinal` attribute input
static mut imported_variable: i32;
}

View file

@ -1,18 +1,21 @@
error: illegal ordinal format in `link_ordinal`
error[E0539]: malformed `link_ordinal` attribute input
--> $DIR/link-ordinal-invalid-format.rs:3:5
|
LL | #[link_ordinal("JustMonika")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: an unsuffixed integer value, e.g., `1`, is expected
| ^^^^^^^^^^^^^^^------------^^
| | |
| | expected an integer literal here
| help: must be of the form: `#[link_ordinal(ordinal)]`
error: illegal ordinal format in `link_ordinal`
error[E0539]: malformed `link_ordinal` attribute input
--> $DIR/link-ordinal-invalid-format.rs:6:5
|
LL | #[link_ordinal("JustMonika")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: an unsuffixed integer value, e.g., `1`, is expected
| ^^^^^^^^^^^^^^^------------^^
| | |
| | expected an integer literal here
| help: must be of the form: `#[link_ordinal(ordinal)]`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0539`.

View file

@ -1,10 +1,12 @@
#[link(name = "foo")]
extern "C" {
#[link_ordinal()]
//~^ ERROR incorrect number of arguments to `#[link_ordinal]`
//~^ ERROR malformed `link_ordinal` attribute input
//~| NOTE expected a single argument
fn foo();
#[link_ordinal()]
//~^ ERROR incorrect number of arguments to `#[link_ordinal]`
//~^ ERROR malformed `link_ordinal` attribute input
//~| NOTE expected a single argument
static mut imported_variable: i32;
}

View file

@ -1,18 +1,21 @@
error: incorrect number of arguments to `#[link_ordinal]`
error[E0805]: malformed `link_ordinal` attribute input
--> $DIR/link-ordinal-missing-argument.rs:3:5
|
LL | #[link_ordinal()]
| ^^^^^^^^^^^^^^^^^
|
= note: the attribute requires exactly one argument
| ^^^^^^^^^^^^^^--^
| | |
| | expected a single argument here
| help: must be of the form: `#[link_ordinal(ordinal)]`
error: incorrect number of arguments to `#[link_ordinal]`
--> $DIR/link-ordinal-missing-argument.rs:6:5
error[E0805]: malformed `link_ordinal` attribute input
--> $DIR/link-ordinal-missing-argument.rs:7:5
|
LL | #[link_ordinal()]
| ^^^^^^^^^^^^^^^^^
|
= note: the attribute requires exactly one argument
| ^^^^^^^^^^^^^^--^
| | |
| | expected a single argument here
| help: must be of the form: `#[link_ordinal(ordinal)]`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0805`.

View file

@ -1,10 +1,12 @@
#[link(name = "foo")]
extern "C" {
#[link_ordinal(3, 4)]
//~^ ERROR incorrect number of arguments to `#[link_ordinal]`
//~^ ERROR malformed `link_ordinal` attribute input
//~| NOTE expected a single argument
fn foo();
#[link_ordinal(3, 4)]
//~^ ERROR incorrect number of arguments to `#[link_ordinal]`
//~^ ERROR malformed `link_ordinal` attribute input
//~| NOTE expected a single argument
static mut imported_variable: i32;
}

View file

@ -1,18 +1,21 @@
error: incorrect number of arguments to `#[link_ordinal]`
error[E0805]: malformed `link_ordinal` attribute input
--> $DIR/link-ordinal-too-many-arguments.rs:3:5
|
LL | #[link_ordinal(3, 4)]
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: the attribute requires exactly one argument
| ^^^^^^^^^^^^^^------^
| | |
| | expected a single argument here
| help: must be of the form: `#[link_ordinal(ordinal)]`
error: incorrect number of arguments to `#[link_ordinal]`
--> $DIR/link-ordinal-too-many-arguments.rs:6:5
error[E0805]: malformed `link_ordinal` attribute input
--> $DIR/link-ordinal-too-many-arguments.rs:7:5
|
LL | #[link_ordinal(3, 4)]
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: the attribute requires exactly one argument
| ^^^^^^^^^^^^^^------^
| | |
| | expected a single argument here
| help: must be of the form: `#[link_ordinal(ordinal)]`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0805`.

View file

@ -5,7 +5,7 @@ LL | Const.func();
| ^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

View file

@ -13,7 +13,7 @@ LL | Const.func();
| ^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

View file

@ -4,7 +4,7 @@ error[E0658]: const trait impls are experimental
LL | impl const T for S {}
| ^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -14,7 +14,7 @@ error[E0658]: const trait impls are experimental
LL | const fn f<A: [const] T>() {}
| ^^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -24,7 +24,7 @@ error[E0658]: const trait impls are experimental
LL | fn g<A: const T>() {}
| ^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -34,7 +34,7 @@ error[E0658]: const trait impls are experimental
LL | discard! { impl [const] T }
| ^^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -44,7 +44,7 @@ error[E0658]: const trait impls are experimental
LL | discard! { impl const T }
| ^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -54,7 +54,7 @@ error[E0658]: `const_trait` is a temporary placeholder for marking a trait that
LL | #[const_trait]
| ^^^^^^^^^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

View file

@ -13,7 +13,7 @@ error[E0658]: const trait impls are experimental
LL | check! { [const] Trait }
| ^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

View file

@ -26,7 +26,7 @@ error[E0658]: const trait impls are experimental
LL | demo! { impl const Trait }
| ^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -36,7 +36,7 @@ error[E0658]: const trait impls are experimental
LL | demo! { dyn const Trait }
| ^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

View file

@ -5,7 +5,7 @@ LL | Unstable::func();
| ^^^^^^^^^^^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

View file

@ -21,7 +21,7 @@ error: trait implementations cannot be const stable yet
LL | impl const U for u16 {}
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
error: const stability on the impl does not match the const stability on the trait
--> $DIR/staged-api.rs:102:1
@ -46,7 +46,7 @@ error: trait implementations cannot be const stable yet
LL | impl const S for u16 {}
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
error: const stability on the impl does not match the const stability on the trait
--> $DIR/staged-api.rs:117:1

View file

@ -5,7 +5,7 @@ LL | Default::default()
| ^^^^^^^^^^^^^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

View file

@ -16,7 +16,7 @@ error[E0658]: const trait impls are experimental
LL | trait Bar: [const] Foo {}
| ^^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -26,7 +26,7 @@ error[E0658]: const trait impls are experimental
LL | const fn foo<T: [const] Bar>(x: &T) {
| ^^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

View file

@ -16,7 +16,7 @@ error[E0658]: const trait impls are experimental
LL | trait Bar: [const] Foo {}
| ^^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -26,7 +26,7 @@ error[E0658]: const trait impls are experimental
LL | const fn foo<T: [const] Bar>(x: &T) {
| ^^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

View file

@ -4,7 +4,7 @@ error[E0658]: const trait impls are experimental
LL | trait Bar: [const] Foo {}
| ^^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -14,7 +14,7 @@ error[E0658]: const trait impls are experimental
LL | const fn foo<T: [const] Bar>(x: &T) {
| ^^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -24,7 +24,7 @@ error[E0658]: `const_trait` is a temporary placeholder for marking a trait that
LL | #[cfg_attr(any(yyy, yyn, nyy, nyn), const_trait)]
| ^^^^^^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -34,7 +34,7 @@ error[E0658]: `const_trait` is a temporary placeholder for marking a trait that
LL | #[cfg_attr(any(yyy, yny, nyy, nyn), const_trait)]
| ^^^^^^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -45,7 +45,7 @@ LL | x.a();
| ^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

View file

@ -4,7 +4,7 @@ error[E0658]: const trait impls are experimental
LL | trait Bar: [const] Foo {}
| ^^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -14,7 +14,7 @@ error[E0658]: const trait impls are experimental
LL | const fn foo<T: [const] Bar>(x: &T) {
| ^^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -24,7 +24,7 @@ error[E0658]: `const_trait` is a temporary placeholder for marking a trait that
LL | #[cfg_attr(any(yyy, yyn, nyy, nyn), const_trait)]
| ^^^^^^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -34,7 +34,7 @@ error[E0658]: `const_trait` is a temporary placeholder for marking a trait that
LL | #[cfg_attr(any(yyy, yny, nyy, nyn), const_trait)]
| ^^^^^^^^^^^
|
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -45,7 +45,7 @@ LL | x.a();
| ^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date