diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index f61efcf238852..8a41225101e22 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -294,6 +294,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 }, @@ -328,6 +331,9 @@ pub enum AttributeKind { /// Represents `#[non_exhaustive]` NonExhaustive(Span), + /// Represents `#[omit_gdb_pretty_printer_section]` + OmitGdbPrettyPrinterSection, + /// Represents `#[optimize(size|speed)]` Optimize(OptimizeAttr, Span), diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index ad587523e0373..662631e242834 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -40,6 +40,7 @@ impl AttributeKind { Ignore { .. } => No, Inline(..) => No, LinkName { .. } => Yes, + LinkOrdinal { .. } => No, LinkSection { .. } => No, LoopMatch(..) => No, MacroTransparency(..) => Yes, @@ -50,6 +51,7 @@ impl AttributeKind { NoImplicitPrelude(..) => No, NoMangle(..) => No, NonExhaustive(..) => Yes, + OmitGdbPrettyPrinterSection => No, Optimize(..) => No, ParenSugar(..) => No, PassByValue(..) => Yes, diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index bec3a1e8a599b..8d0ead63a8d82 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -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' diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index fdec09edaa150..34d9b04834825 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -334,3 +334,11 @@ impl CombineAttributeParser for TargetFeatureParser { features } } + +pub(crate) struct OmitGdbPrettyPrinterSectionParser; + +impl NoArgsAttributeParser for OmitGdbPrettyPrinterSectionParser { + const PATH: &[Symbol] = &[sym::omit_gdb_pretty_printer_section]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::OmitGdbPrettyPrinterSection; +} diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index 23a8e96482de8..960cebd89259a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -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 NoArgsAttributeParser for StdInternalSymbolParser { const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const CREATE: fn(Span) -> AttributeKind = AttributeKind::StdInternalSymbol; } + +pub(crate) struct LinkOrdinalParser; + +impl SingleAttributeParser for LinkOrdinalParser { + const PATH: &[Symbol] = &[sym::link_ordinal]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const TEMPLATE: AttributeTemplate = template!(List: "ordinal"); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + 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 }) + } +} diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index ec821cb11ce9f..7ca951dc0bbb0 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -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 SingleAttributeParser for RustcLayoutScalarValidRangeStart { const TEMPLATE: AttributeTemplate = template!(List: "start"); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { - 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 SingleAttributeParser for RustcLayoutScalarValidRangeEnd { const TEMPLATE: AttributeTemplate = template!(List: "end"); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { - 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( - cx: &mut AcceptContext<'_, '_, S>, - args: &ArgParser<'_>, -) -> Option> { - 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 SingleAttributeParser for RustcObjectLifetimeDefaultParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index ad48eb1498e11..aea5998b3456b 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -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}; @@ -16,16 +16,16 @@ use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym}; use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser}; use crate::attributes::codegen_attrs::{ - ColdParser, ExportNameParser, NakedParser, NoMangleParser, OptimizeParser, TargetFeatureParser, - TrackCallerParser, UsedParser, + ColdParser, ExportNameParser, NakedParser, NoMangleParser, OmitGdbPrettyPrinterSectionParser, + OptimizeParser, TargetFeatureParser, TrackCallerParser, UsedParser, }; use crate::attributes::confusables::ConfusablesParser; 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, PassByValueParser, PubTransparentParser}; use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; @@ -141,6 +141,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, @@ -171,6 +172,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, @@ -772,3 +774,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( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser<'_>, +) -> Option { + 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) +} diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 28f6786f37fae..8a240639d75a8 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -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 }, diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index 8ed552cfa4f00..ca636a8c9992c 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -159,6 +159,9 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { } GenericArgKind::Type(mut t1) => { + // Scraped constraints may have had inference vars. + t1 = self.infcx.resolve_vars_if_possible(t1); + // Normalize the type we receive from a `TypeOutlives` obligation // in the new trait solver. if infcx.next_trait_solver() { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs index 8f0948b8183bf..49ee96a41d696 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs @@ -1,13 +1,12 @@ // .debug_gdb_scripts binary section. -use rustc_ast::attr; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_codegen_ssa::base::collect_debugger_visualizers_transitive; use rustc_codegen_ssa::traits::*; use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::bug; use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerType; use rustc_session::config::{CrateType, DebugInfo}; -use rustc_span::sym; use crate::builder::Builder; use crate::common::CodegenCx; @@ -87,7 +86,7 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>( pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool { let omit_gdb_pretty_printer_section = - attr::contains_name(cx.tcx.hir_krate_attrs(), sym::omit_gdb_pretty_printer_section); + find_attr!(cx.tcx.hir_krate_attrs(), AttributeKind::OmitGdbPrettyPrinterSection); // To ensure the section `__rustc_debug_gdb_scripts_section__` will not create // ODR violations at link time, this section will not be emitted for rlibs since diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 63e9005da45c2..c7bd6ffd1f27c 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -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` diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 85d01d4f93898..dd49db26689e0 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -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 { tcx.codegen_fn_attrs(opt_trait_item(tcx, def_id)?).alignment } -fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &hir::Attribute) -> Option { - 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, diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index e042fe1f81966..9040915b6af34 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -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 { diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index efd8bde71d76d..e985e04ba3307 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -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. diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 008ef6900089f..d5d49e3188aa8 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -13,7 +13,6 @@ use std::iter; use rustc_index::{Idx, IndexVec}; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::bug; -use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::{self, BoundVar, GenericArg, GenericArgKind, Ty, TyCtxt, TypeFoldable}; use tracing::{debug, instrument}; @@ -23,7 +22,9 @@ use crate::infer::canonical::{ QueryRegionConstraints, QueryResponse, }; use crate::infer::region_constraints::{Constraint, RegionConstraintData}; -use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, InferResult, SubregionOrigin}; +use crate::infer::{ + DefineOpaqueTypes, InferCtxt, InferOk, InferResult, SubregionOrigin, TypeOutlivesConstraint, +}; use crate::traits::query::NoSolution; use crate::traits::{ObligationCause, PredicateObligations, ScrubbedTraitError, TraitEngine}; @@ -117,13 +118,7 @@ impl<'tcx> InferCtxt<'tcx> { let region_obligations = self.take_registered_region_obligations(); debug!(?region_obligations); let region_constraints = self.with_region_constraints(|region_constraints| { - make_query_region_constraints( - tcx, - region_obligations - .iter() - .map(|r_o| (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())), - region_constraints, - ) + make_query_region_constraints(tcx, region_obligations, region_constraints) }); debug!(?region_constraints); @@ -570,7 +565,7 @@ impl<'tcx> InferCtxt<'tcx> { /// creates query region constraints. pub fn make_query_region_constraints<'tcx>( tcx: TyCtxt<'tcx>, - outlives_obligations: impl Iterator, ty::Region<'tcx>, ConstraintCategory<'tcx>)>, + outlives_obligations: Vec>, region_constraints: &RegionConstraintData<'tcx>, ) -> QueryRegionConstraints<'tcx> { let RegionConstraintData { constraints, verifys } = region_constraints; @@ -599,8 +594,11 @@ pub fn make_query_region_constraints<'tcx>( }; (constraint, origin.to_constraint_category()) }) - .chain(outlives_obligations.map(|(ty, r, constraint_category)| { - (ty::OutlivesPredicate(ty.into(), r), constraint_category) + .chain(outlives_obligations.into_iter().map(|obl| { + ( + ty::OutlivesPredicate(obl.sup_type.into(), obl.sub_region), + obl.origin.to_constraint_category(), + ) })) .collect(); diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index f272052aaa544..43504bd77c18b 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -166,6 +166,7 @@ impl<'tcx> InferCtxt<'tcx> { /// Trait queries just want to pass back type obligations "as is" pub fn take_registered_region_obligations(&self) -> Vec> { + assert!(!self.in_snapshot(), "cannot take registered region obligations in a snapshot"); std::mem::take(&mut self.inner.borrow_mut().region_obligations) } diff --git a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs index 6193f35f3eb60..34e649afedc69 100644 --- a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs +++ b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs @@ -1,3 +1,4 @@ +use std::assert_matches::assert_matches; use std::marker::PhantomData; use rustc_data_structures::undo_log::{Rollback, UndoLogs}; @@ -73,7 +74,8 @@ impl<'tcx> Rollback> for InferCtxtInner<'tcx> { } UndoLog::ProjectionCache(undo) => self.projection_cache.reverse(undo), UndoLog::PushTypeOutlivesConstraint => { - self.region_obligations.pop(); + let popped = self.region_obligations.pop(); + assert_matches!(popped, Some(_), "pushed region constraint but could not pop it"); } } } diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index f10d71f4c6540..4d276f814ef25 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -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 }); } } diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index bb5c1e0e653a7..f134488933552 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -305,11 +305,13 @@ pub fn check_builtin_meta_item( | sym::naked | sym::no_mangle | sym::non_exhaustive + | sym::omit_gdb_pretty_printer_section | sym::path | sym::ignore | sym::must_use | sym::track_caller | sym::link_name + | sym::link_ordinal | sym::export_name | sym::rustc_macro_transparency | sym::link_section diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 46c21dcf67b19..3418d997b834f 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -17,6 +17,10 @@ passes_align_attr_application = `#[align(...)]` should be applied to a function item .label = not a function item +passes_align_on_fields = + attribute should be applied to a function or method + .warn = {-passes_previously_accepted} + passes_align_should_be_repr_align = `#[align(...)]` is not supported on {$item} items .suggestion = use `#[repr(align(...))]` instead @@ -700,7 +704,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 for more information + .note = see issue #143874 for more information passes_transparent_incompatible = transparent {$target} cannot have other repr hints diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index e7af615a715f7..30a8d334f1790 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -45,6 +45,7 @@ use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs}; use rustc_trait_selection::traits::ObligationCtxt; use tracing::debug; +use crate::errors::AlignOnFields; use crate::{errors, fluent_generated as fluent}; #[derive(LintDiagnostic)] @@ -199,8 +200,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::ExportName { span: attr_span, .. }) => { self.check_export_name(hir_id, *attr_span, span, target) } - Attribute::Parsed(AttributeKind::Align { align, span: repr_span }) => { - self.check_align(span, target, *align, *repr_span) + Attribute::Parsed(AttributeKind::Align { align, span: attr_span }) => { + self.check_align(span, hir_id, target, *align, *attr_span) } Attribute::Parsed(AttributeKind::LinkSection { span: attr_span, .. }) => { self.check_link_section(hir_id, *attr_span, span, target) @@ -242,7 +243,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { AttributeKind::BodyStability { .. } | AttributeKind::ConstStabilityIndirect | AttributeKind::MacroTransparency(_) - | AttributeKind::Dummy, + | AttributeKind::Dummy + | AttributeKind::OmitGdbPrettyPrinterSection, ) => { /* do nothing */ } Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => { self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target) @@ -250,6 +252,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) } @@ -327,7 +332,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) @@ -371,7 +377,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // need to be fixed | sym::cfi_encoding // FIXME(cfi_encoding) | sym::pointee // FIXME(derive_coerce_pointee) - | sym::omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section) | sym::instruction_set // broken on stable!!! | sym::windows_subsystem // broken on stable!!! | sym::patchable_function_entry // FIXME(patchable_function_entry) @@ -1944,22 +1949,37 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } /// Checks if the `#[align]` attributes on `item` are valid. - fn check_align(&self, span: Span, target: Target, align: Align, repr_span: Span) { + fn check_align( + &self, + span: Span, + hir_id: HirId, + target: Target, + align: Align, + attr_span: Span, + ) { match target { Target::Fn | Target::Method(_) | Target::ForeignFn => {} + Target::Field => { + self.tcx.emit_node_span_lint( + UNUSED_ATTRIBUTES, + hir_id, + attr_span, + AlignOnFields { span }, + ); + } Target::Struct | Target::Union | Target::Enum => { self.dcx().emit_err(errors::AlignShouldBeReprAlign { - span: repr_span, + span: attr_span, item: target.name(), align_bytes: align.bytes(), }); } _ => { - self.dcx().emit_err(errors::AlignAttrApplication { hint_span: repr_span, span }); + self.dcx().emit_err(errors::AlignAttrApplication { hint_span: attr_span, span }); } } - self.check_align_value(align, repr_span); + self.check_align_value(align, attr_span); } /// Checks if the `#[repr]` attributes on `item` are valid. @@ -2260,11 +2280,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 }); } } } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 4ad615a2abfc8..093a2b38804fd 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -604,6 +604,14 @@ pub(crate) struct NoMangle { pub span: Span, } +#[derive(LintDiagnostic)] +#[diag(passes_align_on_fields)] +#[warning] +pub(crate) struct AlignOnFields { + #[label] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(passes_repr_conflicting, code = E0566)] pub(crate) struct ReprConflicting { diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs index 93d164e7d01f8..3b2b2b3e948d8 100644 --- a/compiler/rustc_passes/src/weak_lang_items.rs +++ b/compiler/rustc_passes/src/weak_lang_items.rs @@ -13,6 +13,14 @@ use crate::errors::{ MissingLangItem, MissingPanicHandler, PanicUnwindWithoutStd, UnknownExternLangItem, }; +fn has_personality(tcx: TyCtxt<'_>) -> bool { + // MSVC and wasm targets (except emscripten) have their own personalities + tcx.sess.target.is_like_msvc + || (tcx.sess.target.is_like_wasm + && (tcx.sess.target.os != "emscripten" + || tcx.sess.opts.unstable_opts.emscripten_wasm_eh)) +} + /// Checks the crate for usage of weak lang items, returning a vector of all the /// lang items required by this crate, but not defined yet. pub(crate) fn check_crate( @@ -23,7 +31,7 @@ pub(crate) fn check_crate( // These are never called by user code, they're generated by the compiler. // They will never implicitly be added to the `missing` array unless we do // so here. - if items.eh_personality().is_none() { + if items.eh_personality().is_none() && !has_personality(tcx) { items.missing.push(LangItem::EhPersonality); } if tcx.sess.target.os == "emscripten" diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index d22529d56a468..1a24254d57fbe 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -213,13 +213,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< // inside of a `probe` whenever we have multiple choices inside of the solver. let region_obligations = self.0.inner.borrow().region_obligations().to_owned(); let region_constraints = self.0.with_region_constraints(|region_constraints| { - make_query_region_constraints( - self.tcx, - region_obligations - .iter() - .map(|r_o| (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())), - region_constraints, - ) + make_query_region_constraints(self.tcx, region_obligations, region_constraints) }); let mut seen = FxHashSet::default(); diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs index 18010603286d1..3b549244431d2 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs @@ -103,10 +103,7 @@ where let region_constraint_data = infcx.take_and_reset_region_constraints(); let region_constraints = query_response::make_query_region_constraints( infcx.tcx, - region_obligations - .iter() - .map(|r_o| (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())) - .map(|(ty, r, cc)| (infcx.resolve_vars_if_possible(ty), r, cc)), + region_obligations, ®ion_constraint_data, ); diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 58baa07bc1741..a189c00a6b61d 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -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] diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 9dac58bac4f88..1df6ab672eaaa 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -3895,7 +3895,7 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for Vec { } #[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 Vec { /// Creates an empty `Vec`. /// diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index c53a2b2beb4cc..d6d1bf2effae2 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -333,7 +333,7 @@ impl Clone for Cell { } #[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 Cell { /// Creates a `Cell`, with the `Default` value for T. #[inline] @@ -1324,7 +1324,7 @@ impl Clone for RefCell { } #[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 RefCell { /// Creates a `RefCell`, with the `Default` value for T. #[inline] @@ -2332,7 +2332,7 @@ impl UnsafeCell { } #[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 const Default for UnsafeCell { /// Creates an `UnsafeCell`, with the `Default` value for T. fn default() -> UnsafeCell { @@ -2437,7 +2437,7 @@ impl SyncUnsafeCell { } #[unstable(feature = "sync_unsafe_cell", issue = "95439")] -#[rustc_const_unstable(feature = "const_default", issue = "67792")] +#[rustc_const_unstable(feature = "const_default", issue = "143894")] impl const Default for SyncUnsafeCell { /// Creates an `SyncUnsafeCell`, with the `Default` value for T. fn default() -> SyncUnsafeCell { diff --git a/library/core/src/default.rs b/library/core/src/default.rs index 4d108b0c18ed3..897267968aacc 100644 --- a/library/core/src/default.rs +++ b/library/core/src/default.rs @@ -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] diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index e1381ace44151..7d41ae45093ea 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -358,7 +358,7 @@ macro_rules! impl_Display { } #[cfg(feature = "optimize_for_size")] { - offset = _inner_slow_integer_to_str(self.unsigned_abs().$conv_fn(), &mut buf.buf); + offset = ${concat(_inner_slow_integer_to_str, $gen_name)}(self.unsigned_abs().$conv_fn(), &mut buf.buf); } // Only difference between signed and unsigned are these 4 lines. if self < 0 { @@ -401,7 +401,7 @@ macro_rules! impl_Display { } #[cfg(feature = "optimize_for_size")] { - offset = _inner_slow_integer_to_str(self.$conv_fn(), &mut buf.buf); + offset = ${concat(_inner_slow_integer_to_str, $gen_name)}(self.$conv_fn(), &mut buf.buf); } // SAFETY: Starting from `offset`, all elements of the slice have been set. unsafe { slice_buffer_to_str(&buf.buf, offset) } @@ -412,7 +412,7 @@ macro_rules! impl_Display { )* #[cfg(feature = "optimize_for_size")] - fn _inner_slow_integer_to_str(mut n: $u, buf: &mut [MaybeUninit::]) -> usize { + fn ${concat(_inner_slow_integer_to_str, $gen_name)}(mut n: $u, buf: &mut [MaybeUninit::]) -> usize { let mut curr = buf.len(); // SAFETY: To show that it's OK to copy into `buf_ptr`, notice that at the beginning @@ -437,7 +437,7 @@ macro_rules! impl_Display { const MAX_DEC_N: usize = $u::MAX.ilog(10) as usize + 1; let mut buf = [MaybeUninit::::uninit(); MAX_DEC_N]; - let offset = _inner_slow_integer_to_str(n, &mut buf); + let offset = ${concat(_inner_slow_integer_to_str, $gen_name)}(n, &mut buf); // SAFETY: Starting from `offset`, all elements of the slice have been set. let buf_slice = unsafe { slice_buffer_to_str(&buf, offset) }; f.pad_integral(is_nonnegative, "", buf_slice) diff --git a/library/core/src/io/borrowed_buf.rs b/library/core/src/io/borrowed_buf.rs index 854e03cf18279..b5dfe6dbd71e1 100644 --- a/library/core/src/io/borrowed_buf.rs +++ b/library/core/src/io/borrowed_buf.rs @@ -69,6 +69,23 @@ impl<'data> From<&'data mut [MaybeUninit]> for BorrowedBuf<'data> { } } +/// Creates a new `BorrowedBuf` from a cursor. +/// +/// Use `BorrowedCursor::with_unfilled_buf` instead for a safer alternative. +impl<'data> From> for BorrowedBuf<'data> { + #[inline] + fn from(mut buf: BorrowedCursor<'data>) -> BorrowedBuf<'data> { + let init = buf.init_mut().len(); + BorrowedBuf { + // SAFETY: no initialized byte is ever uninitialized as per + // `BorrowedBuf`'s invariant + buf: unsafe { buf.buf.buf.get_unchecked_mut(buf.buf.filled..) }, + filled: 0, + init, + } + } +} + impl<'data> BorrowedBuf<'data> { /// Returns the total capacity of the buffer. #[inline] @@ -353,4 +370,38 @@ impl<'a> BorrowedCursor<'a> { } self.buf.filled += buf.len(); } + + /// Runs the given closure with a `BorrowedBuf` containing the unfilled part + /// of the cursor. + /// + /// This enables inspecting what was written to the cursor. + /// + /// # Panics + /// + /// Panics if the `BorrowedBuf` given to the closure is replaced by another + /// one. + pub fn with_unfilled_buf(&mut self, f: impl FnOnce(&mut BorrowedBuf<'_>) -> T) -> T { + let mut buf = BorrowedBuf::from(self.reborrow()); + let prev_ptr = buf.buf as *const _; + let res = f(&mut buf); + + // Check that the caller didn't replace the `BorrowedBuf`. + // This is necessary for the safety of the code below: if the check wasn't + // there, one could mark some bytes as initialized even though there aren't. + assert!(core::ptr::addr_eq(prev_ptr, buf.buf)); + + let filled = buf.filled; + let init = buf.init; + + // Update `init` and `filled` fields with what was written to the buffer. + // `self.buf.filled` was the starting length of the `BorrowedBuf`. + // + // SAFETY: These amounts of bytes were initialized/filled in the `BorrowedBuf`, + // and therefore they are initialized/filled in the cursor too, because the + // buffer wasn't replaced. + self.buf.init = self.buf.filled + init; + self.buf.filled += filled; + + res + } } diff --git a/library/core/src/iter/sources/empty.rs b/library/core/src/iter/sources/empty.rs index 309962ab70ce1..1844c76e5df7e 100644 --- a/library/core/src/iter/sources/empty.rs +++ b/library/core/src/iter/sources/empty.rs @@ -81,7 +81,7 @@ impl Clone for Empty { // 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 const Default for Empty { fn default() -> Empty { Empty(marker::PhantomData) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 2f701171505c7..e08edde3b38bb 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -160,6 +160,7 @@ #![feature(lang_items)] #![feature(link_llvm_intrinsics)] #![feature(macro_metavar_expr)] +#![feature(macro_metavar_expr_concat)] #![feature(marker_trait_attr)] #![feature(min_specialization)] #![feature(multiple_supertrait_upcastable)] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 6531d3ec766a9..45277a1c82d3a 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -863,7 +863,7 @@ impl Clone for PhantomData { } #[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 PhantomData { fn default() -> Self { Self diff --git a/library/core/src/num/wrapping.rs b/library/core/src/num/wrapping.rs index 55fa91d0b9f49..c460f38bd2e4d 100644 --- a/library/core/src/num/wrapping.rs +++ b/library/core/src/num/wrapping.rs @@ -94,9 +94,9 @@ macro_rules! sh_impl_signed { #[inline] fn shl(self, other: $f) -> Wrapping<$t> { if other < 0 { - Wrapping(self.0.wrapping_shr((-other & self::shift_max::$t as $f) as u32)) + Wrapping(self.0.wrapping_shr(-other as u32)) } else { - Wrapping(self.0.wrapping_shl((other & self::shift_max::$t as $f) as u32)) + Wrapping(self.0.wrapping_shl(other as u32)) } } } @@ -119,9 +119,9 @@ macro_rules! sh_impl_signed { #[inline] fn shr(self, other: $f) -> Wrapping<$t> { if other < 0 { - Wrapping(self.0.wrapping_shl((-other & self::shift_max::$t as $f) as u32)) + Wrapping(self.0.wrapping_shl(-other as u32)) } else { - Wrapping(self.0.wrapping_shr((other & self::shift_max::$t as $f) as u32)) + Wrapping(self.0.wrapping_shr(other as u32)) } } } @@ -147,7 +147,7 @@ macro_rules! sh_impl_unsigned { #[inline] fn shl(self, other: $f) -> Wrapping<$t> { - Wrapping(self.0.wrapping_shl((other & self::shift_max::$t as $f) as u32)) + Wrapping(self.0.wrapping_shl(other as u32)) } } forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f, @@ -168,7 +168,7 @@ macro_rules! sh_impl_unsigned { #[inline] fn shr(self, other: $f) -> Wrapping<$t> { - Wrapping(self.0.wrapping_shr((other & self::shift_max::$t as $f) as u32)) + Wrapping(self.0.wrapping_shr(other as u32)) } } forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f, @@ -1052,39 +1052,3 @@ macro_rules! wrapping_int_impl_unsigned { } wrapping_int_impl_unsigned! { usize u8 u16 u32 u64 u128 } - -mod shift_max { - #![allow(non_upper_case_globals)] - - #[cfg(target_pointer_width = "16")] - mod platform { - pub(crate) const usize: u32 = super::u16; - pub(crate) const isize: u32 = super::i16; - } - - #[cfg(target_pointer_width = "32")] - mod platform { - pub(crate) const usize: u32 = super::u32; - pub(crate) const isize: u32 = super::i32; - } - - #[cfg(target_pointer_width = "64")] - mod platform { - pub(crate) const usize: u32 = super::u64; - pub(crate) const isize: u32 = super::i64; - } - - pub(super) const i8: u32 = (1 << 3) - 1; - pub(super) const i16: u32 = (1 << 4) - 1; - pub(super) const i32: u32 = (1 << 5) - 1; - pub(super) const i64: u32 = (1 << 6) - 1; - pub(super) const i128: u32 = (1 << 7) - 1; - pub(super) use self::platform::isize; - - pub(super) const u8: u32 = i8; - pub(super) const u16: u32 = i16; - pub(super) const u32: u32 = i32; - pub(super) const u64: u32 = i64; - pub(super) const u128: u32 = i128; - pub(super) use self::platform::usize; -} diff --git a/library/core/src/ops/function.rs b/library/core/src/ops/function.rs index 763b60d88e510..efc751a094d12 100644 --- a/library/core/src/ops/function.rs +++ b/library/core/src/ops/function.rs @@ -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: FnMut { /// Performs the call operation. #[unstable(feature = "fn_traits", issue = "29625")] @@ -161,7 +161,7 @@ pub trait Fn: FnMut { #[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: FnOnce { /// Performs the call operation. #[unstable(feature = "fn_traits", issue = "29625")] @@ -241,7 +241,7 @@ pub trait FnMut: FnOnce { #[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 { /// 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 const Fn for &F where F: ~const Fn, @@ -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 const FnMut for &F where F: ~const Fn, @@ -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 const FnOnce for &F where F: ~const Fn, @@ -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 const FnMut for &mut F where F: ~const FnMut, @@ -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 const FnOnce for &mut F where F: ~const FnMut, diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 4ede273feda9b..9f432758a66f6 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2112,7 +2112,7 @@ where impl crate::clone::UseCloned for Option 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 const Default for Option { /// Returns [`None`][Option::None]. /// diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 2c77c55745b46..5bd80149a1d6e 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1081,13 +1081,11 @@ mod prim_str {} /// * [`Debug`] /// * [`Default`] /// * [`Hash`] -/// * [`Random`] /// * [`From<[T; N]>`][from] /// /// [from]: convert::From /// [`Debug`]: fmt::Debug /// [`Hash`]: hash::Hash -/// [`Random`]: random::Random /// /// The following traits are implemented for tuples of any length. These traits have /// implementations that are automatically generated by the compiler, so are not limited by diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs index 304cde05af9bc..6d473a4bd5663 100644 --- a/library/core/src/ptr/alignment.rs +++ b/library/core/src/ptr/alignment.rs @@ -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 diff --git a/library/core/src/random.rs b/library/core/src/random.rs index 051fe26086389..8a51fb289d8f3 100644 --- a/library/core/src/random.rs +++ b/library/core/src/random.rs @@ -1,48 +1,46 @@ //! Random value generation. -//! -//! The [`Random`] trait allows generating a random value for a type using a -//! given [`RandomSource`]. + +use crate::range::RangeFull; /// A source of randomness. #[unstable(feature = "random", issue = "130703")] pub trait RandomSource { /// Fills `bytes` with random bytes. + /// + /// Note that calling `fill_bytes` multiple times is not equivalent to calling `fill_bytes` once + /// with a larger buffer. A `RandomSource` is allowed to return different bytes for those two + /// cases. For instance, this allows a `RandomSource` to generate a word at a time and throw + /// part of it away if not needed. fn fill_bytes(&mut self, bytes: &mut [u8]); } -/// A trait for getting a random value for a type. -/// -/// **Warning:** Be careful when manipulating random values! The -/// [`random`](Random::random) method on integers samples them with a uniform -/// distribution, so a value of 1 is just as likely as [`i32::MAX`]. By using -/// modulo operations, some of the resulting values can become more likely than -/// others. Use audited crates when in doubt. +/// A trait representing a distribution of random values for a type. #[unstable(feature = "random", issue = "130703")] -pub trait Random: Sized { - /// Generates a random value. - fn random(source: &mut (impl RandomSource + ?Sized)) -> Self; +pub trait Distribution { + /// Samples a random value from the distribution, using the specified random source. + fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> T; +} + +impl> Distribution for &DT { + fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> T { + (*self).sample(source) + } } -impl Random for bool { - fn random(source: &mut (impl RandomSource + ?Sized)) -> Self { - u8::random(source) & 1 == 1 +impl Distribution for RangeFull { + fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> bool { + let byte: u8 = RangeFull.sample(source); + byte & 1 == 1 } } macro_rules! impl_primitive { ($t:ty) => { - impl Random for $t { - /// Generates a random value. - /// - /// **Warning:** Be careful when manipulating the resulting value! This - /// method samples according to a uniform distribution, so a value of 1 is - /// just as likely as [`MAX`](Self::MAX). By using modulo operations, some - /// values can become more likely than others. Use audited crates when in - /// doubt. - fn random(source: &mut (impl RandomSource + ?Sized)) -> Self { - let mut bytes = (0 as Self).to_ne_bytes(); + impl Distribution<$t> for RangeFull { + fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> $t { + let mut bytes = (0 as $t).to_ne_bytes(); source.fill_bytes(&mut bytes); - Self::from_ne_bytes(bytes) + <$t>::from_ne_bytes(bytes) } } }; diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 58b7e9a9fdf4a..abcba5a621e23 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -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 const Default for &[T] { /// Creates an empty slice. fn default() -> Self { @@ -5201,7 +5201,7 @@ impl 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 const Default for &mut [T] { /// Creates a mutable empty slice. fn default() -> Self { diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 32a2298817538..fba3436496e3d 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -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] diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs index 9cf08e74ff692..23a0a6877df77 100644 --- a/library/core/src/tuple.rs +++ b/library/core/src/tuple.rs @@ -3,7 +3,6 @@ use crate::cmp::Ordering::{self, *}; use crate::marker::{ConstParamTy_, StructuralPartialEq, UnsizedConstParamTy}; use crate::ops::ControlFlow::{self, Break, Continue}; -use crate::random::{Random, RandomSource}; // Recursive macro for implementing n-ary tuple functions and operations // @@ -131,16 +130,6 @@ macro_rules! tuple_impls { } } - maybe_tuple_doc! { - $($T)+ @ - #[unstable(feature = "random", issue = "130703")] - impl<$($T: Random),+> Random for ($($T,)+) { - fn random(source: &mut (impl RandomSource + ?Sized)) -> Self { - ($({ let x: $T = Random::random(source); x},)+) - } - } - } - maybe_tuple_doc! { $($T)+ @ #[stable(feature = "array_tuple_conv", since = "1.71.0")] diff --git a/library/coretests/tests/floats/f128.rs b/library/coretests/tests/floats/f128.rs index 38df09a91c103..36d6a20a94427 100644 --- a/library/coretests/tests/floats/f128.rs +++ b/library/coretests/tests/floats/f128.rs @@ -1,9 +1,7 @@ // FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy #![cfg(target_has_reliable_f128)] -use core::ops::{Add, Div, Mul, Sub}; use std::f128::consts; -use std::num::FpCategory as Fp; use super::{assert_approx_eq, assert_biteq}; @@ -38,160 +36,9 @@ const NAN_MASK1: u128 = 0x0000aaaaaaaaaaaaaaaaaaaaaaaaaaaa; /// Second pattern over the mantissa const NAN_MASK2: u128 = 0x00005555555555555555555555555555; -#[test] -fn test_num_f128() { - // FIXME(f16_f128): replace with a `test_num` call once the required `fmodl`/`fmodf128` - // function is available on all platforms. - let ten = 10f128; - let two = 2f128; - assert_biteq!(ten.add(two), ten + two); - assert_biteq!(ten.sub(two), ten - two); - assert_biteq!(ten.mul(two), ten * two); - assert_biteq!(ten.div(two), ten / two); - #[cfg(any(miri, target_has_reliable_f128_math))] - assert_biteq!(core::ops::Rem::rem(ten, two), ten % two); -} - // FIXME(f16_f128,miri): many of these have to be disabled since miri does not yet support // the intrinsics. -#[test] -fn test_infinity() { - let inf: f128 = f128::INFINITY; - assert!(inf.is_infinite()); - assert!(!inf.is_finite()); - assert!(inf.is_sign_positive()); - assert!(!inf.is_sign_negative()); - assert!(!inf.is_nan()); - assert!(!inf.is_normal()); - assert_eq!(Fp::Infinite, inf.classify()); -} - -#[test] -fn test_neg_infinity() { - let neg_inf: f128 = f128::NEG_INFINITY; - assert!(neg_inf.is_infinite()); - assert!(!neg_inf.is_finite()); - assert!(!neg_inf.is_sign_positive()); - assert!(neg_inf.is_sign_negative()); - assert!(!neg_inf.is_nan()); - assert!(!neg_inf.is_normal()); - assert_eq!(Fp::Infinite, neg_inf.classify()); -} - -#[test] -fn test_zero() { - let zero: f128 = 0.0f128; - assert_biteq!(0.0, zero); - assert!(!zero.is_infinite()); - assert!(zero.is_finite()); - assert!(zero.is_sign_positive()); - assert!(!zero.is_sign_negative()); - assert!(!zero.is_nan()); - assert!(!zero.is_normal()); - assert_eq!(Fp::Zero, zero.classify()); -} - -#[test] -fn test_neg_zero() { - let neg_zero: f128 = -0.0; - assert_eq!(0.0, neg_zero); - assert_biteq!(-0.0, neg_zero); - assert!(!neg_zero.is_infinite()); - assert!(neg_zero.is_finite()); - assert!(!neg_zero.is_sign_positive()); - assert!(neg_zero.is_sign_negative()); - assert!(!neg_zero.is_nan()); - assert!(!neg_zero.is_normal()); - assert_eq!(Fp::Zero, neg_zero.classify()); -} - -#[test] -fn test_one() { - let one: f128 = 1.0f128; - assert_biteq!(1.0, one); - assert!(!one.is_infinite()); - assert!(one.is_finite()); - assert!(one.is_sign_positive()); - assert!(!one.is_sign_negative()); - assert!(!one.is_nan()); - assert!(one.is_normal()); - assert_eq!(Fp::Normal, one.classify()); -} - -#[test] -fn test_is_nan() { - let nan: f128 = f128::NAN; - let inf: f128 = f128::INFINITY; - let neg_inf: f128 = f128::NEG_INFINITY; - assert!(nan.is_nan()); - assert!(!0.0f128.is_nan()); - assert!(!5.3f128.is_nan()); - assert!(!(-10.732f128).is_nan()); - assert!(!inf.is_nan()); - assert!(!neg_inf.is_nan()); -} - -#[test] -fn test_is_infinite() { - let nan: f128 = f128::NAN; - let inf: f128 = f128::INFINITY; - let neg_inf: f128 = f128::NEG_INFINITY; - assert!(!nan.is_infinite()); - assert!(inf.is_infinite()); - assert!(neg_inf.is_infinite()); - assert!(!0.0f128.is_infinite()); - assert!(!42.8f128.is_infinite()); - assert!(!(-109.2f128).is_infinite()); -} - -#[test] -fn test_is_finite() { - let nan: f128 = f128::NAN; - let inf: f128 = f128::INFINITY; - let neg_inf: f128 = f128::NEG_INFINITY; - assert!(!nan.is_finite()); - assert!(!inf.is_finite()); - assert!(!neg_inf.is_finite()); - assert!(0.0f128.is_finite()); - assert!(42.8f128.is_finite()); - assert!((-109.2f128).is_finite()); -} - -#[test] -fn test_is_normal() { - let nan: f128 = f128::NAN; - let inf: f128 = f128::INFINITY; - let neg_inf: f128 = f128::NEG_INFINITY; - let zero: f128 = 0.0f128; - let neg_zero: f128 = -0.0; - assert!(!nan.is_normal()); - assert!(!inf.is_normal()); - assert!(!neg_inf.is_normal()); - assert!(!zero.is_normal()); - assert!(!neg_zero.is_normal()); - assert!(1f128.is_normal()); - assert!(1e-4931f128.is_normal()); - assert!(!1e-4932f128.is_normal()); -} - -#[test] -fn test_classify() { - let nan: f128 = f128::NAN; - let inf: f128 = f128::INFINITY; - let neg_inf: f128 = f128::NEG_INFINITY; - let zero: f128 = 0.0f128; - let neg_zero: f128 = -0.0; - assert_eq!(nan.classify(), Fp::Nan); - assert_eq!(inf.classify(), Fp::Infinite); - assert_eq!(neg_inf.classify(), Fp::Infinite); - assert_eq!(zero.classify(), Fp::Zero); - assert_eq!(neg_zero.classify(), Fp::Zero); - assert_eq!(1f128.classify(), Fp::Normal); - assert_eq!(1e-4931f128.classify(), Fp::Normal); - assert_eq!(1e-4932f128.classify(), Fp::Subnormal); -} - #[test] #[cfg(any(miri, target_has_reliable_f128_math))] fn test_abs() { diff --git a/library/coretests/tests/floats/f16.rs b/library/coretests/tests/floats/f16.rs index f6749d796cca9..351c008a37bab 100644 --- a/library/coretests/tests/floats/f16.rs +++ b/library/coretests/tests/floats/f16.rs @@ -2,7 +2,6 @@ #![cfg(target_has_reliable_f16)] use std::f16::consts; -use std::num::FpCategory as Fp; use super::{assert_approx_eq, assert_biteq}; @@ -43,151 +42,9 @@ const NAN_MASK1: u16 = 0x02aa; /// Second pattern over the mantissa const NAN_MASK2: u16 = 0x0155; -#[test] -fn test_num_f16() { - super::test_num(10f16, 2f16); -} - // FIXME(f16_f128,miri): many of these have to be disabled since miri does not yet support // the intrinsics. -#[test] -fn test_infinity() { - let inf: f16 = f16::INFINITY; - assert!(inf.is_infinite()); - assert!(!inf.is_finite()); - assert!(inf.is_sign_positive()); - assert!(!inf.is_sign_negative()); - assert!(!inf.is_nan()); - assert!(!inf.is_normal()); - assert_eq!(Fp::Infinite, inf.classify()); -} - -#[test] -fn test_neg_infinity() { - let neg_inf: f16 = f16::NEG_INFINITY; - assert!(neg_inf.is_infinite()); - assert!(!neg_inf.is_finite()); - assert!(!neg_inf.is_sign_positive()); - assert!(neg_inf.is_sign_negative()); - assert!(!neg_inf.is_nan()); - assert!(!neg_inf.is_normal()); - assert_eq!(Fp::Infinite, neg_inf.classify()); -} - -#[test] -fn test_zero() { - let zero: f16 = 0.0f16; - assert_biteq!(0.0, zero); - assert!(!zero.is_infinite()); - assert!(zero.is_finite()); - assert!(zero.is_sign_positive()); - assert!(!zero.is_sign_negative()); - assert!(!zero.is_nan()); - assert!(!zero.is_normal()); - assert_eq!(Fp::Zero, zero.classify()); -} - -#[test] -fn test_neg_zero() { - let neg_zero: f16 = -0.0; - assert_eq!(0.0, neg_zero); - assert_biteq!(-0.0, neg_zero); - assert!(!neg_zero.is_infinite()); - assert!(neg_zero.is_finite()); - assert!(!neg_zero.is_sign_positive()); - assert!(neg_zero.is_sign_negative()); - assert!(!neg_zero.is_nan()); - assert!(!neg_zero.is_normal()); - assert_eq!(Fp::Zero, neg_zero.classify()); -} - -#[test] -fn test_one() { - let one: f16 = 1.0f16; - assert_biteq!(1.0, one); - assert!(!one.is_infinite()); - assert!(one.is_finite()); - assert!(one.is_sign_positive()); - assert!(!one.is_sign_negative()); - assert!(!one.is_nan()); - assert!(one.is_normal()); - assert_eq!(Fp::Normal, one.classify()); -} - -#[test] -fn test_is_nan() { - let nan: f16 = f16::NAN; - let inf: f16 = f16::INFINITY; - let neg_inf: f16 = f16::NEG_INFINITY; - assert!(nan.is_nan()); - assert!(!0.0f16.is_nan()); - assert!(!5.3f16.is_nan()); - assert!(!(-10.732f16).is_nan()); - assert!(!inf.is_nan()); - assert!(!neg_inf.is_nan()); -} - -#[test] -fn test_is_infinite() { - let nan: f16 = f16::NAN; - let inf: f16 = f16::INFINITY; - let neg_inf: f16 = f16::NEG_INFINITY; - assert!(!nan.is_infinite()); - assert!(inf.is_infinite()); - assert!(neg_inf.is_infinite()); - assert!(!0.0f16.is_infinite()); - assert!(!42.8f16.is_infinite()); - assert!(!(-109.2f16).is_infinite()); -} - -#[test] -fn test_is_finite() { - let nan: f16 = f16::NAN; - let inf: f16 = f16::INFINITY; - let neg_inf: f16 = f16::NEG_INFINITY; - assert!(!nan.is_finite()); - assert!(!inf.is_finite()); - assert!(!neg_inf.is_finite()); - assert!(0.0f16.is_finite()); - assert!(42.8f16.is_finite()); - assert!((-109.2f16).is_finite()); -} - -#[test] -fn test_is_normal() { - let nan: f16 = f16::NAN; - let inf: f16 = f16::INFINITY; - let neg_inf: f16 = f16::NEG_INFINITY; - let zero: f16 = 0.0f16; - let neg_zero: f16 = -0.0; - assert!(!nan.is_normal()); - assert!(!inf.is_normal()); - assert!(!neg_inf.is_normal()); - assert!(!zero.is_normal()); - assert!(!neg_zero.is_normal()); - assert!(1f16.is_normal()); - assert!(1e-4f16.is_normal()); - assert!(!1e-5f16.is_normal()); -} - -#[test] -fn test_classify() { - let nan: f16 = f16::NAN; - let inf: f16 = f16::INFINITY; - let neg_inf: f16 = f16::NEG_INFINITY; - let zero: f16 = 0.0f16; - let neg_zero: f16 = -0.0; - assert_eq!(nan.classify(), Fp::Nan); - assert_eq!(inf.classify(), Fp::Infinite); - assert_eq!(neg_inf.classify(), Fp::Infinite); - assert_eq!(zero.classify(), Fp::Zero); - assert_eq!(neg_zero.classify(), Fp::Zero); - assert_eq!(1f16.classify(), Fp::Normal); - assert_eq!(1e-4f16.classify(), Fp::Normal); - assert_eq!(1e-5f16.classify(), Fp::Subnormal); -} - #[test] #[cfg(any(miri, target_has_reliable_f16_math))] fn test_abs() { diff --git a/library/coretests/tests/floats/f32.rs b/library/coretests/tests/floats/f32.rs index f5d5723fea455..267b0e4e29434 100644 --- a/library/coretests/tests/floats/f32.rs +++ b/library/coretests/tests/floats/f32.rs @@ -1,6 +1,5 @@ use core::f32; use core::f32::consts; -use core::num::FpCategory as Fp; use super::{assert_approx_eq, assert_biteq}; @@ -30,148 +29,6 @@ const NAN_MASK2: u32 = 0x0055_5555; /// They serve as a way to get an idea of the real precision of floating point operations on different platforms. const APPROX_DELTA: f32 = if cfg!(miri) { 1e-4 } else { 1e-6 }; -#[test] -fn test_num_f32() { - super::test_num(10f32, 2f32); -} - -#[test] -fn test_infinity() { - let inf: f32 = f32::INFINITY; - assert!(inf.is_infinite()); - assert!(!inf.is_finite()); - assert!(inf.is_sign_positive()); - assert!(!inf.is_sign_negative()); - assert!(!inf.is_nan()); - assert!(!inf.is_normal()); - assert_eq!(Fp::Infinite, inf.classify()); -} - -#[test] -fn test_neg_infinity() { - let neg_inf: f32 = f32::NEG_INFINITY; - assert!(neg_inf.is_infinite()); - assert!(!neg_inf.is_finite()); - assert!(!neg_inf.is_sign_positive()); - assert!(neg_inf.is_sign_negative()); - assert!(!neg_inf.is_nan()); - assert!(!neg_inf.is_normal()); - assert_eq!(Fp::Infinite, neg_inf.classify()); -} - -#[test] -fn test_zero() { - let zero: f32 = 0.0f32; - assert_biteq!(0.0, zero); - assert!(!zero.is_infinite()); - assert!(zero.is_finite()); - assert!(zero.is_sign_positive()); - assert!(!zero.is_sign_negative()); - assert!(!zero.is_nan()); - assert!(!zero.is_normal()); - assert_eq!(Fp::Zero, zero.classify()); -} - -#[test] -fn test_neg_zero() { - let neg_zero: f32 = -0.0; - assert_eq!(0.0, neg_zero); - assert_biteq!(-0.0, neg_zero); - assert!(!neg_zero.is_infinite()); - assert!(neg_zero.is_finite()); - assert!(!neg_zero.is_sign_positive()); - assert!(neg_zero.is_sign_negative()); - assert!(!neg_zero.is_nan()); - assert!(!neg_zero.is_normal()); - assert_eq!(Fp::Zero, neg_zero.classify()); -} - -#[test] -fn test_one() { - let one: f32 = 1.0f32; - assert_biteq!(1.0, one); - assert!(!one.is_infinite()); - assert!(one.is_finite()); - assert!(one.is_sign_positive()); - assert!(!one.is_sign_negative()); - assert!(!one.is_nan()); - assert!(one.is_normal()); - assert_eq!(Fp::Normal, one.classify()); -} - -#[test] -fn test_is_nan() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert!(nan.is_nan()); - assert!(!0.0f32.is_nan()); - assert!(!5.3f32.is_nan()); - assert!(!(-10.732f32).is_nan()); - assert!(!inf.is_nan()); - assert!(!neg_inf.is_nan()); -} - -#[test] -fn test_is_infinite() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert!(!nan.is_infinite()); - assert!(inf.is_infinite()); - assert!(neg_inf.is_infinite()); - assert!(!0.0f32.is_infinite()); - assert!(!42.8f32.is_infinite()); - assert!(!(-109.2f32).is_infinite()); -} - -#[test] -fn test_is_finite() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert!(!nan.is_finite()); - assert!(!inf.is_finite()); - assert!(!neg_inf.is_finite()); - assert!(0.0f32.is_finite()); - assert!(42.8f32.is_finite()); - assert!((-109.2f32).is_finite()); -} - -#[test] -fn test_is_normal() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - let zero: f32 = 0.0f32; - let neg_zero: f32 = -0.0; - assert!(!nan.is_normal()); - assert!(!inf.is_normal()); - assert!(!neg_inf.is_normal()); - assert!(!zero.is_normal()); - assert!(!neg_zero.is_normal()); - assert!(1f32.is_normal()); - assert!(1e-37f32.is_normal()); - assert!(!1e-38f32.is_normal()); -} - -#[test] -fn test_classify() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - let zero: f32 = 0.0f32; - let neg_zero: f32 = -0.0; - assert_eq!(nan.classify(), Fp::Nan); - assert_eq!(inf.classify(), Fp::Infinite); - assert_eq!(neg_inf.classify(), Fp::Infinite); - assert_eq!(zero.classify(), Fp::Zero); - assert_eq!(neg_zero.classify(), Fp::Zero); - assert_eq!(1f32.classify(), Fp::Normal); - assert_eq!(1e-37f32.classify(), Fp::Normal); - assert_eq!(1e-38f32.classify(), Fp::Subnormal); -} - #[test] fn test_abs() { assert_biteq!(f32::INFINITY.abs(), f32::INFINITY); diff --git a/library/coretests/tests/floats/f64.rs b/library/coretests/tests/floats/f64.rs index 34af87c241e91..735b7a7651519 100644 --- a/library/coretests/tests/floats/f64.rs +++ b/library/coretests/tests/floats/f64.rs @@ -1,6 +1,5 @@ use core::f64; use core::f64::consts; -use core::num::FpCategory as Fp; use super::{assert_approx_eq, assert_biteq}; @@ -25,147 +24,6 @@ const NAN_MASK1: u64 = 0x000a_aaaa_aaaa_aaaa; /// Second pattern over the mantissa const NAN_MASK2: u64 = 0x0005_5555_5555_5555; -#[test] -fn test_num_f64() { - super::test_num(10f64, 2f64); -} - -#[test] -fn test_infinity() { - let inf: f64 = f64::INFINITY; - assert!(inf.is_infinite()); - assert!(!inf.is_finite()); - assert!(inf.is_sign_positive()); - assert!(!inf.is_sign_negative()); - assert!(!inf.is_nan()); - assert!(!inf.is_normal()); - assert_eq!(Fp::Infinite, inf.classify()); -} - -#[test] -fn test_neg_infinity() { - let neg_inf: f64 = f64::NEG_INFINITY; - assert!(neg_inf.is_infinite()); - assert!(!neg_inf.is_finite()); - assert!(!neg_inf.is_sign_positive()); - assert!(neg_inf.is_sign_negative()); - assert!(!neg_inf.is_nan()); - assert!(!neg_inf.is_normal()); - assert_eq!(Fp::Infinite, neg_inf.classify()); -} - -#[test] -fn test_zero() { - let zero: f64 = 0.0f64; - assert_biteq!(0.0, zero); - assert!(!zero.is_infinite()); - assert!(zero.is_finite()); - assert!(zero.is_sign_positive()); - assert!(!zero.is_sign_negative()); - assert!(!zero.is_nan()); - assert!(!zero.is_normal()); - assert_eq!(Fp::Zero, zero.classify()); -} - -#[test] -fn test_neg_zero() { - let neg_zero: f64 = -0.0; - assert_eq!(0.0, neg_zero); - assert_biteq!(-0.0, neg_zero); - assert!(!neg_zero.is_infinite()); - assert!(neg_zero.is_finite()); - assert!(!neg_zero.is_sign_positive()); - assert!(neg_zero.is_sign_negative()); - assert!(!neg_zero.is_nan()); - assert!(!neg_zero.is_normal()); - assert_eq!(Fp::Zero, neg_zero.classify()); -} - -#[test] -fn test_one() { - let one: f64 = 1.0f64; - assert_biteq!(1.0, one); - assert!(!one.is_infinite()); - assert!(one.is_finite()); - assert!(one.is_sign_positive()); - assert!(!one.is_sign_negative()); - assert!(!one.is_nan()); - assert!(one.is_normal()); - assert_eq!(Fp::Normal, one.classify()); -} - -#[test] -fn test_is_nan() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert!(nan.is_nan()); - assert!(!0.0f64.is_nan()); - assert!(!5.3f64.is_nan()); - assert!(!(-10.732f64).is_nan()); - assert!(!inf.is_nan()); - assert!(!neg_inf.is_nan()); -} - -#[test] -fn test_is_infinite() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert!(!nan.is_infinite()); - assert!(inf.is_infinite()); - assert!(neg_inf.is_infinite()); - assert!(!0.0f64.is_infinite()); - assert!(!42.8f64.is_infinite()); - assert!(!(-109.2f64).is_infinite()); -} - -#[test] -fn test_is_finite() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert!(!nan.is_finite()); - assert!(!inf.is_finite()); - assert!(!neg_inf.is_finite()); - assert!(0.0f64.is_finite()); - assert!(42.8f64.is_finite()); - assert!((-109.2f64).is_finite()); -} - -#[test] -fn test_is_normal() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - let zero: f64 = 0.0f64; - let neg_zero: f64 = -0.0; - assert!(!nan.is_normal()); - assert!(!inf.is_normal()); - assert!(!neg_inf.is_normal()); - assert!(!zero.is_normal()); - assert!(!neg_zero.is_normal()); - assert!(1f64.is_normal()); - assert!(1e-307f64.is_normal()); - assert!(!1e-308f64.is_normal()); -} - -#[test] -fn test_classify() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - let zero: f64 = 0.0f64; - let neg_zero: f64 = -0.0; - assert_eq!(nan.classify(), Fp::Nan); - assert_eq!(inf.classify(), Fp::Infinite); - assert_eq!(neg_inf.classify(), Fp::Infinite); - assert_eq!(zero.classify(), Fp::Zero); - assert_eq!(neg_zero.classify(), Fp::Zero); - assert_eq!(1e-307f64.classify(), Fp::Normal); - assert_eq!(1e-308f64.classify(), Fp::Subnormal); -} - #[test] fn test_abs() { assert_biteq!(f64::INFINITY.abs(), f64::INFINITY); diff --git a/library/coretests/tests/floats/mod.rs b/library/coretests/tests/floats/mod.rs index 36743a7d6df9e..43431bba6954b 100644 --- a/library/coretests/tests/floats/mod.rs +++ b/library/coretests/tests/floats/mod.rs @@ -1,28 +1,40 @@ -use std::fmt; use std::num::FpCategory as Fp; use std::ops::{Add, Div, Mul, Rem, Sub}; -/// Set the default tolerance for float comparison based on the type. -trait Approx { - const LIM: Self; +trait TestableFloat { + /// Set the default tolerance for float comparison based on the type. + const APPROX: Self; + const MIN_POSITIVE_NORMAL: Self; + const MAX_SUBNORMAL: Self; } -impl Approx for f16 { - const LIM: Self = 1e-3; +impl TestableFloat for f16 { + const APPROX: Self = 1e-3; + const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE; + const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down(); } -impl Approx for f32 { - const LIM: Self = 1e-6; + +impl TestableFloat for f32 { + const APPROX: Self = 1e-6; + const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE; + const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down(); } -impl Approx for f64 { - const LIM: Self = 1e-6; + +impl TestableFloat for f64 { + const APPROX: Self = 1e-6; + const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE; + const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down(); } -impl Approx for f128 { - const LIM: Self = 1e-9; + +impl TestableFloat for f128 { + const APPROX: Self = 1e-9; + const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE; + const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down(); } /// Determine the tolerance for values of the argument type. -const fn lim_for_ty(_x: T) -> T { - T::LIM +const fn lim_for_ty(_x: T) -> T { + T::APPROX } // We have runtime ("rt") and const versions of these macros. @@ -187,9 +199,11 @@ macro_rules! float_test { $( $( #[$const_meta] )+ )? mod const_ { #[allow(unused)] - use super::Approx; + use super::TestableFloat; #[allow(unused)] use std::num::FpCategory as Fp; + #[allow(unused)] + use std::ops::{Add, Div, Mul, Rem, Sub}; // Shadow the runtime versions of the macro with const-compatible versions. #[allow(unused)] use $crate::floats::{ @@ -229,30 +243,42 @@ macro_rules! float_test { }; } -/// Helper function for testing numeric operations -pub fn test_num(ten: T, two: T) -where - T: PartialEq - + Add - + Sub - + Mul - + Div - + Rem - + fmt::Debug - + Copy, -{ - assert_eq!(ten.add(two), ten + two); - assert_eq!(ten.sub(two), ten - two); - assert_eq!(ten.mul(two), ten * two); - assert_eq!(ten.div(two), ten / two); - assert_eq!(ten.rem(two), ten % two); -} - mod f128; mod f16; mod f32; mod f64; +float_test! { + name: num, + attrs: { + f16: #[cfg(any(miri, target_has_reliable_f16))], + f128: #[cfg(any(miri, target_has_reliable_f128))], + }, + test { + let two: Float = 2.0; + let ten: Float = 10.0; + assert_biteq!(ten.add(two), ten + two); + assert_biteq!(ten.sub(two), ten - two); + assert_biteq!(ten.mul(two), ten * two); + assert_biteq!(ten.div(two), ten / two); + } +} + +// FIXME(f16_f128): merge into `num` once the required `fmodl`/`fmodf128` function is available on +// all platforms. +float_test! { + name: num_rem, + attrs: { + f16: #[cfg(any(miri, target_has_reliable_f16_math))], + f128: #[cfg(any(miri, target_has_reliable_f128_math))], + }, + test { + let two: Float = 2.0; + let ten: Float = 10.0; + assert_biteq!(ten.rem(two), ten % two); + } +} + float_test! { name: nan, attrs: { @@ -273,6 +299,213 @@ float_test! { } } +float_test! { + name: infinity, + attrs: { + f16: #[cfg(any(miri, target_has_reliable_f16))], + f128: #[cfg(any(miri, target_has_reliable_f128))], + }, + test { + let inf: Float = Float::INFINITY; + assert!(inf.is_infinite()); + assert!(!inf.is_finite()); + assert!(inf.is_sign_positive()); + assert!(!inf.is_sign_negative()); + assert!(!inf.is_nan()); + assert!(!inf.is_normal()); + assert!(matches!(inf.classify(), Fp::Infinite)); + } +} + +float_test! { + name: neg_infinity, + attrs: { + f16: #[cfg(any(miri, target_has_reliable_f16))], + f128: #[cfg(any(miri, target_has_reliable_f128))], + }, + test { + let neg_inf: Float = Float::NEG_INFINITY; + assert!(neg_inf.is_infinite()); + assert!(!neg_inf.is_finite()); + assert!(!neg_inf.is_sign_positive()); + assert!(neg_inf.is_sign_negative()); + assert!(!neg_inf.is_nan()); + assert!(!neg_inf.is_normal()); + assert!(matches!(neg_inf.classify(), Fp::Infinite)); + } +} + +float_test! { + name: zero, + attrs: { + f16: #[cfg(any(miri, target_has_reliable_f16))], + f128: #[cfg(any(miri, target_has_reliable_f128))], + }, + test { + let zero: Float = 0.0; + assert_biteq!(0.0, zero); + assert!(!zero.is_infinite()); + assert!(zero.is_finite()); + assert!(zero.is_sign_positive()); + assert!(!zero.is_sign_negative()); + assert!(!zero.is_nan()); + assert!(!zero.is_normal()); + assert!(matches!(zero.classify(), Fp::Zero)); + } +} + +float_test! { + name: neg_zero, + attrs: { + f16: #[cfg(any(miri, target_has_reliable_f16))], + f128: #[cfg(any(miri, target_has_reliable_f128))], + }, + test { + let neg_zero: Float = -0.0; + assert!(0.0 == neg_zero); + assert_biteq!(-0.0, neg_zero); + assert!(!neg_zero.is_infinite()); + assert!(neg_zero.is_finite()); + assert!(!neg_zero.is_sign_positive()); + assert!(neg_zero.is_sign_negative()); + assert!(!neg_zero.is_nan()); + assert!(!neg_zero.is_normal()); + assert!(matches!(neg_zero.classify(), Fp::Zero)); + } +} + +float_test! { + name: one, + attrs: { + f16: #[cfg(any(miri, target_has_reliable_f16))], + f128: #[cfg(any(miri, target_has_reliable_f128))], + }, + test { + let one: Float = 1.0; + assert_biteq!(1.0, one); + assert!(!one.is_infinite()); + assert!(one.is_finite()); + assert!(one.is_sign_positive()); + assert!(!one.is_sign_negative()); + assert!(!one.is_nan()); + assert!(one.is_normal()); + assert!(matches!(one.classify(), Fp::Normal)); + } +} + +float_test! { + name: is_nan, + attrs: { + f16: #[cfg(any(miri, target_has_reliable_f16))], + f128: #[cfg(any(miri, target_has_reliable_f128))], + }, + test { + let nan: Float = Float::NAN; + let inf: Float = Float::INFINITY; + let neg_inf: Float = Float::NEG_INFINITY; + let zero: Float = 0.0; + let pos: Float = 5.3; + let neg: Float = -10.732; + assert!(nan.is_nan()); + assert!(!zero.is_nan()); + assert!(!pos.is_nan()); + assert!(!neg.is_nan()); + assert!(!inf.is_nan()); + assert!(!neg_inf.is_nan()); + } +} + +float_test! { + name: is_infinite, + attrs: { + f16: #[cfg(any(miri, target_has_reliable_f16))], + f128: #[cfg(any(miri, target_has_reliable_f128))], + }, + test { + let nan: Float = Float::NAN; + let inf: Float = Float::INFINITY; + let neg_inf: Float = Float::NEG_INFINITY; + let zero: Float = 0.0; + let pos: Float = 42.8; + let neg: Float = -109.2; + assert!(!nan.is_infinite()); + assert!(inf.is_infinite()); + assert!(neg_inf.is_infinite()); + assert!(!zero.is_infinite()); + assert!(!pos.is_infinite()); + assert!(!neg.is_infinite()); + } +} + +float_test! { + name: is_finite, + attrs: { + f16: #[cfg(any(miri, target_has_reliable_f16))], + f128: #[cfg(any(miri, target_has_reliable_f128))], + }, + test { + let nan: Float = Float::NAN; + let inf: Float = Float::INFINITY; + let neg_inf: Float = Float::NEG_INFINITY; + let zero: Float = 0.0; + let pos: Float = 42.8; + let neg: Float = -109.2; + assert!(!nan.is_finite()); + assert!(!inf.is_finite()); + assert!(!neg_inf.is_finite()); + assert!(zero.is_finite()); + assert!(pos.is_finite()); + assert!(neg.is_finite()); + } +} + +float_test! { + name: is_normal, + attrs: { + f16: #[cfg(any(miri, target_has_reliable_f16))], + f128: #[cfg(any(miri, target_has_reliable_f128))], + }, + test { + let nan: Float = Float::NAN; + let inf: Float = Float::INFINITY; + let neg_inf: Float = Float::NEG_INFINITY; + let zero: Float = 0.0; + let neg_zero: Float = -0.0; + let one : Float = 1.0; + assert!(!nan.is_normal()); + assert!(!inf.is_normal()); + assert!(!neg_inf.is_normal()); + assert!(!zero.is_normal()); + assert!(!neg_zero.is_normal()); + assert!(one.is_normal()); + assert!(Float::MIN_POSITIVE_NORMAL.is_normal()); + assert!(!Float::MAX_SUBNORMAL.is_normal()); + } +} + +float_test! { + name: classify, + attrs: { + f16: #[cfg(any(miri, target_has_reliable_f16))], + }, + test { + let nan: Float = Float::NAN; + let inf: Float = Float::INFINITY; + let neg_inf: Float = Float::NEG_INFINITY; + let zero: Float = 0.0; + let neg_zero: Float = -0.0; + let one: Float = 1.0; + assert!(matches!(nan.classify(), Fp::Nan)); + assert!(matches!(inf.classify(), Fp::Infinite)); + assert!(matches!(neg_inf.classify(), Fp::Infinite)); + assert!(matches!(zero.classify(), Fp::Zero)); + assert!(matches!(neg_zero.classify(), Fp::Zero)); + assert!(matches!(one.classify(), Fp::Normal)); + assert!(matches!(Float::MIN_POSITIVE_NORMAL.classify(), Fp::Normal)); + assert!(matches!(Float::MAX_SUBNORMAL.classify(), Fp::Subnormal)); + } +} + float_test! { name: min, attrs: { diff --git a/library/coretests/tests/io/borrowed_buf.rs b/library/coretests/tests/io/borrowed_buf.rs index fbd3864dcac14..73dbfaf5ee906 100644 --- a/library/coretests/tests/io/borrowed_buf.rs +++ b/library/coretests/tests/io/borrowed_buf.rs @@ -165,3 +165,39 @@ fn cursor_set_init() { assert_eq!(rbuf.unfilled().uninit_mut().len(), 4); assert_eq!(unsafe { rbuf.unfilled().as_mut().len() }, 12); } + +#[test] +fn cursor_with_unfilled_buf() { + let buf: &mut [_] = &mut [MaybeUninit::uninit(); 16]; + let mut rbuf = BorrowedBuf::from(buf); + let mut cursor = rbuf.unfilled(); + + cursor.with_unfilled_buf(|buf| { + buf.unfilled().append(&[1, 2, 3]); + assert_eq!(buf.filled(), &[1, 2, 3]); + }); + + assert_eq!(cursor.init_mut().len(), 0); + assert_eq!(cursor.written(), 3); + + cursor.with_unfilled_buf(|buf| { + assert_eq!(buf.capacity(), 13); + assert_eq!(buf.init_len(), 0); + + buf.unfilled().ensure_init(); + buf.unfilled().advance(4); + }); + + assert_eq!(cursor.init_mut().len(), 9); + assert_eq!(cursor.written(), 7); + + cursor.with_unfilled_buf(|buf| { + assert_eq!(buf.capacity(), 9); + assert_eq!(buf.init_len(), 9); + }); + + assert_eq!(cursor.init_mut().len(), 9); + assert_eq!(cursor.written(), 7); + + assert_eq!(rbuf.filled(), &[1, 2, 3, 0, 0, 0, 0]); +} diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index fdef736c0c0f7..e2249bd7f6a11 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -20,6 +20,7 @@ #![feature(const_destruct)] #![feature(const_eval_select)] #![feature(const_float_round_methods)] +#![feature(const_ops)] #![feature(const_ref_cell)] #![feature(const_trait_impl)] #![feature(core_float_math)] diff --git a/library/std/src/random.rs b/library/std/src/random.rs index e7d4ab81df0ac..3994c5cfaf6f4 100644 --- a/library/std/src/random.rs +++ b/library/std/src/random.rs @@ -1,7 +1,4 @@ //! Random value generation. -//! -//! The [`Random`] trait allows generating a random value for a type using a -//! given [`RandomSource`]. #[unstable(feature = "random", issue = "130703")] pub use core::random::*; @@ -68,18 +65,11 @@ impl RandomSource for DefaultRandomSource { } } -/// Generates a random value with the default random source. +/// Generates a random value from a distribution, using the default random source. /// -/// This is a convenience function for `T::random(&mut DefaultRandomSource)` and -/// will sample according to the same distribution as the underlying [`Random`] -/// trait implementation. See [`DefaultRandomSource`] for more information about -/// how randomness is sourced. -/// -/// **Warning:** Be careful when manipulating random values! The -/// [`random`](Random::random) method on integers samples them with a uniform -/// distribution, so a value of 1 is just as likely as [`i32::MAX`]. By using -/// modulo operations, some of the resulting values can become more likely than -/// others. Use audited crates when in doubt. +/// This is a convenience function for `dist.sample(&mut DefaultRandomSource)` and will sample +/// according to the same distribution as the underlying [`Distribution`] trait implementation. See +/// [`DefaultRandomSource`] for more information about how randomness is sourced. /// /// # Examples /// @@ -89,7 +79,7 @@ impl RandomSource for DefaultRandomSource { /// /// use std::random::random; /// -/// let bits: u128 = random(); +/// let bits: u128 = random(..); /// let g1 = (bits >> 96) as u32; /// let g2 = (bits >> 80) as u16; /// let g3 = (0x4000 | (bits >> 64) & 0x0fff) as u16; @@ -101,6 +91,6 @@ impl RandomSource for DefaultRandomSource { /// /// [version 4/variant 1 UUID]: https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random) #[unstable(feature = "random", issue = "130703")] -pub fn random() -> T { - T::random(&mut DefaultRandomSource) +pub fn random(dist: impl Distribution) -> T { + dist.sample(&mut DefaultRandomSource) } diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs index cbdaf439b2847..dea44124f458b 100644 --- a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs +++ b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs @@ -2,7 +2,7 @@ use crate::cmp; use crate::io::{ BorrowedCursor, Error as IoError, ErrorKind, IoSlice, IoSliceMut, Result as IoResult, }; -use crate::random::{DefaultRandomSource, Random}; +use crate::random::random; use crate::time::{Duration, Instant}; pub(crate) mod alloc; @@ -179,7 +179,7 @@ pub fn wait(event_mask: u64, mut timeout: u64) -> IoResult { // trusted to ensure accurate timeouts. if let Ok(timeout_signed) = i64::try_from(timeout) { let tenth = timeout_signed / 10; - let deviation = i64::random(&mut DefaultRandomSource).checked_rem(tenth).unwrap_or(0); + let deviation = random::(..).checked_rem(tenth).unwrap_or(0); timeout = timeout_signed.saturating_add(deviation) as _; } } diff --git a/library/std/src/sys/personality/mod.rs b/library/std/src/sys/personality/mod.rs index 2e1d2e53a2979..2623a0b8e5f32 100644 --- a/library/std/src/sys/personality/mod.rs +++ b/library/std/src/sys/personality/mod.rs @@ -16,16 +16,6 @@ mod dwarf; cfg_if::cfg_if! { if #[cfg(target_os = "emscripten")] { mod emcc; - } else if #[cfg(any(target_env = "msvc", target_family = "wasm"))] { - // This is required by the compiler to exist (e.g., it's a lang item), - // but it's never actually called by the compiler because - // __CxxFrameHandler3 (msvc) / __gxx_wasm_personality_v0 (wasm) is the - // personality function that is always used. Hence this is just an - // aborting stub. - #[lang = "eh_personality"] - fn rust_eh_personality() { - core::intrinsics::abort() - } } else if #[cfg(any( all(target_family = "windows", target_env = "gnu"), target_os = "psp", @@ -36,6 +26,9 @@ cfg_if::cfg_if! { ))] { mod gcc; } else { + // Targets that have a pre-defined personality: + // - msvc + // - wasm (except for emscripten) // Targets that don't support unwinding. // - os=none ("bare metal" targets) // - os=uefi diff --git a/library/std/src/sys/sync/once/futex.rs b/library/std/src/sys/sync/once/futex.rs index 539f0fe89eaaa..407fdcebcf5cc 100644 --- a/library/std/src/sys/sync/once/futex.rs +++ b/library/std/src/sys/sync/once/futex.rs @@ -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: diff --git a/library/std/src/sys/sync/once/queue.rs b/library/std/src/sys/sync/once/queue.rs index 6a2ab0dcf1b33..49e15d65f25a2 100644 --- a/library/std/src/sys/sync/once/queue.rs +++ b/library/std/src/sys/sync/once/queue.rs @@ -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. diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 5de1b472d7940..02241b3e69799 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -1140,6 +1140,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 +1181,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 +1221,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 +1230,7 @@ fn run_tool_build_step( path: &'static str, add_bins_to_sysroot: Option<&[&str]>, add_features: Option, TargetSelection, &mut Vec)>, + cargo_args: Option<&[&'static str]>, ) -> ToolBuildResult { let mut extra_features = Vec::new(); if let Some(func) = add_features { @@ -1243,7 +1247,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 +1298,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", diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 4d606953d9986..7115c5a1cbe7b 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -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, ), diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md index b05318ce9e6cf..4f44cf1701c43 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md @@ -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`). diff --git a/src/etc/htmldocck.py b/src/etc/htmldocck.py index ddbd256a0d8c9..72975cc6206c0 100755 --- a/src/etc/htmldocck.py +++ b/src/etc/htmldocck.py @@ -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 . -KNOWN_DIRECTIVE_NAMES = get_known_directive_names() - LINE_PATTERN = re.compile( r""" //@\s+ - (?P!?)(?P[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*) - (?P.*)$ + (?P!?)(?P.+?) + (?:[\s:](?P.*))?$ """, 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) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 6a1fad06ae34d..70f3f54e4c050 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -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), diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs deleted file mode 100644 index adf2a7bffeff9..0000000000000 --- a/src/tools/compiletest/src/directive-list.rs +++ /dev/null @@ -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 -]; diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index 7fadb4dae2a1d..215793fe947f8 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -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 . -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; } diff --git a/src/tools/compiletest/src/runtest/rustdoc.rs b/src/tools/compiletest/src/runtest/rustdoc.rs index 637ea833357a2..236f021ce827c 100644 --- a/src/tools/compiletest/src/runtest/rustdoc.rs +++ b/src/tools/compiletest/src/runtest/rustdoc.rs @@ -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| { diff --git a/src/tools/compiletest/src/runtest/rustdoc_json.rs b/src/tools/compiletest/src/runtest/rustdoc_json.rs index 9f88faca89268..4f35efedfde49 100644 --- a/src/tools/compiletest/src/runtest/rustdoc_json.rs +++ b/src/tools/compiletest/src/runtest/rustdoc_json.rs @@ -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| { diff --git a/src/tools/jsondocck/src/directive.rs b/src/tools/jsondocck/src/directive.rs index fdb2fa6dbbe01..c52c16866608d 100644 --- a/src/tools/jsondocck/src/directive.rs +++ b/src/tools/jsondocck/src/directive.rs @@ -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 . -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(|| { diff --git a/src/tools/jsondocck/src/main.rs b/src/tools/jsondocck/src/main.rs index d84be4d3a3a6f..c3487565c23ed 100644 --- a/src/tools/jsondocck/src/main.rs +++ b/src/tools/jsondocck/src/main.rs @@ -47,8 +47,8 @@ static LINE_PATTERN: LazyLock = LazyLock::new(|| { ^\s* //@\s+ (?P!?) - (?P[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*) - (?P.*)$ + (?P.+?) + (?:[\s:](?P.*))?$ "#, ) .ignore_whitespace(true) @@ -58,15 +58,7 @@ static LINE_PATTERN: LazyLock = LazyLock::new(|| { }); static DEPRECATED_LINE_PATTERN: LazyLock = 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, ()> { 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; diff --git a/src/tools/miri/tests/pass/shims/random.rs b/src/tools/miri/tests/pass/shims/random.rs index ae75ebdcd3f32..2a5c8993662be 100644 --- a/src/tools/miri/tests/pass/shims/random.rs +++ b/src/tools/miri/tests/pass/shims/random.rs @@ -1,5 +1,5 @@ #![feature(random)] fn main() { - let _x: i32 = std::random::random(); + let _x: i32 = std::random::random(..); } diff --git a/src/tools/remote-test-client/src/main.rs b/src/tools/remote-test-client/src/main.rs index bda08423487b5..b9741431b5034 100644 --- a/src/tools/remote-test-client/src/main.rs +++ b/src/tools/remote-test-client/src/main.rs @@ -335,7 +335,9 @@ fn run(support_lib_count: usize, exe: String, all_args: Vec) { std::process::exit(code); } else { println!("died due to signal {}", code); - std::process::exit(3); + // Behave like bash and other tools and exit with 128 + the signal + // number. That way we can avoid special case code in other places. + std::process::exit(128 + code); } } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs index de8a42979bb1d..f9eb44d03abb9 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs @@ -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 ------------------------ "##, diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index 4835c22021042..d995106ae0257 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "tidy" version = "0.1.0" -edition = "2021" +edition = "2024" autobins = false [dependencies] diff --git a/src/tools/tidy/src/alphabetical.rs b/src/tools/tidy/src/alphabetical.rs index 141083290c6c8..9ddce72510693 100644 --- a/src/tools/tidy/src/alphabetical.rs +++ b/src/tools/tidy/src/alphabetical.rs @@ -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); } diff --git a/src/tools/tidy/src/bins.rs b/src/tools/tidy/src/bins.rs index 9b78ba75a0553..a18f549844b86 100644 --- a/src/tools/tidy/src/bins.rs +++ b/src/tools/tidy/src/bins.rs @@ -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("\\", "/"); diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index bf813d2131e87..f43f5eae9a560 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -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 diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index bb61412f67882..65aa89fe80169 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -119,8 +119,7 @@ fn extract_error_codes(root_path: &Path, errors: &mut Vec) -> Vec) -> Vec) -> Vec, 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::>(); - let mut file_args_ruff = file_args.into_iter().copied().collect::>(); + 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) } diff --git a/src/tools/tidy/src/extdeps.rs b/src/tools/tidy/src/extdeps.rs index 55f937aeacf50..bc217a55cc199 100644 --- a/src/tools/tidy/src/extdeps.rs +++ b/src/tools/tidy/src/extdeps.rs @@ -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); } } diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 6093e7fd2632f..e83b47e138064 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -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); } diff --git a/src/tools/tidy/src/features/version.rs b/src/tools/tidy/src/features/version.rs index 6a902e80f8e70..0e0629a48e218 100644 --- a/src/tools/tidy/src/features/version.rs +++ b/src/tools/tidy/src/features/version.rs @@ -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"), } } } diff --git a/src/tools/tidy/src/features/version/tests.rs b/src/tools/tidy/src/features/version/tests.rs index 7701dce2df173..453ba40586e73 100644 --- a/src/tools/tidy/src/features/version/tests.rs +++ b/src/tools/tidy/src/features/version/tests.rs @@ -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"); } diff --git a/src/tools/tidy/src/fluent_alphabetical.rs b/src/tools/tidy/src/fluent_alphabetical.rs index 6f154b92eff15..48d14a37514bd 100644 --- a/src/tools/tidy/src/fluent_alphabetical.rs +++ b/src/tools/tidy/src/fluent_alphabetical.rs @@ -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( diff --git a/src/tools/tidy/src/fluent_period.rs b/src/tools/tidy/src/fluent_period.rs index 6a136e5aec698..85c1ef6166a4b 100644 --- a/src/tools/tidy/src/fluent_period.rs +++ b/src/tools/tidy/src/fluent_period.rs @@ -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"); } diff --git a/src/tools/tidy/src/fluent_used.rs b/src/tools/tidy/src/fluent_used.rs index ab56b5f0b0ec3..12fafd9a7ffc2 100644 --- a/src/tools/tidy/src/fluent_used.rs +++ b/src/tools/tidy/src/fluent_used.rs @@ -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`. diff --git a/src/tools/tidy/src/gcc_submodule.rs b/src/tools/tidy/src/gcc_submodule.rs index 952ebe9e0cffe..5d726c3ea48ff 100644 --- a/src/tools/tidy/src/gcc_submodule.rs +++ b/src/tools/tidy/src/gcc_submodule.rs @@ -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!( diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 1eb5485f2b869..a67f7a511b598 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -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(); diff --git a/src/tools/tidy/src/mir_opt_tests.rs b/src/tools/tidy/src/mir_opt_tests.rs index bb0d8150be4e1..1efe71b1687e3 100644 --- a/src/tools/tidy/src/mir_opt_tests.rs +++ b/src/tools/tidy/src/mir_opt_tests.rs @@ -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()) diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index 9b915e0f737dc..b7d4a331891a8 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -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); diff --git a/src/tools/tidy/src/rustdoc_gui_tests.rs b/src/tools/tidy/src/rustdoc_gui_tests.rs index 91776bc989e1d..3b995f219d269 100644 --- a/src/tools/tidy/src/rustdoc_gui_tests.rs +++ b/src/tools/tidy/src/rustdoc_gui_tests.rs @@ -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("// ") { diff --git a/src/tools/tidy/src/rustdoc_js.rs b/src/tools/tidy/src/rustdoc_js.rs index 5e924544f0dc7..5737fcbafc02d 100644 --- a/src/tools/tidy/src/rustdoc_js.rs +++ b/src/tools/tidy/src/rustdoc_js.rs @@ -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()); }, diff --git a/src/tools/tidy/src/rustdoc_json.rs b/src/tools/tidy/src/rustdoc_json.rs index 19b8e79ec33a3..722e1ebd0cad2 100644 --- a/src/tools/tidy/src/rustdoc_json.rs +++ b/src/tools/tidy/src/rustdoc_json.rs @@ -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; diff --git a/src/tools/tidy/src/rustdoc_templates.rs b/src/tools/tidy/src/rustdoc_templates.rs index 2173dbf7e746a..dca3e8d9d25f8 100644 --- a/src/tools/tidy/src/rustdoc_templates.rs +++ b/src/tools/tidy/src/rustdoc_templates.rs @@ -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); diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index 2237eac200d80..8dde4618ce528 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -94,10 +94,9 @@ fn generate_problems<'a>( letter_digit: &'a FxHashMap, ) -> impl Iterator + '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 = 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; diff --git a/src/tools/tidy/src/target_specific_tests.rs b/src/tools/tidy/src/target_specific_tests.rs index a66ccd37070ad..1a6fd3eaf2dde 100644 --- a/src/tools/tidy/src/target_specific_tests.rs +++ b/src/tools/tidy/src/target_specific_tests.rs @@ -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; } diff --git a/src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs b/src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs index ee92d302db3c9..02412b6f190e8 100644 --- a/src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs +++ b/src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs @@ -38,7 +38,7 @@ pub fn check(tests_path: impl AsRef, 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, 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, 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, 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. diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 53226fcb80e6a..b1ace74e5bd28 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -57,11 +57,9 @@ const EXTENSION_EXCEPTION_PATHS: &[&str] = &[ fn check_entries(tests_path: &Path, bad: &mut bool) { let mut directories: HashMap = 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(); diff --git a/src/tools/tidy/src/unstable_book.rs b/src/tools/tidy/src/unstable_book.rs index a2453a6c96057..9dc9d42d46600 100644 --- a/src/tools/tidy/src/unstable_book.rs +++ b/src/tools/tidy/src/unstable_book.rs @@ -38,7 +38,7 @@ fn dir_entry_is_file(dir_entry: &fs::DirEntry) -> bool { pub fn collect_unstable_feature_names(features: &Features) -> BTreeSet { 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::(); // Library features diff --git a/src/tools/tidy/src/walk.rs b/src/tools/tidy/src/walk.rs index c2c9eb8d2507e..7825ebeb5baa6 100644 --- a/src/tools/tidy/src/walk.rs +++ b/src/tools/tidy/src/walk.rs @@ -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); diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs index 489343561e180..6a5e9eca81328 100644 --- a/src/tools/tidy/src/x_version.rs +++ b/src/tools/tidy/src/x_version.rs @@ -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) diff --git a/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr b/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr index be3de58098325..5ce815b9aed4d 100644 --- a/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr +++ b/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr @@ -16,7 +16,7 @@ error[E0658]: const trait impls are experimental LL | trait Bar: ~const Foo {} | ^^^^^^ | - = note: see issue #67792 for more information + = note: see issue #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(x: &T) { | ^^^^^^ | - = note: see issue #67792 for more information + = note: see issue #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 diff --git a/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr b/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr index a23793580f7a8..3dc147e076fff 100644 --- a/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr +++ b/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr @@ -16,7 +16,7 @@ error[E0658]: const trait impls are experimental 7 | trait Bar: ~const Foo {} | ^^^^^^ | - = note: see issue #67792 for more information + = note: see issue #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(x: &T) { | ^^^^^^ | - = note: see issue #67792 for more information + = note: see issue #143874 for more information error: `[const]` can only be applied to `#[const_trait]` traits --> const-super-trait.rs:7:12 diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index f16ba706485da..d7a641cdcbefe 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -22,12 +22,6 @@ error[E0463]: can't find crate for `wloop` LL | extern crate wloop; | ^^^^^^^^^^^^^^^^^^^ can't find crate -error: malformed `omit_gdb_pretty_printer_section` attribute input - --> $DIR/malformed-attrs.rs:26:1 - | -LL | #![omit_gdb_pretty_printer_section = 1] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![omit_gdb_pretty_printer_section]` - error: malformed `windows_subsystem` attribute input --> $DIR/malformed-attrs.rs:29:1 | @@ -116,12 +110,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 | @@ -283,6 +271,15 @@ LL | #[debugger_visualizer] = note: OR = note: expected: `gdb_script_file = "..."` +error[E0565]: malformed `omit_gdb_pretty_printer_section` attribute input + --> $DIR/malformed-attrs.rs:26:1 + | +LL | #![omit_gdb_pretty_printer_section = 1] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[omit_gdb_pretty_printer_section]` + error[E0539]: malformed `export_name` attribute input --> $DIR/malformed-attrs.rs:32:1 | @@ -537,6 +534,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 | diff --git a/tests/ui/consts/issue-90870.stderr b/tests/ui/consts/issue-90870.stderr index 60993f2586427..c5a78531026ad 100644 --- a/tests/ui/consts/issue-90870.stderr +++ b/tests/ui/consts/issue-90870.stderr @@ -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 for more information + = note: see issue #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 for more information + = note: see issue #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 for more information + = note: see issue #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 diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr index d4b5b47b41b5e..deab31c251f83 100644 --- a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr +++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr @@ -63,7 +63,7 @@ error[E0658]: const trait impls are experimental LL | fn constness() -> impl Sized + const use<> {} | ^^^^^ | - = note: see issue #67792 for more information + = note: see issue #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 diff --git a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-invalid-format.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-invalid-format.rs index 9b7e8d70743b7..87b4999c5f9fd 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-invalid-format.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-invalid-format.rs @@ -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; } diff --git a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-invalid-format.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-invalid-format.stderr index 6341e57a0be53..ffae30aabcc3f 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-invalid-format.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-invalid-format.stderr @@ -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`. diff --git a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-missing-argument.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-missing-argument.rs index 6b8cd49566dfe..2a8b9ebacf7f1 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-missing-argument.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-missing-argument.rs @@ -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; } diff --git a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-missing-argument.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-missing-argument.stderr index 1b04bb228e76a..c6b8a18d03a36 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-missing-argument.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-missing-argument.stderr @@ -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`. diff --git a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-many-arguments.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-many-arguments.rs index 9988115fd8b0d..ddf9583352fad 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-many-arguments.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-many-arguments.rs @@ -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; } diff --git a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-many-arguments.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-many-arguments.stderr index d5ce8aff34f20..7d63304f5982b 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-many-arguments.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-many-arguments.stderr @@ -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`. diff --git a/tests/ui/traits/const-traits/cross-crate.stock.stderr b/tests/ui/traits/const-traits/cross-crate.stock.stderr index 7cdde5a079f2d..44a60c99ae9ea 100644 --- a/tests/ui/traits/const-traits/cross-crate.stock.stderr +++ b/tests/ui/traits/const-traits/cross-crate.stock.stderr @@ -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 for more information + = note: see issue #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 diff --git a/tests/ui/traits/const-traits/cross-crate.stocknc.stderr b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr index fb47bf9169fe2..766c20aa8211f 100644 --- a/tests/ui/traits/const-traits/cross-crate.stocknc.stderr +++ b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr @@ -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 for more information + = note: see issue #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 diff --git a/tests/ui/traits/const-traits/feature-gate.stock.stderr b/tests/ui/traits/const-traits/feature-gate.stock.stderr index f9d966f036239..f3ba3039a23aa 100644 --- a/tests/ui/traits/const-traits/feature-gate.stock.stderr +++ b/tests/ui/traits/const-traits/feature-gate.stock.stderr @@ -4,7 +4,7 @@ error[E0658]: const trait impls are experimental LL | impl const T for S {} | ^^^^^ | - = note: see issue #67792 for more information + = note: see issue #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() {} | ^^^^^^^ | - = note: see issue #67792 for more information + = note: see issue #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() {} | ^^^^^ | - = note: see issue #67792 for more information + = note: see issue #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 for more information + = note: see issue #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 for more information + = note: see issue #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 for more information + = note: see issue #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 diff --git a/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.stderr b/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.stderr index bc0e48112b9b8..a4e77154b17d1 100644 --- a/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.stderr +++ b/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.stderr @@ -13,7 +13,7 @@ error[E0658]: const trait impls are experimental LL | check! { [const] Trait } | ^^^^^ | - = note: see issue #67792 for more information + = note: see issue #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 diff --git a/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr b/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr index 5dd648554c9fa..b500e4858d125 100644 --- a/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr +++ b/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr @@ -26,7 +26,7 @@ error[E0658]: const trait impls are experimental LL | demo! { impl const Trait } | ^^^^^ | - = note: see issue #67792 for more information + = note: see issue #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 for more information + = note: see issue #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 diff --git a/tests/ui/traits/const-traits/staged-api-user-crate.stderr b/tests/ui/traits/const-traits/staged-api-user-crate.stderr index 8ac83770cf7a4..81611da9e748c 100644 --- a/tests/ui/traits/const-traits/staged-api-user-crate.stderr +++ b/tests/ui/traits/const-traits/staged-api-user-crate.stderr @@ -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 for more information + = note: see issue #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 diff --git a/tests/ui/traits/const-traits/staged-api.stderr b/tests/ui/traits/const-traits/staged-api.stderr index 4756c490cb10a..3e85834eb94ae 100644 --- a/tests/ui/traits/const-traits/staged-api.stderr +++ b/tests/ui/traits/const-traits/staged-api.stderr @@ -21,7 +21,7 @@ error: trait implementations cannot be const stable yet LL | impl const U for u16 {} | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: see issue #67792 for more information + = note: see issue #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 for more information + = note: see issue #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 diff --git a/tests/ui/traits/const-traits/std-impl-gate.stock.stderr b/tests/ui/traits/const-traits/std-impl-gate.stock.stderr index 1fa71e41a988d..261f68bebdb25 100644 --- a/tests/ui/traits/const-traits/std-impl-gate.stock.stderr +++ b/tests/ui/traits/const-traits/std-impl-gate.stock.stderr @@ -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 for more information + = note: see issue #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 diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr index eb1beb41e37e2..3f48375dd0453 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr @@ -16,7 +16,7 @@ error[E0658]: const trait impls are experimental LL | trait Bar: [const] Foo {} | ^^^^^^^ | - = note: see issue #67792 for more information + = note: see issue #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(x: &T) { | ^^^^^^^ | - = note: see issue #67792 for more information + = note: see issue #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 diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr index eb1beb41e37e2..3f48375dd0453 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr @@ -16,7 +16,7 @@ error[E0658]: const trait impls are experimental LL | trait Bar: [const] Foo {} | ^^^^^^^ | - = note: see issue #67792 for more information + = note: see issue #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(x: &T) { | ^^^^^^^ | - = note: see issue #67792 for more information + = note: see issue #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 diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr index 7c465731a99f5..b00ad706a5fa1 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nyn.stderr @@ -4,7 +4,7 @@ error[E0658]: const trait impls are experimental LL | trait Bar: [const] Foo {} | ^^^^^^^ | - = note: see issue #67792 for more information + = note: see issue #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(x: &T) { | ^^^^^^^ | - = note: see issue #67792 for more information + = note: see issue #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 for more information + = note: see issue #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 for more information + = note: see issue #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 for more information + = note: see issue #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 diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nyy.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nyy.stderr index 7c465731a99f5..b00ad706a5fa1 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nyy.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nyy.stderr @@ -4,7 +4,7 @@ error[E0658]: const trait impls are experimental LL | trait Bar: [const] Foo {} | ^^^^^^^ | - = note: see issue #67792 for more information + = note: see issue #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(x: &T) { | ^^^^^^^ | - = note: see issue #67792 for more information + = note: see issue #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 for more information + = note: see issue #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 for more information + = note: see issue #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 for more information + = note: see issue #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