diff --git a/Cargo.lock b/Cargo.lock index 39049cd7e2c6f..9894e374a0bf0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2558,8 +2558,10 @@ dependencies = [ "serde", "serde_json", "smallvec", + "socket2", "tempfile", "ui_test", + "windows-sys 0.61.2", ] [[package]] @@ -5472,9 +5474,9 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", "windows-sys 0.61.2", diff --git a/compiler/rustc/src/main.rs b/compiler/rustc/src/main.rs index 17f768f6dc54a..6609a19fa9e34 100644 --- a/compiler/rustc/src/main.rs +++ b/compiler/rustc/src/main.rs @@ -1,7 +1,5 @@ // We need this feature as it changes `dylib` linking behavior and allows us to link to `rustc_driver`. #![feature(rustc_private)] -// Several crates are depended upon but unused so that they are present in the sysroot -#![expect(unused_crate_dependencies)] use std::process::ExitCode; diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index f2c6ffe44cdfd..4c9258b753d8f 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -10,7 +10,6 @@ // tidy-alphabetical-start #![allow(clippy::mut_from_ref)] // Arena allocators are one place where this pattern is fine. #![allow(internal_features)] -#![cfg_attr(bootstrap, feature(never_type))] #![cfg_attr(bootstrap, feature(unwrap_infallible))] #![cfg_attr(test, feature(test))] #![deny(unsafe_op_in_unsafe_fn)] diff --git a/compiler/rustc_ast_ir/src/lib.rs b/compiler/rustc_ast_ir/src/lib.rs index e919e7df99ee0..dc2bf67d338e7 100644 --- a/compiler/rustc_ast_ir/src/lib.rs +++ b/compiler/rustc_ast_ir/src/lib.rs @@ -7,7 +7,6 @@ // tidy-alphabetical-start #![cfg_attr(feature = "nightly", allow(internal_features))] -#![cfg_attr(feature = "nightly", cfg_attr(bootstrap, feature(never_type)))] #![cfg_attr(feature = "nightly", feature(rustc_attrs))] // tidy-alphabetical-end diff --git a/compiler/rustc_attr_ir/src/attribute_docs.rs b/compiler/rustc_attr_ir/src/attribute_docs.rs index a2b00c90b3028..975594771d3fb 100644 --- a/compiler/rustc_attr_ir/src/attribute_docs.rs +++ b/compiler/rustc_attr_ir/src/attribute_docs.rs @@ -12,7 +12,7 @@ macro_rules! include_example { }; } -#[cfg_attr(not(bootstrap), doc(attribute = "rustc_dump_clauses"))] +#[doc(attribute = "rustc_dump_clauses")] /// Dumps the list of [`ty::Clause`]s as computed by the [`clauses_of`] query. /// /// See [`AttributeKind::RustcDumpClauses`] for the internal representation of this attribute. diff --git a/compiler/rustc_attr_ir/src/data_structures.rs b/compiler/rustc_attr_ir/src/data_structures.rs index 712ed41ae7759..55c0bedb9c39c 100644 --- a/compiler/rustc_attr_ir/src/data_structures.rs +++ b/compiler/rustc_attr_ir/src/data_structures.rs @@ -283,7 +283,6 @@ impl StrippedCfgItem { #[derive(StableHash, PrintAttribute)] pub enum Linkage { AvailableExternally, - Common, ExternalWeak, External, Internal, diff --git a/compiler/rustc_attr_ir/src/encode_cross_crate.rs b/compiler/rustc_attr_ir/src/encode_cross_crate.rs index 66fbbc1e3cbf7..b6733e8c1db54 100644 --- a/compiler/rustc_attr_ir/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_ir/src/encode_cross_crate.rs @@ -265,7 +265,6 @@ impl AttributeKind { Linkage(linkage, _) => match *linkage { crate::Linkage::Internal => false, crate::Linkage::AvailableExternally - | crate::Linkage::Common | crate::Linkage::External | crate::Linkage::ExternalWeak | crate::Linkage::LinkOnceAny diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index 8102208ec519d..d244e6c59e5f9 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -306,7 +306,8 @@ pub fn parse_cfg_attr( features: Option<&Features>, lint_node_id: ast::NodeId, ) -> Option<(CfgEntry, Vec<(WithTokens, Span)>)> { - match &cfg_attr.get_normal_item().args { + let item = cfg_attr.get_normal_item(); + match &item.args { ast::AttrArgs::Delimited(ast::DelimArgs { dspan, delim, tokens }) if !tokens.is_empty() => { check_cfg_attr_bad_delim(&sess.psess, *dspan, *delim); match parse_in(&sess.psess, tokens.clone(), "`cfg_attr` input", |p| { @@ -316,11 +317,11 @@ pub fn parse_cfg_attr( Err(e) => { let suggestions = CFG_ATTR_TEMPLATE.suggestions( ParsedDescription::Attribute, - cfg_attr.get_normal_item().unsafety, + item.unsafety, sym::cfg_attr, ); e.with_span_suggestions( - cfg_attr.get_normal_item().span, + item.span, "must be of the form", suggestions, Applicability::HasPlaceholders, @@ -334,25 +335,24 @@ pub fn parse_cfg_attr( } } _ => { - let (span, reason) = if let ast::AttrArgs::Delimited(ast::DelimArgs { dspan, .. }) = - cfg_attr.get_normal_item().args - { - (dspan.entire(), AttributeParseErrorReason::ExpectedAtLeastOneArgument) - } else { - (cfg_attr.get_normal_item().span, AttributeParseErrorReason::ExpectedList) - }; + let (span, reason) = + if let ast::AttrArgs::Delimited(ast::DelimArgs { dspan, .. }) = item.args { + (dspan.entire(), AttributeParseErrorReason::ExpectedAtLeastOneArgument) + } else { + (item.span, AttributeParseErrorReason::ExpectedList) + }; sess.dcx().emit_err(AttributeParseError { span, - inner_span: cfg_attr.get_normal_item().span, + inner_span: item.span, template: CFG_ATTR_TEMPLATE, - path: AttrPath::from_ast(&cfg_attr.get_normal_item().path, identity), + path: AttrPath::from_ast(&item.path, identity), description: ParsedDescription::Attribute, reason, suggestions: diagnostics::AttributeParseErrorSuggestions::CreatedByTemplate( CFG_ATTR_TEMPLATE.suggestions( ParsedDescription::Attribute, - cfg_attr.get_normal_item().unsafety, + item.unsafety, sym::cfg_attr, ), ), @@ -389,13 +389,14 @@ fn parse_cfg_attr_internal<'a>( )?; let pred_span = pred_start.with_hi(parser.token.span.hi()); + let item = attribute.get_normal_item(); let cfg_predicate = AttributeParser::parse_single_args( sess, attribute.span, - attribute.get_normal_item().span, + item.span, attribute.style, AttrPath { segments: attribute.path().into_boxed_slice(), span: attribute.span }, - Some(attribute.get_normal_item().unsafety), + Some(item.unsafety), AttributeSafety::Normal, ParsedDescription::Attribute, pred_span, diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index f4d0fa35e3f47..ed911a63eb7fe 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -685,10 +685,7 @@ impl SingleAttributeParser for LinkageParser { ]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: [ "available_externally", - "common", "extern_weak", - "external", - "internal", "linkonce", "linkonce_odr", "weak", @@ -711,10 +708,7 @@ impl SingleAttributeParser for LinkageParser { // and don't have to be, LLVM treats them as no-ops. let linkage = match value { sym::available_externally => Linkage::AvailableExternally, - sym::common => Linkage::Common, sym::extern_weak => Linkage::ExternalWeak, - sym::external => Linkage::External, - sym::internal => Linkage::Internal, sym::linkonce => Linkage::LinkOnceAny, sym::linkonce_odr => Linkage::LinkOnceODR, sym::weak => Linkage::WeakAny, @@ -725,10 +719,7 @@ impl SingleAttributeParser for LinkageParser { name_value.value_span, &[ sym::available_externally, - sym::common, sym::extern_weak, - sym::external, - sym::internal, sym::linkonce, sym::linkonce_odr, sym::weak, diff --git a/compiler/rustc_attr_parsing/src/diagnostics.rs b/compiler/rustc_attr_parsing/src/diagnostics.rs index fb4a32d864fbe..a43cd918c8f35 100644 --- a/compiler/rustc_attr_parsing/src/diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/diagnostics.rs @@ -1235,7 +1235,7 @@ pub(crate) struct UnknownVersionLiteral { #[diag("multiple `{$name}` attributes")] pub(crate) struct UnusedMultiple { #[primary_span] - #[suggestion("remove this attribute", code = "", applicability = "machine-applicable")] + #[suggestion("remove this attribute", code = "", applicability = "unspecified")] pub this: Span, #[note("attribute also specified here")] pub other: Span, @@ -2061,7 +2061,7 @@ pub(crate) struct AdditionalCommaSuggestion { #[derive(Diagnostic)] #[diag("unused attribute")] pub(crate) struct UnusedDuplicate { - #[suggestion("remove this attribute", code = "", applicability = "machine-applicable")] + #[suggestion("remove this attribute", code = "", applicability = "unspecified")] pub this: Span, #[note("attribute also specified here")] pub other: Span, diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index c35c7ab311572..514c06141db73 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -2,7 +2,6 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![cfg_attr(bootstrap, feature(never_type))] #![feature(default_field_values)] #![feature(deref_patterns)] #![feature(file_buffered)] diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 0a6fb9d5da47a..0e8565aef3f0b 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1361,7 +1361,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let cast_ty_from = CastTy::from_ty(ty_from); let cast_ty_to = CastTy::from_ty(*ty); match (cast_ty_from, cast_ty_to) { - (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_))) => (), + (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int)) => (), _ => { span_mirbug!( self, @@ -1379,7 +1379,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let cast_ty_from = CastTy::from_ty(ty_from); let cast_ty_to = CastTy::from_ty(*ty); match (cast_ty_from, cast_ty_to) { - (Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => (), + (Some(CastTy::Int), Some(CastTy::Ptr(_))) => (), _ => { span_mirbug!( self, @@ -1396,7 +1396,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let cast_ty_from = CastTy::from_ty(ty_from); let cast_ty_to = CastTy::from_ty(*ty); match (cast_ty_from, cast_ty_to) { - (Some(CastTy::Int(_)), Some(CastTy::Int(_))) => (), + (Some(from), Some(to)) if from.is_int_like() && to.is_int_like() => (), _ => { span_mirbug!( self, @@ -1413,7 +1413,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let cast_ty_from = CastTy::from_ty(ty_from); let cast_ty_to = CastTy::from_ty(*ty); match (cast_ty_from, cast_ty_to) { - (Some(CastTy::Int(_)), Some(CastTy::Float)) => (), + (Some(CastTy::Int), Some(CastTy::Float)) => (), _ => { span_mirbug!( self, @@ -1430,7 +1430,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let cast_ty_from = CastTy::from_ty(ty_from); let cast_ty_to = CastTy::from_ty(*ty); match (cast_ty_from, cast_ty_to) { - (Some(CastTy::Float), Some(CastTy::Int(_))) => (), + (Some(CastTy::Float), Some(CastTy::Int)) => (), _ => { span_mirbug!( self, diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index e52da1136dd64..d4817d7ad25ac 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -339,7 +339,9 @@ fn make_format_args( parse::Suggestion::UsePositional => { let captured_arg_span = fmt_span.from_inner(InnerSpan::new(err.span.start, err.span.end)); - if let Ok(arg) = ecx.source_map().span_to_snippet(captured_arg_span) { + if is_source_literal + && let Ok(arg) = ecx.source_map().span_to_snippet(captured_arg_span) + { let span = match args.unnamed_args().last() { Some(arg) => arg.expr.span, None => fmt_span, @@ -360,17 +362,21 @@ fn make_format_args( } } parse::Suggestion::ReorderFormatParameter(span, replacement) => { - let span = fmt_span.from_inner(InnerSpan::new(span.start, span.end)); - e.sugg_ = - Some(diagnostics::InvalidFormatStringSuggestion::ReorderFormatParameter { - span, - replacement, - }); + if is_source_literal { + let span = fmt_span.from_inner(InnerSpan::new(span.start, span.end)); + e.sugg_ = + Some(diagnostics::InvalidFormatStringSuggestion::ReorderFormatParameter { + span, + replacement, + }); + } } parse::Suggestion::AddMissingColon(span) => { - let span = fmt_span.from_inner(InnerSpan::new(span.start, span.end)); - e.sugg_ = - Some(diagnostics::InvalidFormatStringSuggestion::AddMissingColon { span }); + if is_source_literal { + let span = fmt_span.from_inner(InnerSpan::new(span.start, span.end)); + e.sugg_ = + Some(diagnostics::InvalidFormatStringSuggestion::AddMissingColon { span }); + } } parse::Suggestion::UseRustDebugPrintingMacro => { // This targets `println!("{=}", x);` and `println!("{0=}", x);` diff --git a/compiler/rustc_codegen_cranelift/build_system/stdarch_skip/aarch64_core.txt b/compiler/rustc_codegen_cranelift/build_system/stdarch_skip/aarch64_core.txt new file mode 100644 index 0000000000000..3a028cd380029 --- /dev/null +++ b/compiler/rustc_codegen_cranelift/build_system/stdarch_skip/aarch64_core.txt @@ -0,0 +1,301 @@ +vaba_s16 +vaba_s32 +vaba_s8 +vaba_u16 +vaba_u32 +vaba_u8 +vabaq_s16 +vabaq_s32 +vabaq_s8 +vabaq_u16 +vabaq_u32 +vabaq_u8 +vhadd_s16 +vhadd_s32 +vhadd_s8 +vhadd_u16 +vhadd_u32 +vhadd_u8 +vhaddq_s16 +vhaddq_s32 +vhaddq_s8 +vhaddq_u16 +vhaddq_u32 +vhaddq_u8 +vhsub_s16 +vhsub_s32 +vhsub_s8 +vhsub_u16 +vhsub_u32 +vhsub_u8 +vhsubq_s16 +vhsubq_s32 +vhsubq_s8 +vhsubq_u16 +vhsubq_u32 +vhsubq_u8 +vld1_f16_x2 +vld1_f16_x3 +vld1_f16_x4 +vld1_f32_x2 +vld1_f32_x3 +vld1_f32_x4 +vld1_f64_x2 +vld1_f64_x3 +vld1_f64_x4 +vld1_p16_x2 +vld1_p16_x3 +vld1_p16_x4 +vld1_p64_x2 +vld1_p64_x3 +vld1_p64_x4 +vld1_p8_x2 +vld1_p8_x3 +vld1_p8_x4 +vld1_s16_x2 +vld1_s16_x3 +vld1_s16_x4 +vld1_s32_x2 +vld1_s32_x3 +vld1_s32_x4 +vld1_s64_x2 +vld1_s64_x3 +vld1_s64_x4 +vld1_s8_x2 +vld1_s8_x3 +vld1_s8_x4 +vld1_u16_x2 +vld1_u16_x3 +vld1_u16_x4 +vld1_u32_x2 +vld1_u32_x3 +vld1_u32_x4 +vld1_u64_x2 +vld1_u64_x3 +vld1_u64_x4 +vld1_u8_x2 +vld1_u8_x3 +vld1_u8_x4 +vld1q_f16_x2 +vld1q_f16_x3 +vld1q_f16_x4 +vld1q_f32_x2 +vld1q_f32_x3 +vld1q_f32_x4 +vld1q_f64_x2 +vld1q_f64_x3 +vld1q_f64_x4 +vld1q_p16_x2 +vld1q_p16_x3 +vld1q_p16_x4 +vld1q_p64_x2 +vld1q_p64_x3 +vld1q_p64_x4 +vld1q_p8_x2 +vld1q_p8_x3 +vld1q_p8_x4 +vld1q_s16_x2 +vld1q_s16_x3 +vld1q_s16_x4 +vld1q_s32_x2 +vld1q_s32_x3 +vld1q_s32_x4 +vld1q_s64_x2 +vld1q_s64_x3 +vld1q_s64_x4 +vld1q_s8_x2 +vld1q_s8_x3 +vld1q_s8_x4 +vld1q_u16_x2 +vld1q_u16_x3 +vld1q_u16_x4 +vld1q_u32_x2 +vld1q_u32_x3 +vld1q_u32_x4 +vld1q_u64_x2 +vld1q_u64_x3 +vld1q_u64_x4 +vld1q_u8_x2 +vld1q_u8_x3 +vld1q_u8_x4 +vld2_f16 +vld2_f32 +vld2_lane_f16 +vld2_lane_f32 +vld2_lane_s16 +vld2_lane_s32 +vld2_lane_s64 +vld2_lane_s8 +vld2_lane_u16 +vld2_lane_u32 +vld2_lane_u64 +vld2_lane_u8 +vld2_p16 +vld2_p8 +vld2_s16 +vld2_s32 +vld2_s64 +vld2_s8 +vld2_u16 +vld2_u32 +vld2_u64 +vld2_u8 +vld2q_f16 +vld2q_f32 +vld2q_f64 +vld2q_lane_f16 +vld2q_lane_f32 +vld2q_lane_s16 +vld2q_lane_s32 +vld2q_lane_s64 +vld2q_lane_s8 +vld2q_lane_u16 +vld2q_lane_u32 +vld2q_lane_u64 +vld2q_lane_u8 +vld2q_p16 +vld2q_p8 +vld2q_s16 +vld2q_s32 +vld2q_s64 +vld2q_s8 +vld2q_u16 +vld2q_u32 +vld2q_u64 +vld2q_u8 +vld3_f16 +vld3_lane_f16 +vld3_lane_f32 +vld3_lane_s16 +vld3_lane_s32 +vld3_lane_s64 +vld3_lane_s8 +vld3_lane_u16 +vld3_lane_u32 +vld3_lane_u64 +vld3_lane_u8 +vld3q_f16 +vld3q_lane_f16 +vld3q_lane_f32 +vld3q_lane_s16 +vld3q_lane_s32 +vld3q_lane_s64 +vld3q_lane_s8 +vld3q_lane_u16 +vld3q_lane_u32 +vld3q_lane_u64 +vld3q_lane_u8 +vld4_f16 +vld4_lane_f16 +vld4_lane_f32 +vld4_lane_s16 +vld4_lane_s32 +vld4_lane_s64 +vld4_lane_s8 +vld4_lane_u16 +vld4_lane_u32 +vld4_lane_u64 +vld4_lane_u8 +vld4q_f16 +vld4q_lane_f16 +vld4q_lane_f32 +vld4q_lane_s16 +vld4q_lane_s32 +vld4q_lane_s64 +vld4q_lane_s8 +vld4q_lane_u16 +vld4q_lane_u32 +vld4q_lane_u64 +vld4q_lane_u8 +vqtbl2_p8 +vqtbl2_s8 +vqtbl2_u8 +vqtbl2q_p8 +vqtbl2q_s8 +vqtbl2q_u8 +vqtbl3_p8 +vqtbl3_s8 +vqtbl3_u8 +vqtbl3q_p8 +vqtbl3q_s8 +vqtbl3q_u8 +vqtbl4_p8 +vqtbl4_s8 +vqtbl4_u8 +vqtbl4q_p8 +vqtbl4q_s8 +vqtbl4q_u8 +vqtbx1_p8 +vqtbx1_s8 +vqtbx1_u8 +vqtbx1q_p8 +vqtbx1q_s8 +vqtbx1q_u8 +vqtbx2_p8 +vqtbx2_s8 +vqtbx2_u8 +vqtbx2q_p8 +vqtbx2q_s8 +vqtbx2q_u8 +vqtbx3_p8 +vqtbx3_s8 +vqtbx3_u8 +vqtbx3q_p8 +vqtbx3q_s8 +vqtbx3q_u8 +vqtbx4_p8 +vqtbx4_s8 +vqtbx4_u8 +vqtbx4q_p8 +vqtbx4q_s8 +vqtbx4q_u8 +vrhadd_s16 +vrhadd_s32 +vrhadd_s8 +vrhadd_u16 +vrhadd_u32 +vrhadd_u8 +vrhaddq_s16 +vrhaddq_s32 +vrhaddq_s8 +vrhaddq_u16 +vrhaddq_u32 +vrhaddq_u8 +vsli_n_p16 +vsli_n_p8 +vsli_n_s16 +vsli_n_s32 +vsli_n_s64 +vsli_n_s8 +vsli_n_u16 +vsli_n_u32 +vsli_n_u64 +vsli_n_u8 +vsliq_n_p16 +vsliq_n_p8 +vsliq_n_s16 +vsliq_n_s32 +vsliq_n_s64 +vsliq_n_s8 +vsliq_n_u16 +vsliq_n_u32 +vsliq_n_u64 +vsliq_n_u8 +vtbl3_p8 +vtbl3_s8 +vtbl3_u8 +vtbl4_p8 +vtbl4_s8 +vtbl4_u8 +vtbx1_p8 +vtbx1_s8 +vtbx1_u8 +vtbx2_p8 +vtbx2_s8 +vtbx2_u8 +vtbx3_p8 +vtbx3_s8 +vtbx3_u8 +vtbx4_p8 +vtbx4_s8 +vtbx4_u8 diff --git a/compiler/rustc_codegen_cranelift/build_system/stdarch_skip/aarch64_intrinsics_clang.txt b/compiler/rustc_codegen_cranelift/build_system/stdarch_skip/aarch64_intrinsics_clang.txt new file mode 100644 index 0000000000000..5f11867fd3ee9 --- /dev/null +++ b/compiler/rustc_codegen_cranelift/build_system/stdarch_skip/aarch64_intrinsics_clang.txt @@ -0,0 +1 @@ +vcvth_s16_f16 diff --git a/compiler/rustc_codegen_cranelift/build_system/stdarch_skip/aarch64_intrinsics_common.txt b/compiler/rustc_codegen_cranelift/build_system/stdarch_skip/aarch64_intrinsics_common.txt new file mode 100644 index 0000000000000..a452f0c16b593 --- /dev/null +++ b/compiler/rustc_codegen_cranelift/build_system/stdarch_skip/aarch64_intrinsics_common.txt @@ -0,0 +1,1173 @@ +__jcvt +vaba_s16 +vaba_s32 +vaba_s8 +vaba_u16 +vaba_u32 +vaba_u8 +vabal_high_s16 +vabal_high_s32 +vabal_high_s8 +vabal_high_u16 +vabal_high_u32 +vabal_high_u8 +vabal_s16 +vabal_s32 +vabal_s8 +vabal_u16 +vabal_u32 +vabal_u8 +vabaq_s16 +vabaq_s32 +vabaq_s8 +vabaq_u16 +vabaq_u32 +vabaq_u8 +vabd_f16 +vabd_f32 +vabd_f64 +vabd_s16 +vabd_s32 +vabd_s8 +vabd_u16 +vabd_u32 +vabd_u8 +vabdd_f64 +vabdh_f16 +vabdl_high_s16 +vabdl_high_s32 +vabdl_high_s8 +vabdl_high_u16 +vabdl_high_u32 +vabdl_high_u8 +vabdl_s16 +vabdl_s32 +vabdl_s8 +vabdl_u16 +vabdl_u32 +vabdl_u8 +vabdq_f16 +vabdq_f32 +vabdq_f64 +vabdq_s16 +vabdq_s32 +vabdq_s8 +vabdq_u16 +vabdq_u32 +vabdq_u8 +vabds_f32 +vabsd_s64 +vaddlv_s16 +vaddlv_s32 +vaddlv_s8 +vaddlv_u16 +vaddlv_u32 +vaddlv_u8 +vaddlvq_s16 +vaddlvq_s32 +vaddlvq_s8 +vaddlvq_u16 +vaddlvq_u32 +vaddvq_f64 +vamax_f16 +vamaxq_f16 +vamin_f16 +vaminq_f16 +vcadd_rot270_f16 +vcadd_rot270_f32 +vcadd_rot90_f16 +vcadd_rot90_f32 +vcaddq_rot270_f16 +vcaddq_rot270_f32 +vcaddq_rot270_f64 +vcaddq_rot90_f16 +vcaddq_rot90_f32 +vcaddq_rot90_f64 +vcage_f16 +vcage_f32 +vcage_f64 +vcaged_f64 +vcageh_f16 +vcageq_f16 +vcageq_f32 +vcageq_f64 +vcages_f32 +vcagt_f16 +vcagt_f32 +vcagt_f64 +vcagtd_f64 +vcagth_f16 +vcagtq_f16 +vcagtq_f32 +vcagtq_f64 +vcagts_f32 +vcale_f16 +vcale_f32 +vcale_f64 +vcaled_f64 +vcaleh_f16 +vcaleq_f16 +vcaleq_f32 +vcaleq_f64 +vcales_f32 +vcalt_f16 +vcalt_f32 +vcalt_f64 +vcaltd_f64 +vcalth_f16 +vcaltq_f16 +vcaltq_f32 +vcaltq_f64 +vcalts_f32 +vcmla_f16 +vcmla_f32 +vcmla_lane_f16 +vcmla_lane_f32 +vcmla_laneq_f16 +vcmla_laneq_f32 +vcmla_rot180_f16 +vcmla_rot180_f32 +vcmla_rot180_lane_f16 +vcmla_rot180_lane_f32 +vcmla_rot180_laneq_f16 +vcmla_rot180_laneq_f32 +vcmla_rot270_f16 +vcmla_rot270_f32 +vcmla_rot270_lane_f16 +vcmla_rot270_lane_f32 +vcmla_rot270_laneq_f16 +vcmla_rot270_laneq_f32 +vcmla_rot90_f16 +vcmla_rot90_f32 +vcmla_rot90_lane_f16 +vcmla_rot90_lane_f32 +vcmla_rot90_laneq_f16 +vcmla_rot90_laneq_f32 +vcmlaq_f16 +vcmlaq_f32 +vcmlaq_f64 +vcmlaq_lane_f16 +vcmlaq_lane_f32 +vcmlaq_laneq_f16 +vcmlaq_laneq_f32 +vcmlaq_rot180_f16 +vcmlaq_rot180_f32 +vcmlaq_rot180_f64 +vcmlaq_rot180_lane_f16 +vcmlaq_rot180_lane_f32 +vcmlaq_rot180_laneq_f16 +vcmlaq_rot180_laneq_f32 +vcmlaq_rot270_f16 +vcmlaq_rot270_f32 +vcmlaq_rot270_f64 +vcmlaq_rot270_lane_f16 +vcmlaq_rot270_lane_f32 +vcmlaq_rot270_laneq_f16 +vcmlaq_rot270_laneq_f32 +vcmlaq_rot90_f16 +vcmlaq_rot90_f32 +vcmlaq_rot90_f64 +vcmlaq_rot90_lane_f16 +vcmlaq_rot90_lane_f32 +vcmlaq_rot90_laneq_f16 +vcmlaq_rot90_laneq_f32 +vcvt_n_f16_s16 +vcvt_n_f16_u16 +vcvt_n_f32_s32 +vcvt_n_f32_u32 +vcvt_n_f64_s64 +vcvt_n_f64_u64 +vcvt_n_s16_f16 +vcvt_n_s32_f32 +vcvt_n_s64_f64 +vcvt_n_u16_f16 +vcvt_n_u32_f32 +vcvt_n_u64_f64 +vcvt_s32_f32 +vcvt_s64_f64 +vcvt_u32_f32 +vcvt_u64_f64 +vcvta_s16_f16 +vcvta_s32_f32 +vcvta_s64_f64 +vcvta_u16_f16 +vcvta_u32_f32 +vcvta_u64_f64 +vcvtad_s64_f64 +vcvtad_u64_f64 +vcvtah_s16_f16 +vcvtah_s32_f16 +vcvtah_s64_f16 +vcvtah_u16_f16 +vcvtah_u32_f16 +vcvtah_u64_f16 +vcvtaq_s16_f16 +vcvtaq_s32_f32 +vcvtaq_s64_f64 +vcvtaq_u16_f16 +vcvtaq_u32_f32 +vcvtaq_u64_f64 +vcvtas_s32_f32 +vcvtas_u32_f32 +vcvtd_n_f64_s64 +vcvtd_n_f64_u64 +vcvtd_n_s64_f64 +vcvtd_n_u64_f64 +vcvth_n_f16_s16 +vcvth_n_f16_s32 +vcvth_n_f16_s64 +vcvth_n_f16_u16 +vcvth_n_f16_u32 +vcvth_n_f16_u64 +vcvth_n_s16_f16 +vcvth_n_s32_f16 +vcvth_n_s64_f16 +vcvth_n_u16_f16 +vcvth_n_u32_f16 +vcvth_n_u64_f16 +vcvtm_s16_f16 +vcvtm_s32_f32 +vcvtm_s64_f64 +vcvtm_u16_f16 +vcvtm_u32_f32 +vcvtm_u64_f64 +vcvtmd_s64_f64 +vcvtmd_u64_f64 +vcvtmh_s16_f16 +vcvtmh_s32_f16 +vcvtmh_s64_f16 +vcvtmh_u16_f16 +vcvtmh_u32_f16 +vcvtmh_u64_f16 +vcvtmq_s16_f16 +vcvtmq_s32_f32 +vcvtmq_s64_f64 +vcvtmq_u16_f16 +vcvtmq_u32_f32 +vcvtmq_u64_f64 +vcvtms_s32_f32 +vcvtms_u32_f32 +vcvtn_s16_f16 +vcvtn_s32_f32 +vcvtn_s64_f64 +vcvtn_u16_f16 +vcvtn_u32_f32 +vcvtn_u64_f64 +vcvtnd_s64_f64 +vcvtnd_u64_f64 +vcvtnh_s16_f16 +vcvtnh_s32_f16 +vcvtnh_s64_f16 +vcvtnh_u16_f16 +vcvtnh_u32_f16 +vcvtnh_u64_f16 +vcvtnq_s16_f16 +vcvtnq_s64_f64 +vcvtnq_u16_f16 +vcvtnq_u32_f32 +vcvtnq_u64_f64 +vcvtns_s32_f32 +vcvtns_u32_f32 +vcvtp_s16_f16 +vcvtp_s32_f32 +vcvtp_s64_f64 +vcvtp_u16_f16 +vcvtp_u32_f32 +vcvtp_u64_f64 +vcvtpd_s64_f64 +vcvtpd_u64_f64 +vcvtph_s16_f16 +vcvtph_s32_f16 +vcvtph_s64_f16 +vcvtph_u16_f16 +vcvtph_u32_f16 +vcvtph_u64_f16 +vcvtpq_s16_f16 +vcvtpq_s32_f32 +vcvtpq_s64_f64 +vcvtpq_u16_f16 +vcvtpq_u32_f32 +vcvtpq_u64_f64 +vcvtps_s32_f32 +vcvtps_u32_f32 +vcvtq_n_f16_s16 +vcvtq_n_f16_u16 +vcvtq_n_f32_s32 +vcvtq_n_f32_u32 +vcvtq_n_f64_s64 +vcvtq_n_f64_u64 +vcvtq_n_s16_f16 +vcvtq_n_s32_f32 +vcvtq_n_s64_f64 +vcvtq_n_u16_f16 +vcvtq_n_u32_f32 +vcvtq_n_u64_f64 +vcvtq_s64_f64 +vcvtq_u32_f32 +vcvtq_u64_f64 +vcvts_n_f32_s32 +vcvts_n_f32_u32 +vcvts_n_s32_f32 +vcvts_n_u32_f32 +vcvtx_f32_f64 +vcvtx_high_f32_f64 +vcvtxd_f32_f64 +vdot_lane_s32 +vdot_lane_u32 +vdot_laneq_s32 +vdot_laneq_u32 +vdot_s32 +vdot_u32 +vdotq_lane_s32 +vdotq_lane_u32 +vdotq_laneq_s32 +vdotq_laneq_u32 +vdotq_s32 +vdotq_u32 +vfmlal_high_f16 +vfmlal_lane_high_f16 +vfmlal_lane_low_f16 +vfmlal_laneq_high_f16 +vfmlal_laneq_low_f16 +vfmlal_low_f16 +vfmlalq_high_f16 +vfmlalq_lane_high_f16 +vfmlalq_lane_low_f16 +vfmlalq_laneq_high_f16 +vfmlalq_laneq_low_f16 +vfmlalq_low_f16 +vfmlsl_high_f16 +vfmlsl_lane_high_f16 +vfmlsl_lane_low_f16 +vfmlsl_laneq_high_f16 +vfmlsl_laneq_low_f16 +vfmlsl_low_f16 +vfmlslq_high_f16 +vfmlslq_lane_high_f16 +vfmlslq_lane_low_f16 +vfmlslq_laneq_high_f16 +vfmlslq_laneq_low_f16 +vfmlslq_low_f16 +vhadd_s16 +vhadd_s32 +vhadd_s8 +vhadd_u16 +vhadd_u32 +vhadd_u8 +vhaddq_s16 +vhaddq_s32 +vhaddq_s8 +vhaddq_u16 +vhaddq_u32 +vhaddq_u8 +vhsub_s16 +vhsub_s32 +vhsub_s8 +vhsub_u16 +vhsub_u32 +vhsub_u8 +vhsubq_s16 +vhsubq_s32 +vhsubq_s8 +vhsubq_u16 +vhsubq_u32 +vhsubq_u8 +vld1_dup_f16 +vld1_f16 +vld1_f16_x2 +vld1_f16_x3 +vld1_f16_x4 +vld1_lane_f16 +vld1q_dup_f16 +vld1q_f16 +vld1q_f16_x2 +vld1q_f16_x3 +vld1q_f16_x4 +vld1q_lane_f16 +vld2_dup_f16 +vld2_f16 +vld2_lane_f16 +vld2q_dup_f16 +vld2q_f16 +vld2q_lane_f16 +vld3_dup_f16 +vld3_f16 +vld3_lane_f16 +vld3q_dup_f16 +vld3q_f16 +vld3q_lane_f16 +vld4_dup_f16 +vld4_f16 +vld4_lane_f16 +vld4q_dup_f16 +vld4q_f16 +vld4q_lane_f16 +vluti2_lane_f16 +vluti2_laneq_f16 +vluti2q_lane_f16 +vluti2q_laneq_f16 +vluti4q_lane_f16_x2 +vluti4q_laneq_f16_x2 +vmax_f16 +vmaxh_f16 +vmaxnm_f16 +vmaxnm_f32 +vmaxnm_f64 +vmaxnmh_f16 +vmaxnmq_f16 +vmaxnmq_f32 +vmaxnmq_f64 +vmaxnmv_f16 +vmaxnmv_f32 +vmaxnmvq_f16 +vmaxnmvq_f32 +vmaxnmvq_f64 +vmaxq_f16 +vmaxv_f16 +vmaxv_f32 +vmaxvq_f16 +vmaxvq_f32 +vmaxvq_f64 +vmin_f16 +vminh_f16 +vminnm_f16 +vminnm_f32 +vminnm_f64 +vminnmh_f16 +vminnmq_f16 +vminnmq_f32 +vminnmq_f64 +vminnmv_f16 +vminnmv_f32 +vminnmvq_f16 +vminnmvq_f32 +vminnmvq_f64 +vminq_f16 +vminv_f16 +vminv_f32 +vminvq_f16 +vminvq_f32 +vminvq_f64 +vmmlaq_s32 +vmmlaq_u32 +vmul_p8 +vmulq_p8 +vmulx_f16 +vmulx_f32 +vmulx_f64 +vmulx_lane_f16 +vmulx_lane_f32 +vmulx_lane_f64 +vmulx_laneq_f16 +vmulx_laneq_f32 +vmulx_laneq_f64 +vmulx_n_f16 +vmulxd_f64 +vmulxd_lane_f64 +vmulxd_laneq_f64 +vmulxh_f16 +vmulxh_lane_f16 +vmulxh_laneq_f16 +vmulxq_f16 +vmulxq_f32 +vmulxq_f64 +vmulxq_lane_f16 +vmulxq_lane_f32 +vmulxq_lane_f64 +vmulxq_laneq_f16 +vmulxq_laneq_f32 +vmulxq_laneq_f64 +vmulxq_n_f16 +vmulxs_f32 +vmulxs_lane_f32 +vmulxs_laneq_f32 +vpadd_f16 +vpadd_f32 +vpaddq_f16 +vpmax_f16 +vpmaxnm_f16 +vpmaxnm_f32 +vpmaxnmq_f16 +vpmaxnmq_f32 +vpmaxnmq_f64 +vpmaxnmqd_f64 +vpmaxnms_f32 +vpmaxq_f16 +vpmaxqd_f64 +vpmaxs_f32 +vpmin_f16 +vpminnm_f16 +vpminnm_f32 +vpminnmq_f16 +vpminnmq_f32 +vpminnmq_f64 +vpminnmqd_f64 +vpminnms_f32 +vpminq_f16 +vpminqd_f64 +vpmins_f32 +vqabs_s16 +vqabs_s32 +vqabs_s64 +vqabs_s8 +vqabsb_s8 +vqabsd_s64 +vqabsh_s16 +vqabsq_s16 +vqabsq_s32 +vqabsq_s64 +vqabsq_s8 +vqabss_s32 +vqaddd_s64 +vqaddd_u64 +vqadds_s32 +vqadds_u32 +vqdmlal_high_lane_s16 +vqdmlal_high_lane_s32 +vqdmlal_high_laneq_s16 +vqdmlal_high_laneq_s32 +vqdmlal_high_n_s16 +vqdmlal_high_n_s32 +vqdmlal_high_s16 +vqdmlal_high_s32 +vqdmlal_lane_s16 +vqdmlal_lane_s32 +vqdmlal_laneq_s16 +vqdmlal_laneq_s32 +vqdmlal_n_s16 +vqdmlal_n_s32 +vqdmlal_s16 +vqdmlal_s32 +vqdmlalh_lane_s16 +vqdmlalh_laneq_s16 +vqdmlalh_s16 +vqdmlals_lane_s32 +vqdmlals_laneq_s32 +vqdmlals_s32 +vqdmlsl_high_lane_s16 +vqdmlsl_high_lane_s32 +vqdmlsl_high_laneq_s16 +vqdmlsl_high_laneq_s32 +vqdmlsl_high_n_s16 +vqdmlsl_high_n_s32 +vqdmlsl_high_s16 +vqdmlsl_high_s32 +vqdmlsl_lane_s16 +vqdmlsl_lane_s32 +vqdmlsl_laneq_s16 +vqdmlsl_laneq_s32 +vqdmlsl_n_s16 +vqdmlsl_n_s32 +vqdmlsl_s16 +vqdmlsl_s32 +vqdmlslh_lane_s16 +vqdmlslh_laneq_s16 +vqdmlslh_s16 +vqdmlsls_lane_s32 +vqdmlsls_laneq_s32 +vqdmlsls_s32 +vqdmull_high_lane_s16 +vqdmull_high_lane_s32 +vqdmull_high_laneq_s16 +vqdmull_high_laneq_s32 +vqdmull_high_n_s16 +vqdmull_high_n_s32 +vqdmull_high_s16 +vqdmull_high_s32 +vqdmull_lane_s16 +vqdmull_lane_s32 +vqdmull_laneq_s16 +vqdmull_laneq_s32 +vqdmull_n_s16 +vqdmull_n_s32 +vqdmull_s16 +vqdmull_s32 +vqdmullh_lane_s16 +vqdmullh_laneq_s16 +vqdmullh_s16 +vqdmulls_lane_s32 +vqdmulls_laneq_s32 +vqdmulls_s32 +vqmovn_high_s16 +vqmovn_high_s32 +vqmovn_high_s64 +vqmovn_high_u16 +vqmovn_high_u32 +vqmovn_high_u64 +vqmovn_s16 +vqmovn_s32 +vqmovn_s64 +vqmovn_u16 +vqmovn_u32 +vqmovn_u64 +vqmovnd_s64 +vqmovnd_u64 +vqmovnh_s16 +vqmovnh_u16 +vqmovns_s32 +vqmovns_u32 +vqmovun_high_s16 +vqmovun_high_s32 +vqmovun_high_s64 +vqmovun_s16 +vqmovun_s32 +vqmovun_s64 +vqmovund_s64 +vqmovunh_s16 +vqmovuns_s32 +vqneg_s16 +vqneg_s32 +vqneg_s64 +vqneg_s8 +vqnegb_s8 +vqnegd_s64 +vqnegh_s16 +vqnegq_s16 +vqnegq_s32 +vqnegq_s64 +vqnegq_s8 +vqnegs_s32 +vqrdmlah_lane_s16 +vqrdmlah_lane_s32 +vqrdmlah_laneq_s16 +vqrdmlah_laneq_s32 +vqrdmlah_s16 +vqrdmlah_s32 +vqrdmlahh_lane_s16 +vqrdmlahh_laneq_s16 +vqrdmlahh_s16 +vqrdmlahq_lane_s16 +vqrdmlahq_lane_s32 +vqrdmlahq_laneq_s16 +vqrdmlahq_laneq_s32 +vqrdmlahq_s16 +vqrdmlahq_s32 +vqrdmlahs_lane_s32 +vqrdmlahs_laneq_s32 +vqrdmlahs_s32 +vqrdmlsh_lane_s16 +vqrdmlsh_lane_s32 +vqrdmlsh_laneq_s16 +vqrdmlsh_laneq_s32 +vqrdmlsh_s16 +vqrdmlsh_s32 +vqrdmlshh_lane_s16 +vqrdmlshh_laneq_s16 +vqrdmlshh_s16 +vqrdmlshq_lane_s16 +vqrdmlshq_lane_s32 +vqrdmlshq_laneq_s16 +vqrdmlshq_laneq_s32 +vqrdmlshq_s16 +vqrdmlshq_s32 +vqrdmlshs_lane_s32 +vqrdmlshs_laneq_s32 +vqrdmlshs_s32 +vqrdmulh_lane_s16 +vqrdmulh_lane_s32 +vqrdmulh_laneq_s16 +vqrdmulh_laneq_s32 +vqrdmulh_n_s16 +vqrdmulh_n_s32 +vqrdmulh_s16 +vqrdmulh_s32 +vqrdmulhh_lane_s16 +vqrdmulhh_laneq_s16 +vqrdmulhh_s16 +vqrdmulhq_lane_s16 +vqrdmulhq_lane_s32 +vqrdmulhq_laneq_s16 +vqrdmulhq_laneq_s32 +vqrdmulhq_n_s16 +vqrdmulhq_n_s32 +vqrdmulhq_s16 +vqrdmulhq_s32 +vqrdmulhs_lane_s32 +vqrdmulhs_laneq_s32 +vqrdmulhs_s32 +vqrshl_s16 +vqrshl_s32 +vqrshl_s64 +vqrshl_s8 +vqrshl_u16 +vqrshl_u32 +vqrshl_u64 +vqrshl_u8 +vqrshlb_s8 +vqrshlb_u8 +vqrshld_s64 +vqrshld_u64 +vqrshlh_s16 +vqrshlh_u16 +vqrshlq_s16 +vqrshlq_s32 +vqrshlq_s64 +vqrshlq_s8 +vqrshlq_u16 +vqrshlq_u32 +vqrshlq_u64 +vqrshlq_u8 +vqrshls_s32 +vqrshls_u32 +vqrshrn_high_n_s16 +vqrshrn_high_n_s32 +vqrshrn_high_n_s64 +vqrshrn_high_n_u16 +vqrshrn_high_n_u32 +vqrshrn_high_n_u64 +vqrshrn_n_s16 +vqrshrn_n_s32 +vqrshrn_n_s64 +vqrshrn_n_u16 +vqrshrn_n_u32 +vqrshrn_n_u64 +vqrshrnd_n_s64 +vqrshrnd_n_u64 +vqrshrnh_n_s16 +vqrshrnh_n_u16 +vqrshrns_n_s32 +vqrshrns_n_u32 +vqrshrun_high_n_s16 +vqrshrun_high_n_s32 +vqrshrun_high_n_s64 +vqrshrun_n_s16 +vqrshrun_n_s32 +vqrshrun_n_s64 +vqrshrund_n_s64 +vqrshrunh_n_s16 +vqrshruns_n_s32 +vqshl_n_s16 +vqshl_n_s32 +vqshl_n_s64 +vqshl_n_s8 +vqshl_n_u16 +vqshl_n_u32 +vqshl_n_u64 +vqshl_n_u8 +vqshl_s16 +vqshl_s32 +vqshl_s64 +vqshl_s8 +vqshl_u16 +vqshl_u32 +vqshl_u64 +vqshl_u8 +vqshlb_n_s8 +vqshlb_n_u8 +vqshlb_s8 +vqshlb_u8 +vqshld_n_s64 +vqshld_n_u64 +vqshld_s64 +vqshld_u64 +vqshlh_n_s16 +vqshlh_n_u16 +vqshlh_s16 +vqshlh_u16 +vqshlq_n_s16 +vqshlq_n_s32 +vqshlq_n_s64 +vqshlq_n_s8 +vqshlq_n_u16 +vqshlq_n_u32 +vqshlq_n_u64 +vqshlq_n_u8 +vqshlq_s16 +vqshlq_s32 +vqshlq_s64 +vqshlq_s8 +vqshlq_u16 +vqshlq_u32 +vqshlq_u64 +vqshlq_u8 +vqshls_n_s32 +vqshls_n_u32 +vqshls_s32 +vqshls_u32 +vqshlu_n_s16 +vqshlu_n_s32 +vqshlu_n_s64 +vqshlu_n_s8 +vqshlub_n_s8 +vqshlud_n_s64 +vqshluh_n_s16 +vqshluq_n_s16 +vqshluq_n_s32 +vqshluq_n_s64 +vqshluq_n_s8 +vqshlus_n_s32 +vqshrn_high_n_s16 +vqshrn_high_n_s32 +vqshrn_high_n_s64 +vqshrn_high_n_u16 +vqshrn_high_n_u32 +vqshrn_high_n_u64 +vqshrn_n_s16 +vqshrn_n_s32 +vqshrn_n_s64 +vqshrn_n_u16 +vqshrn_n_u32 +vqshrn_n_u64 +vqshrnd_n_s64 +vqshrnd_n_u64 +vqshrnh_n_s16 +vqshrnh_n_u16 +vqshrns_n_s32 +vqshrns_n_u32 +vqshrun_high_n_s16 +vqshrun_high_n_s32 +vqshrun_high_n_s64 +vqshrun_n_s16 +vqshrun_n_s32 +vqshrun_n_s64 +vqshrund_n_s64 +vqshrunh_n_s16 +vqshruns_n_s32 +vqsubd_s64 +vqsubd_u64 +vqsubs_s32 +vqsubs_u32 +vqtbl2_p8 +vqtbl2_s8 +vqtbl2_u8 +vqtbl2q_p8 +vqtbl2q_s8 +vqtbl2q_u8 +vqtbl3_p8 +vqtbl3_s8 +vqtbl3_u8 +vqtbl3q_p8 +vqtbl3q_s8 +vqtbl3q_u8 +vqtbl4_p8 +vqtbl4_s8 +vqtbl4_u8 +vqtbl4q_p8 +vqtbl4q_s8 +vqtbl4q_u8 +vqtbx1_p8 +vqtbx1_s8 +vqtbx1_u8 +vqtbx1q_p8 +vqtbx1q_s8 +vqtbx1q_u8 +vqtbx2_p8 +vqtbx2_s8 +vqtbx2_u8 +vqtbx2q_p8 +vqtbx2q_s8 +vqtbx2q_u8 +vqtbx3_p8 +vqtbx3_s8 +vqtbx3_u8 +vqtbx3q_p8 +vqtbx3q_s8 +vqtbx3q_u8 +vqtbx4_p8 +vqtbx4_s8 +vqtbx4_u8 +vqtbx4q_p8 +vqtbx4q_s8 +vqtbx4q_u8 +vraddhn_high_s16 +vraddhn_high_s32 +vraddhn_high_s64 +vraddhn_high_u16 +vraddhn_high_u32 +vraddhn_high_u64 +vraddhn_s16 +vraddhn_s32 +vraddhn_s64 +vraddhn_u16 +vraddhn_u32 +vraddhn_u64 +vrecpe_f16 +vrecpe_f32 +vrecpe_f64 +vrecpe_u32 +vrecped_f64 +vrecpeh_f16 +vrecpeq_f16 +vrecpeq_f64 +vrecpeq_u32 +vrecpes_f32 +vrecps_f16 +vrecps_f32 +vrecps_f64 +vrecpsd_f64 +vrecpsh_f16 +vrecpsq_f16 +vrecpsq_f64 +vrecpss_f32 +vrecpxd_f64 +vrecpxh_f16 +vrecpxs_f32 +vreinterpretq_f16_p128 +vrhadd_s16 +vrhadd_s32 +vrhadd_s8 +vrhadd_u16 +vrhadd_u32 +vrhadd_u8 +vrhaddq_s16 +vrhaddq_s32 +vrhaddq_s8 +vrhaddq_u16 +vrhaddq_u32 +vrhaddq_u8 +vrnd32x_f32 +vrnd32x_f64 +vrnd32xq_f32 +vrnd32xq_f64 +vrnd32z_f32 +vrnd32z_f64 +vrnd32zq_f32 +vrnd32zq_f64 +vrnd64x_f32 +vrnd64x_f64 +vrnd64xq_f32 +vrnd64xq_f64 +vrnd64z_f32 +vrnd64z_f64 +vrnd64zq_f32 +vrnd64zq_f64 +vrndi_f16 +vrndi_f32 +vrndi_f64 +vrndih_f16 +vrndiq_f16 +vrndiq_f32 +vrndiq_f64 +vrndn_f16 +vrndnh_f16 +vrndnq_f16 +vrndns_f32 +vrshl_s16 +vrshl_s32 +vrshl_s64 +vrshl_s8 +vrshl_u16 +vrshl_u32 +vrshl_u64 +vrshl_u8 +vrshld_s64 +vrshld_u64 +vrshlq_s16 +vrshlq_s32 +vrshlq_s64 +vrshlq_s8 +vrshlq_u16 +vrshlq_u32 +vrshlq_u64 +vrshlq_u8 +vrshr_n_s16 +vrshr_n_s32 +vrshr_n_s64 +vrshr_n_s8 +vrshr_n_u16 +vrshr_n_u32 +vrshr_n_u64 +vrshr_n_u8 +vrshrd_n_s64 +vrshrd_n_u64 +vrshrn_high_n_s16 +vrshrn_high_n_s32 +vrshrn_high_n_s64 +vrshrn_high_n_u16 +vrshrn_high_n_u32 +vrshrn_high_n_u64 +vrshrn_n_s16 +vrshrn_n_s32 +vrshrn_n_s64 +vrshrn_n_u16 +vrshrn_n_u32 +vrshrn_n_u64 +vrshrq_n_s16 +vrshrq_n_s32 +vrshrq_n_s64 +vrshrq_n_s8 +vrshrq_n_u16 +vrshrq_n_u32 +vrshrq_n_u64 +vrshrq_n_u8 +vrsqrte_f16 +vrsqrte_f32 +vrsqrte_f64 +vrsqrte_u32 +vrsqrted_f64 +vrsqrteh_f16 +vrsqrteq_f16 +vrsqrteq_f32 +vrsqrteq_f64 +vrsqrteq_u32 +vrsqrtes_f32 +vrsqrts_f16 +vrsqrts_f32 +vrsqrts_f64 +vrsqrtsd_f64 +vrsqrtsh_f16 +vrsqrtsq_f16 +vrsqrtsq_f32 +vrsqrtsq_f64 +vrsqrtss_f32 +vrsra_n_s16 +vrsra_n_s32 +vrsra_n_s64 +vrsra_n_s8 +vrsra_n_u16 +vrsra_n_u32 +vrsra_n_u64 +vrsra_n_u8 +vrsrad_n_s64 +vrsrad_n_u64 +vrsraq_n_s16 +vrsraq_n_s32 +vrsraq_n_s64 +vrsraq_n_s8 +vrsraq_n_u16 +vrsraq_n_u32 +vrsraq_n_u64 +vrsraq_n_u8 +vrsubhn_high_s16 +vrsubhn_high_s32 +vrsubhn_high_s64 +vrsubhn_high_u16 +vrsubhn_high_u32 +vrsubhn_high_u64 +vrsubhn_s16 +vrsubhn_s32 +vrsubhn_s64 +vrsubhn_u16 +vrsubhn_u32 +vrsubhn_u64 +vscale_f16 +vscaleq_f16 +vshl_s16 +vshl_s32 +vshl_s64 +vshl_s8 +vshl_u16 +vshl_u32 +vshl_u64 +vshl_u8 +vshld_s64 +vshld_u64 +vshlq_s16 +vshlq_s32 +vshlq_s64 +vshlq_s8 +vshlq_u16 +vshlq_u32 +vshlq_u64 +vshlq_u8 +vsli_n_p16 +vsli_n_p64 +vsli_n_p8 +vsli_n_s16 +vsli_n_s32 +vsli_n_s64 +vsli_n_s8 +vsli_n_u16 +vsli_n_u32 +vsli_n_u64 +vsli_n_u8 +vslid_n_s64 +vslid_n_u64 +vsliq_n_p16 +vsliq_n_p64 +vsliq_n_p8 +vsliq_n_s16 +vsliq_n_s32 +vsliq_n_s64 +vsliq_n_s8 +vsliq_n_u16 +vsliq_n_u32 +vsliq_n_u64 +vsliq_n_u8 +vsm3partw1q_u32 +vsm3partw2q_u32 +vsm3ss1q_u32 +vsm3tt1aq_u32 +vsm3tt1bq_u32 +vsm3tt2aq_u32 +vsm3tt2bq_u32 +vsm4ekeyq_u32 +vsm4eq_u32 +vsqadd_u16 +vsqadd_u32 +vsqadd_u64 +vsqadd_u8 +vsqaddb_u8 +vsqaddd_u64 +vsqaddh_u16 +vsqaddq_u16 +vsqaddq_u32 +vsqaddq_u64 +vsqaddq_u8 +vsqadds_u32 +vst1_f16 +vst1_f16_x2 +vst1_f16_x3 +vst1_f16_x4 +vst1_lane_f16 +vst1q_f16 +vst1q_f16_x2 +vst1q_f16_x3 +vst1q_f16_x4 +vst1q_lane_f16 +vst2_f16 +vst2_lane_f16 +vst2q_f16 +vst2q_lane_f16 +vst3_f16 +vst3_lane_f16 +vst3q_f16 +vst3q_lane_f16 +vst4_f16 +vst4_lane_f16 +vst4q_f16 +vst4q_lane_f16 +vsudot_lane_s32 +vsudot_laneq_s32 +vsudotq_lane_s32 +vsudotq_laneq_s32 +vtbl2_p8 +vtbl2_s8 +vtbl2_u8 +vtbl3_p8 +vtbl3_s8 +vtbl3_u8 +vtbl4_p8 +vtbl4_s8 +vtbl4_u8 +vtbx1_p8 +vtbx1_s8 +vtbx1_u8 +vtbx2_p8 +vtbx2_s8 +vtbx2_u8 +vtbx3_p8 +vtbx3_s8 +vtbx3_u8 +vtbx4_p8 +vtbx4_s8 +vtbx4_u8 +vuqadd_s16 +vuqadd_s32 +vuqadd_s64 +vuqadd_s8 +vuqaddb_s8 +vuqaddd_s64 +vuqaddh_s16 +vuqaddq_s16 +vuqaddq_s32 +vuqaddq_s64 +vuqaddq_s8 +vuqadds_s32 +vusdot_lane_s32 +vusdot_laneq_s32 +vusdot_s32 +vusdotq_lane_s32 +vusdotq_laneq_s32 +vusdotq_s32 +vusmmlaq_s32 diff --git a/compiler/rustc_codegen_cranelift/build_system/tests.rs b/compiler/rustc_codegen_cranelift/build_system/tests.rs index 5ae76dc1e591e..3b9ae2608abfe 100644 --- a/compiler/rustc_codegen_cranelift/build_system/tests.rs +++ b/compiler/rustc_codegen_cranelift/build_system/tests.rs @@ -1,4 +1,5 @@ use std::ffi::OsStr; +use std::fs; use std::path::PathBuf; use std::process::Command; @@ -108,7 +109,6 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[ }), TestCase::build_bin_and_run("aot.issue-72793", "example/issue-72793.rs", &[]), TestCase::build_bin("aot.issue-59326", "example/issue-59326.rs"), - TestCase::build_bin_and_run("aot.neon", "example/neon.rs", &[]), TestCase::build_bin_and_run("aot.gen_block_iterate", "example/gen_block_iterate.rs", &[]), TestCase::build_bin_and_run("aot.raw-dylib", "example/raw-dylib.rs", &[]), TestCase::custom("test.sysroot", &|runner| { @@ -182,6 +182,12 @@ static SYSROOT_TESTS_SRC: RelPath = RelPath::build("sysroot_tests"); static SYSROOT_TESTS: CargoProject = CargoProject::new(SYSROOT_TESTS_SRC, "sysroot_tests_target"); +static STDARCH_SRC: RelPath = RelPath::build("stdarch"); + +static STDARCH: CargoProject = CargoProject::new(STDARCH_SRC, "stdarch_target"); +static STDARCH_RUST_PROGRAMS: CargoProject = + CargoProject::new(RelPath::build("stdarch/rust_programs"), "stdarch_rust_programs_target"); + const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ TestCase::custom("test.rust-random/rand", &|runner| { RAND_REPO.patch(&runner.dirs); @@ -283,6 +289,116 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ spawn_and_wait(test_cmd); } }), + TestCase::custom("test.stdarch-core", &|runner| { + let target = runner.target_compiler.target.as_str(); + let (arch, _) = target.split_once('-').unwrap(); + + // FIXME: Add support for remaining architectures. + if !["aarch64"].contains(&arch) { + eprintln!("Skipping `stdarch-core` tests: unsupported target"); + return; + } + + apply_patches( + &runner.dirs, + "stdarch", + &runner.stdlib_source.join("library/stdarch"), + &STDARCH_SRC.to_path(&runner.dirs), + ); + + STDARCH.clean(&runner.dirs); + + let skip = format!("build_system/stdarch_skip/{arch}_core.txt"); + let skip = fs::read_to_string(runner.dirs.source_dir.join(skip)).unwrap_or_default(); + + let skip_functions = skip + .lines() + .map(str::trim) + .filter(|line| !line.is_empty() && !line.starts_with('#')) + .collect::>() + .join(","); + + if runner.is_native { + let mut test_cmd = STDARCH.test(&runner.target_compiler, &runner.dirs); + + test_cmd.env("TARGET", target); + test_cmd.env("STDARCH_TEST_SKIP_FUNCTION", &skip_functions); + + test_cmd.args(["-p", "core_arch", "--tests", "--", "-q"]); + spawn_and_wait(test_cmd); + } else { + eprintln!("Cross-Compiling: Not running tests"); + let mut build_cmd = STDARCH.build(&runner.target_compiler, &runner.dirs); + + build_cmd.env("TARGET", target); + + build_cmd.args(["-p", "core_arch", "--tests"]); + spawn_and_wait(build_cmd); + } + }), + TestCase::custom("test.stdarch-intrinsics", &|runner| { + let target = runner.target_compiler.target.as_str(); + let (arch, _) = target.split_once('-').unwrap(); + + // FIXME: Add support for remaining architectures. + let input = match arch { + "aarch64" => "intrinsics_data/arm_intrinsics.json", + _ => { + eprintln!("Skipping `stdarch-intrinsics` tests: unsupported target"); + return; + } + }; + + apply_patches( + &runner.dirs, + "stdarch", + &runner.stdlib_source.join("library/stdarch"), + &STDARCH_SRC.to_path(&runner.dirs), + ); + + STDARCH_RUST_PROGRAMS.clean(&runner.dirs); + + if !runner.is_native { + eprintln!("Cross-Compiling: Not running tests"); + return; + } + + let cc = if target.contains("apple") { "clang" } else { "gcc" }; + + let mut generate_cmd = STDARCH.run(&runner.target_compiler, &runner.dirs); + generate_cmd.current_dir(STDARCH.source_dir(&runner.dirs)); + generate_cmd.args([ + "-p", + "intrinsic-test", + "--", + input, + "--target", + target, + "--cc-arg-style", + cc, + "--skip", + &format!("crates/intrinsic-test/missing_{arch}_common.txt"), + "--skip", + &format!("crates/intrinsic-test/missing_{arch}_{cc}.txt"), + ]); + + for skip in [ + format!("build_system/stdarch_skip/{arch}_intrinsics_common.txt"), + format!("build_system/stdarch_skip/{arch}_intrinsics_{cc}.txt"), + ] { + let skip = runner.dirs.source_dir.join(skip); + + if skip.exists() { + generate_cmd.arg("--skip").arg(skip); + } + } + + spawn_and_wait(generate_cmd); + + let mut test_cmd = STDARCH_RUST_PROGRAMS.test(&runner.target_compiler, &runner.dirs); + test_cmd.args(["--workspace", "--tests", "--no-fail-fast", "--", "-q"]); + spawn_and_wait(test_cmd); + }), ]; pub(crate) fn run_tests( diff --git a/compiler/rustc_codegen_cranelift/config.txt b/compiler/rustc_codegen_cranelift/config.txt index ca126f4e39e29..c1068e6257d73 100644 --- a/compiler/rustc_codegen_cranelift/config.txt +++ b/compiler/rustc_codegen_cranelift/config.txt @@ -22,7 +22,6 @@ aot.float-minmax-pass aot.powi_libcall_signature aot.issue-72793 aot.issue-59326 -aot.neon aot.gen_block_iterate aot.raw-dylib test.sysroot @@ -32,3 +31,5 @@ test.rust-random/rand test.regex test.graviola test.portable-simd +test.stdarch-core +test.stdarch-intrinsics diff --git a/compiler/rustc_codegen_cranelift/example/neon.rs b/compiler/rustc_codegen_cranelift/example/neon.rs deleted file mode 100644 index ba63333daa339..0000000000000 --- a/compiler/rustc_codegen_cranelift/example/neon.rs +++ /dev/null @@ -1,963 +0,0 @@ -// Most of these tests are copied from https://github.com/japaric/stdsimd/blob/0f4413d01c4f0c3ffbc5a69e9a37fbc7235b31a9/coresimd/arm/neon.rs - -#![cfg_attr(target_arch = "aarch64", feature(portable_simd))] - -#[cfg(target_arch = "aarch64")] -use std::arch::aarch64::*; -#[cfg(target_arch = "aarch64")] -use std::mem::transmute; -#[cfg(target_arch = "aarch64")] -use std::simd::*; - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "crc")] -unsafe fn test_crc32() { - assert!(std::arch::is_aarch64_feature_detected!("crc")); - - let a: u32 = 42; - let b: u64 = 0xdeadbeef; - - assert_eq!(__crc32b(a, b as u8), 0xEB0E363F); - assert_eq!(__crc32h(a, b as u16), 0x9A54BD80); - assert_eq!(__crc32w(a, b as u32), 0xF491F059); - assert_eq!(__crc32d(a, b as u64), 0xD14BBEA6); - - assert_eq!(__crc32cb(a, b as u8), 0xF67C32D8); - assert_eq!(__crc32ch(a, b as u16), 0x479108B8); - assert_eq!(__crc32cw(a, b as u32), 0x979F49F8); - assert_eq!(__crc32cd(a, b as u64), 0x0E6BE593); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpmin_s8() { - let a = i8x8::from([1, -2, 3, -4, 5, 6, 7, 8]); - let b = i8x8::from([0, 3, 2, 5, 4, 7, 6, 9]); - let e = i8x8::from([-2, -4, 5, 7, 0, 2, 4, 6]); - let r: i8x8 = unsafe { transmute(vpmin_s8(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpmin_s16() { - let a = i16x4::from([1, 2, 3, -4]); - let b = i16x4::from([0, 3, 2, 5]); - let e = i16x4::from([1, -4, 0, 2]); - let r: i16x4 = unsafe { transmute(vpmin_s16(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpmin_s32() { - let a = i32x2::from([1, -2]); - let b = i32x2::from([0, 3]); - let e = i32x2::from([-2, 0]); - let r: i32x2 = unsafe { transmute(vpmin_s32(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpmin_u8() { - let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 8]); - let b = u8x8::from([0, 3, 2, 5, 4, 7, 6, 9]); - let e = u8x8::from([1, 3, 5, 7, 0, 2, 4, 6]); - let r: u8x8 = unsafe { transmute(vpmin_u8(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpmin_u16() { - let a = u16x4::from([1, 2, 3, 4]); - let b = u16x4::from([0, 3, 2, 5]); - let e = u16x4::from([1, 3, 0, 2]); - let r: u16x4 = unsafe { transmute(vpmin_u16(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpmin_u32() { - let a = u32x2::from([1, 2]); - let b = u32x2::from([0, 3]); - let e = u32x2::from([1, 0]); - let r: u32x2 = unsafe { transmute(vpmin_u32(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpmin_f32() { - let a = f32x2::from([1., -2.]); - let b = f32x2::from([0., 3.]); - let e = f32x2::from([-2., 0.]); - let r: f32x2 = unsafe { transmute(vpmin_f32(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpmax_s8() { - let a = i8x8::from([1, -2, 3, -4, 5, 6, 7, 8]); - let b = i8x8::from([0, 3, 2, 5, 4, 7, 6, 9]); - let e = i8x8::from([1, 3, 6, 8, 3, 5, 7, 9]); - let r: i8x8 = unsafe { transmute(vpmax_s8(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpmax_s16() { - let a = i16x4::from([1, 2, 3, -4]); - let b = i16x4::from([0, 3, 2, 5]); - let e = i16x4::from([2, 3, 3, 5]); - let r: i16x4 = unsafe { transmute(vpmax_s16(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpmax_s32() { - let a = i32x2::from([1, -2]); - let b = i32x2::from([0, 3]); - let e = i32x2::from([1, 3]); - let r: i32x2 = unsafe { transmute(vpmax_s32(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpmax_u8() { - let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 8]); - let b = u8x8::from([0, 3, 2, 5, 4, 7, 6, 9]); - let e = u8x8::from([2, 4, 6, 8, 3, 5, 7, 9]); - let r: u8x8 = unsafe { transmute(vpmax_u8(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpmax_u16() { - let a = u16x4::from([1, 2, 3, 4]); - let b = u16x4::from([0, 3, 2, 5]); - let e = u16x4::from([2, 4, 3, 5]); - let r: u16x4 = unsafe { transmute(vpmax_u16(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpmax_u32() { - let a = u32x2::from([1, 2]); - let b = u32x2::from([0, 3]); - let e = u32x2::from([2, 3]); - let r: u32x2 = unsafe { transmute(vpmax_u32(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpmax_f32() { - let a = f32x2::from([1., -2.]); - let b = f32x2::from([0., 3.]); - let e = f32x2::from([1., 3.]); - let r: f32x2 = unsafe { transmute(vpmax_f32(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpadd_s16() { - let a = i16x4::from([1, 2, 3, 4]); - let b = i16x4::from([0, -1, -2, -3]); - let r: i16x4 = unsafe { transmute(vpadd_s16(transmute(a), transmute(b))) }; - let e = i16x4::from([3, 7, -1, -5]); - assert_eq!(r, e); -} -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpadd_s32() { - let a = i32x2::from([1, 2]); - let b = i32x2::from([0, -1]); - let r: i32x2 = unsafe { transmute(vpadd_s32(transmute(a), transmute(b))) }; - let e = i32x2::from([3, -1]); - assert_eq!(r, e); -} -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpadd_s8() { - let a = i8x8::from([1, 2, 3, 4, 5, 6, 7, 8]); - let b = i8x8::from([0, -1, -2, -3, -4, -5, -6, -7]); - let r: i8x8 = unsafe { transmute(vpadd_s8(transmute(a), transmute(b))) }; - let e = i8x8::from([3, 7, 11, 15, -1, -5, -9, -13]); - assert_eq!(r, e); -} -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpadd_u16() { - let a = u16x4::from([1, 2, 3, 4]); - let b = u16x4::from([30, 31, 32, 33]); - let r: u16x4 = unsafe { transmute(vpadd_u16(transmute(a), transmute(b))) }; - let e = u16x4::from([3, 7, 61, 65]); - assert_eq!(r, e); -} -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpadd_u32() { - let a = u32x2::from([1, 2]); - let b = u32x2::from([30, 31]); - let r: u32x2 = unsafe { transmute(vpadd_u32(transmute(a), transmute(b))) }; - let e = u32x2::from([3, 61]); - assert_eq!(r, e); -} -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpadd_u8() { - let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 8]); - let b = u8x8::from([30, 31, 32, 33, 34, 35, 36, 37]); - let r: u8x8 = unsafe { transmute(vpadd_u8(transmute(a), transmute(b))) }; - let e = u8x8::from([3, 7, 11, 15, 61, 65, 69, 73]); - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vqsub_u8() { - let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 0xff]); - let b = u8x8::from([30, 1, 1, 1, 34, 0xff, 36, 37]); - let r: u8x8 = unsafe { transmute(vqsub_u8(transmute(a), transmute(b))) }; - let e = u8x8::from([0, 1, 2, 3, 0, 0, 0, 218]); - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vqadd_u8() { - let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 0xff]); - let b = u8x8::from([30, 1, 1, 1, 34, 0xff, 36, 37]); - let r: u8x8 = unsafe { transmute(vqadd_u8(transmute(a), transmute(b))) }; - let e = u8x8::from([31, 3, 4, 5, 39, 0xff, 43, 0xff]); - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vmaxq_f32() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.fmax.v4f32 - let a = f32x4::from([0., -1., 2., -3.]); - let b = f32x4::from([-4., 5., -6., 7.]); - let e = f32x4::from([0., 5., 2., 7.]); - let r: f32x4 = unsafe { transmute(vmaxq_f32(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vminq_f32() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.fmin.v4f32 - let a = f32x4::from([0., -1., 2., -3.]); - let b = f32x4::from([-4., 5., -6., 7.]); - let e = f32x4::from([-4., -1., -6., -3.]); - let r: f32x4 = unsafe { transmute(vminq_f32(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vaddvq_f32() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.faddv.f32.v4f32 - let a = f32x4::from([0., 1., 2., 3.]); - let e = 6f32; - let r = unsafe { vaddvq_f32(transmute(a)) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vrndnq_f32() { - // llvm intrinsic: llvm.roundeven.v4f32 - let a = f32x4::from([0.1, -1.9, 4.5, 5.5]); - let e = f32x4::from([0., -2., 4., 6.]); - let r: f32x4 = unsafe { transmute(vrndnq_f32(transmute(a))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "aes")] -unsafe fn test_vaeseq_u8() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.aese - let a = u8x16::from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); - let b = u8x16::from([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]); - let e = u8x16::from([ - 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, - 0xca, - ]); - let r: u8x16 = unsafe { transmute(vaeseq_u8(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "aes")] -unsafe fn test_vaesdq_u8() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.aesd - let a = u8x16::from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); - let b = u8x16::from([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]); - let e = u8x16::from([ - 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, - 0x7c, - ]); - let r: u8x16 = unsafe { transmute(vaesdq_u8(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "aes")] -unsafe fn test_vaesmcq_u8() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.aesmc - let a = u8x16::from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); - let e = u8x16::from([2, 7, 0, 5, 6, 3, 4, 1, 10, 15, 8, 13, 14, 11, 12, 9]); - let r: u8x16 = unsafe { transmute(vaesmcq_u8(transmute(a))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "aes")] -unsafe fn test_vaesimcq_u8() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.aesimc - let a = u8x16::from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); - let e = u8x16::from([10, 15, 8, 13, 14, 11, 12, 9, 2, 7, 0, 5, 6, 3, 4, 1]); - let r: u8x16 = unsafe { transmute(vaesimcq_u8(transmute(a))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha2")] -unsafe fn test_vsha1cq_u32() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.sha1c - let a = u32x4::from([0, 1, 2, 3]); - let b = 8; - let c = u32x4::from([4, 5, 6, 7]); - let e = u32x4::from([0x40072911, 0x40003948, 0x80000072, 0x80000003]); - let r: u32x4 = unsafe { transmute(vsha1cq_u32(transmute(a), b, transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha2")] -fn test_vsha1h_u32() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.sha1h - let a = 8; - let e = 0x00000002; - let r = vsha1h_u32(a); - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha2")] -unsafe fn test_vsha1mq_u32() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.sha1m - let a = u32x4::from([0, 1, 2, 3]); - let b = 8; - let c = u32x4::from([4, 5, 6, 7]); - let e = u32x4::from([0x4007a107, 0x00003d08, 0x0000007a, 0xc0000003]); - let r: u32x4 = unsafe { transmute(vsha1mq_u32(transmute(a), b, transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha2")] -unsafe fn test_vsha1pq_u32() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.sha1p - let a = u32x4::from([0, 1, 2, 3]); - let b = 8; - let c = u32x4::from([4, 5, 6, 7]); - let e = u32x4::from([0x80062d18, 0x4000315c, 0x90000062, 0x00000003]); - let r: u32x4 = unsafe { transmute(vsha1pq_u32(transmute(a), b, transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha2")] -unsafe fn test_vsha1su0q_u32() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.sha1su0 - let a = u32x4::from([0, 1, 2, 3]); - let b = u32x4::from([4, 5, 6, 7]); - let c = u32x4::from([8, 9, 10, 11]); - let e = u32x4::from([0x0000000a, 0x0000000b, 0x0000000c, 0x0000000d]); - let r: u32x4 = unsafe { transmute(vsha1su0q_u32(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha2")] -unsafe fn test_vsha1su1q_u32() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.sha1su1 - let a = u32x4::from([0, 1, 2, 3]); - let b = u32x4::from([4, 5, 6, 7]); - let e = u32x4::from([0x0000000a, 0x0000000e, 0x0000000a, 0x00000012]); - let r: u32x4 = unsafe { transmute(vsha1su1q_u32(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha2")] -unsafe fn test_vsha256hq_u32() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.sha256h - let a = u32x4::from([0, 1, 2, 3]); - let b = u32x4::from([4, 5, 6, 7]); - let c = u32x4::from([8, 9, 10, 11]); - let e = u32x4::from([0x27bb4ae0, 0xd8f61f7c, 0xb7c1ecdc, 0x10800215]); - let r: u32x4 = unsafe { transmute(vsha256hq_u32(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha2")] -unsafe fn test_vsha256h2q_u32() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.sha256h2 - let a = u32x4::from([0, 1, 2, 3]); - let b = u32x4::from([4, 5, 6, 7]); - let c = u32x4::from([8, 9, 10, 11]); - let e = u32x4::from([0x6989ee0d, 0x4b055920, 0x52800a12, 0x00000014]); - let r: u32x4 = unsafe { transmute(vsha256h2q_u32(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha2")] -unsafe fn test_vsha256su0q_u32() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.sha256su0 - let a = u32x4::from([0, 1, 2, 3]); - let b = u32x4::from([4, 5, 6, 7]); - let e = u32x4::from([0x02004000, 0x04008001, 0x0600c002, 0x08010003]); - let r: u32x4 = unsafe { transmute(vsha256su0q_u32(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha2")] -unsafe fn test_vsha256su1q_u32() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.sha256su1 - let a = u32x4::from([0, 1, 2, 3]); - let b = u32x4::from([4, 5, 6, 7]); - let c = u32x4::from([8, 9, 10, 11]); - let e = u32x4::from([0x00044005, 0x0004e007, 0xa802211b, 0xec036145]); - let r: u32x4 = unsafe { transmute(vsha256su1q_u32(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_vsha512hq_u64() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.sha512h - let a = u64x2::from([0, 1]); - let b = u64x2::from([2, 3]); - let c = u64x2::from([4, 5]); - let e = u64x2::from([0x001c805053800005, 0x0015400002800003]); - let r: u64x2 = unsafe { transmute(vsha512hq_u64(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_vsha512h2q_u64() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.sha512h2 - let a = u64x2::from([0, 1]); - let b = u64x2::from([2, 3]); - let c = u64x2::from([4, 5]); - let e = u64x2::from([0x401000514a000405, 0x0000004108000005]); - let r: u64x2 = unsafe { transmute(vsha512h2q_u64(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_vsha512su0q_u64() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.sha512su0 - let a = u64x2::from([0, 1]); - let b = u64x2::from([2, 3]); - let e = u64x2::from([0x8100000000000000, 0x0200000000000002]); - let r: u64x2 = unsafe { transmute(vsha512su0q_u64(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_vsha512su1q_u64() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.sha512su1 - let a = u64x2::from([0, 1]); - let b = u64x2::from([2, 3]); - let c = u64x2::from([4, 5]); - let e = u64x2::from([0x0000400000000014, 0x000060000000001e]); - let r: u64x2 = unsafe { transmute(vsha512su1q_u64(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_veor3q_s8() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.eor3s.v16i8 - let a = i8x16::from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); - let b = i8x16::from([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]); - let c = i8x16::from([32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47]); - let e = i8x16::from([48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63]); - let r: i8x16 = unsafe { transmute(veor3q_s8(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_veor3q_s16() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.eor3s.v8i16 - let a = i16x8::from([0, 1, 2, 3, 4, 5, 6, 7]); - let b = i16x8::from([8, 9, 10, 11, 12, 13, 14, 15]); - let c = i16x8::from([16, 17, 18, 19, 20, 21, 22, 23]); - let e = i16x8::from([24, 25, 26, 27, 28, 29, 30, 31]); - let r: i16x8 = unsafe { transmute(veor3q_s16(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_veor3q_s32() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.eor3s.v4i32 - let a = i32x4::from([0, 1, 2, 3]); - let b = i32x4::from([4, 5, 6, 7]); - let c = i32x4::from([8, 9, 10, 11]); - let e = i32x4::from([12, 13, 14, 15]); - let r: i32x4 = unsafe { transmute(veor3q_s32(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_veor3q_s64() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.eor3s.v2i64 - let a = i64x2::from([0, 1]); - let b = i64x2::from([2, 3]); - let c = i64x2::from([4, 5]); - let e = i64x2::from([6, 7]); - let r: i64x2 = unsafe { transmute(veor3q_s64(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_veor3q_u8() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.eor3u.v16i8 - let a = u8x16::from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); - let b = u8x16::from([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]); - let c = u8x16::from([32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47]); - let e = u8x16::from([48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63]); - let r: u8x16 = unsafe { transmute(veor3q_u8(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_veor3q_u16() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.eor3u.v8i16 - let a = u16x8::from([0, 1, 2, 3, 4, 5, 6, 7]); - let b = u16x8::from([8, 9, 10, 11, 12, 13, 14, 15]); - let c = u16x8::from([16, 17, 18, 19, 20, 21, 22, 23]); - let e = u16x8::from([24, 25, 26, 27, 28, 29, 30, 31]); - let r: u16x8 = unsafe { transmute(veor3q_u16(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_veor3q_u32() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.eor3u.v4i32 - let a = u32x4::from([0, 1, 2, 3]); - let b = u32x4::from([4, 5, 6, 7]); - let c = u32x4::from([8, 9, 10, 11]); - let e = u32x4::from([12, 13, 14, 15]); - let r: u32x4 = unsafe { transmute(veor3q_u32(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_veor3q_u64() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.eor3u.v2i64 - let a = u64x2::from([0, 1]); - let b = u64x2::from([2, 3]); - let c = u64x2::from([4, 5]); - let e = u64x2::from([6, 7]); - let r: u64x2 = unsafe { transmute(veor3q_u64(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_vbcaxq_s8() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.bcaxs.v16i8 - let a = i8x16::from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); - let b = i8x16::from([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]); - let c = i8x16::from([32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47]); - let e = i8x16::from([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]); - let r: i8x16 = unsafe { transmute(vbcaxq_s8(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_vbcaxq_s16() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.bcaxs.v8i16 - let a = i16x8::from([0, 1, 2, 3, 4, 5, 6, 7]); - let b = i16x8::from([8, 9, 10, 11, 12, 13, 14, 15]); - let c = i16x8::from([16, 17, 18, 19, 20, 21, 22, 23]); - let e = i16x8::from([8, 9, 10, 11, 12, 13, 14, 15]); - let r: i16x8 = unsafe { transmute(vbcaxq_s16(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_vbcaxq_s32() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.bcaxs.v4i32 - let a = i32x4::from([0, 1, 2, 3]); - let b = i32x4::from([4, 5, 6, 7]); - let c = i32x4::from([8, 9, 10, 11]); - let e = i32x4::from([4, 5, 6, 7]); - let r: i32x4 = unsafe { transmute(vbcaxq_s32(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_vbcaxq_s64() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.bcaxs.v2i64 - let a = i64x2::from([0, 1]); - let b = i64x2::from([2, 3]); - let c = i64x2::from([4, 5]); - let e = i64x2::from([2, 3]); - let r: i64x2 = unsafe { transmute(vbcaxq_s64(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_vbcaxq_u8() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.bcaxu.v16i8 - let a = u8x16::from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); - let b = u8x16::from([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]); - let c = u8x16::from([32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47]); - let e = u8x16::from([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]); - let r: u8x16 = unsafe { transmute(vbcaxq_u8(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_vbcaxq_u16() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.bcaxu.v8i16 - let a = u16x8::from([0, 1, 2, 3, 4, 5, 6, 7]); - let b = u16x8::from([8, 9, 10, 11, 12, 13, 14, 15]); - let c = u16x8::from([16, 17, 18, 19, 20, 21, 22, 23]); - let e = u16x8::from([8, 9, 10, 11, 12, 13, 14, 15]); - let r: u16x8 = unsafe { transmute(vbcaxq_u16(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_vbcaxq_u32() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.bcaxu.v4i32 - let a = u32x4::from([0, 1, 2, 3]); - let b = u32x4::from([4, 5, 6, 7]); - let c = u32x4::from([8, 9, 10, 11]); - let e = u32x4::from([4, 5, 6, 7]); - let r: u32x4 = unsafe { transmute(vbcaxq_u32(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_vbcaxq_u64() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.bcaxu.v2i64 - let a = u64x2::from([0, 1]); - let b = u64x2::from([2, 3]); - let c = u64x2::from([4, 5]); - let e = u64x2::from([2, 3]); - let r: u64x2 = unsafe { transmute(vbcaxq_u64(transmute(a), transmute(b), transmute(c))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_vrax1q_u64() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.rax1 - let a = u64x2::from([0, 1]); - let b = u64x2::from([2, 3]); - let e = u64x2::from([4, 7]); - let r: u64x2 = unsafe { transmute(vrax1q_u64(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "sha3")] -unsafe fn test_vxarq_u64() { - // AArch64 llvm intrinsic: llvm.aarch64.crypto.xar - let a = u64x2::from([0, 1]); - let b = u64x2::from([2, 3]); - let e = u64x2::from([4, 4]); - let r: u64x2 = unsafe { transmute(vxarq_u64::<63>(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -#[target_feature(enable = "aes")] -fn test_vmull_p64() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.pmull64 - let a: u64 = 3; - let b: u64 = 6; - let e: u128 = 10; - let r: u128 = vmull_p64(a, b); - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vmull_p8() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.pmull.v8i16 - let a = u8x8::from([0, 1, 2, 3, 4, 5, 6, 7]); - let b = u8x8::from([8, 9, 10, 11, 12, 13, 14, 15]); - let e = u16x8::from([0x0000, 0x0009, 0x0014, 0x001d, 0x0030, 0x0039, 0x0024, 0x002d]); - let r: u16x8 = unsafe { transmute(vmull_p8(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vqdmulh_s16() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.sqdmulh.v4i16 - let a = i16x4::from([1, 2, 4, 8]); - let b = i16x4::from([16384, 16384, 16384, 16384]); - let e = i16x4::from([0, 1, 2, 4]); - let r: i16x4 = unsafe { transmute(vqdmulh_s16(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vqdmulh_s32() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.sqdmulh.v2i32 - let a = i32x2::from([1, 2]); - let b = i32x2::from([1073741824, 1073741824]); - let e = i32x2::from([0, 1]); - let r: i32x2 = unsafe { transmute(vqdmulh_s32(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vqdmulhq_s16() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.sqdmulh.v8i16 - let a = i16x8::from([1, 2, 4, 8, 16, 32, 64, 128]); - let b = i16x8::from([16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384]); - let e = i16x8::from([0, 1, 2, 4, 8, 16, 32, 64]); - let r: i16x8 = unsafe { transmute(vqdmulhq_s16(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vqdmulhq_s32() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.sqdmulh.v4i32 - let a = i32x4::from([1, 2, 4, 8]); - let b = i32x4::from([1073741824, 1073741824, 1073741824, 1073741824]); - let e = i32x4::from([0, 1, 2, 4]); - let r: i32x4 = unsafe { transmute(vqdmulhq_s32(transmute(a), transmute(b))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpaddl_s8() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.saddlp.v4i16.v8i8 - let a = i8x8::from([1, 2, 3, 4, -5, -6, -7, -8]); - let e = i16x4::from([3, 7, -11, -15]); - let r: i16x4 = unsafe { transmute(vpaddl_s8(transmute(a))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpaddl_s16() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.saddlp.v2i32.v4i16 - let a = i16x4::from([1, 2, -3, -4]); - let e = i32x2::from([3, -7]); - let r: i32x2 = unsafe { transmute(vpaddl_s16(transmute(a))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpaddl_s32() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.saddlp.v1i64.v2i32 - let a = i32x2::from([1, -2]); - let e = i64x1::from([-1]); - let r: i64x1 = unsafe { transmute(vpaddl_s32(transmute(a))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpaddlq_s8() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.saddlp.v8i16.v16i8 - let a = i8x16::from([1, 2, 3, 4, 5, 6, 7, 8, -9, -10, -11, -12, -13, -14, -15, -16]); - let e = i16x8::from([3, 7, 11, 15, -19, -23, -27, -31]); - let r: i16x8 = unsafe { transmute(vpaddlq_s8(transmute(a))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpaddlq_s16() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.saddlp.v4i32.v8i16 - let a = i16x8::from([1, 2, 3, 4, -5, -6, -7, -8]); - let e = i32x4::from([3, 7, -11, -15]); - let r: i32x4 = unsafe { transmute(vpaddlq_s16(transmute(a))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpaddlq_s32() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.saddlp.v2i64.v4i32 - let a = i32x4::from([1, 2, -3, -4]); - let e = i64x2::from([3, -7]); - let r: i64x2 = unsafe { transmute(vpaddlq_s32(transmute(a))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpaddl_u8() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.uaddlp.v4i16.v8i8 - let a = u8x8::from([255, 254, 253, 252, 251, 250, 249, 248]); - let e = u16x4::from([509, 505, 501, 497]); - let r: u16x4 = unsafe { transmute(vpaddl_u8(transmute(a))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpaddl_u16() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.uaddlp.v2i32.v4i16 - let a = u16x4::from([65535, 65534, 65533, 65532]); - let e = u32x2::from([131069, 131065]); - let r: u32x2 = unsafe { transmute(vpaddl_u16(transmute(a))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpaddl_u32() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.uaddlp.v1i64.v2i32 - let a = u32x2::from([4294967295, 4294967294]); - let e = u64x1::from([8589934589]); - let r: u64x1 = unsafe { transmute(vpaddl_u32(transmute(a))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpaddlq_u8() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.uaddlp.v8i16.v16i8 - let a = u8x16::from([ - 255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, - ]); - let e = u16x8::from([509, 505, 501, 497, 493, 489, 485, 481]); - let r: u16x8 = unsafe { transmute(vpaddlq_u8(transmute(a))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpaddlq_u16() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.uaddlp.v4i32.v8i16 - let a = u16x8::from([65535, 65534, 65533, 65532, 65531, 65530, 65529, 65528]); - let e = u32x4::from([131069, 131065, 131061, 131057]); - let r: u32x4 = unsafe { transmute(vpaddlq_u16(transmute(a))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -unsafe fn test_vpaddlq_u32() { - // AArch64 llvm intrinsic: llvm.aarch64.neon.uaddlp.v2i64.v4i32 - let a = u32x4::from([4294967295, 4294967294, 4294967293, 4294967292]); - let e = u64x2::from([8589934589, 8589934585]); - let r: u64x2 = unsafe { transmute(vpaddlq_u32(transmute(a))) }; - assert_eq!(r, e); -} - -#[cfg(target_arch = "aarch64")] -fn main() { - unsafe { - test_vpmin_s8(); - test_vpmin_s16(); - test_vpmin_s32(); - test_vpmin_u8(); - test_vpmin_u16(); - test_vpmin_u32(); - test_vpmin_f32(); - test_vpmax_s8(); - test_vpmax_s16(); - test_vpmax_s32(); - test_vpmax_u8(); - test_vpmax_u16(); - test_vpmax_u32(); - test_vpmax_f32(); - - test_vpadd_s16(); - test_vpadd_s32(); - test_vpadd_s8(); - test_vpadd_u16(); - test_vpadd_u32(); - test_vpadd_u8(); - - test_vqsub_u8(); - test_vqadd_u8(); - - test_vmaxq_f32(); - test_vminq_f32(); - test_vaddvq_f32(); - test_vrndnq_f32(); - - test_crc32(); - - test_vaeseq_u8(); - test_vaesdq_u8(); - test_vaesmcq_u8(); - test_vaesimcq_u8(); - - test_vsha1cq_u32(); - test_vsha1h_u32(); - test_vsha1mq_u32(); - test_vsha1pq_u32(); - test_vsha1su0q_u32(); - test_vsha1su1q_u32(); - - test_vsha256hq_u32(); - test_vsha256h2q_u32(); - test_vsha256su0q_u32(); - test_vsha256su1q_u32(); - - if std::arch::is_aarch64_feature_detected!("sha3") { - test_vsha512hq_u64(); - test_vsha512h2q_u64(); - test_vsha512su0q_u64(); - test_vsha512su1q_u64(); - - test_veor3q_s8(); - test_veor3q_s16(); - test_veor3q_s32(); - test_veor3q_s64(); - test_veor3q_u8(); - test_veor3q_u16(); - test_veor3q_u32(); - test_veor3q_u64(); - - test_vbcaxq_s8(); - test_vbcaxq_s16(); - test_vbcaxq_s32(); - test_vbcaxq_s64(); - test_vbcaxq_u8(); - test_vbcaxq_u16(); - test_vbcaxq_u32(); - test_vbcaxq_u64(); - - test_vrax1q_u64(); - test_vxarq_u64(); - } - - test_vmull_p64(); - test_vmull_p8(); - - test_vqdmulh_s16(); - test_vqdmulh_s32(); - test_vqdmulhq_s16(); - test_vqdmulhq_s32(); - - test_vpaddl_s8(); - test_vpaddl_s16(); - test_vpaddl_s32(); - test_vpaddlq_s8(); - test_vpaddlq_s16(); - test_vpaddlq_s32(); - - test_vpaddl_u8(); - test_vpaddl_u16(); - test_vpaddl_u32(); - test_vpaddlq_u8(); - test_vpaddlq_u16(); - test_vpaddlq_u32(); - } -} - -#[cfg(not(target_arch = "aarch64"))] -fn main() {} diff --git a/compiler/rustc_codegen_cranelift/example/std_example.rs b/compiler/rustc_codegen_cranelift/example/std_example.rs index e1287683d495d..5fc5f17682cc8 100644 --- a/compiler/rustc_codegen_cranelift/example/std_example.rs +++ b/compiler/rustc_codegen_cranelift/example/std_example.rs @@ -294,6 +294,19 @@ unsafe fn test_simd() { if is_x86_feature_detected!("avx512f") { test_zmm_roundtrip(); } + + #[cfg(not(jit))] + { + if is_x86_feature_detected!("pclmulqdq") { + test_mm_clmulepi64_si128(); + } + if is_x86_feature_detected!("vpclmulqdq") { + test_mm256_clmulepi64_epi128(); + } + if is_x86_feature_detected!("vpclmulqdq") && is_x86_feature_detected!("avx512f") { + test_mm512_clmulepi64_epi128(); + } + } } } @@ -395,6 +408,14 @@ pub fn assert_eq_m256i(a: __m256i, b: __m256i) { } } +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "avx512f")] +pub fn assert_eq_m512i(a: __m512i, b: __m512i) { + unsafe { + assert_eq!(std::mem::transmute::<_, [u64; 8]>(a), std::mem::transmute::<_, [u64; 8]>(b)) + } +} + #[cfg(target_arch = "x86_64")] #[target_feature(enable = "sse2")] unsafe fn test_mm_cvtsi128_si64() { @@ -537,6 +558,62 @@ unsafe fn test_mm256_permutevar8x32_epi32() { assert_eq_m256i(r, e); } +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "pclmulqdq")] +#[cfg(not(jit))] +unsafe fn test_mm_clmulepi64_si128() { + // Constants taken from https://software.intel.com/sites/default/files/managed/72/cc/clmul-wp-rev-2.02-2014-04-20.pdf + let a = _mm_set_epi64x(0x7b5b546573745665, 0x63746f725d53475d); + let b = _mm_set_epi64x(0x4869285368617929, 0x5b477565726f6e5d); + let r00 = _mm_set_epi64x(0x1d4d84c85c3440c0, 0x929633d5d36f0451u64.cast_signed()); + let r01 = _mm_set_epi64x(0x1bd17c8d556ab5a1, 0x7fa540ac2a281315); + let r10 = _mm_set_epi64x(0x1a2bf6db3a30862f, 0xbabf262df4b7d5c9u64.cast_signed()); + let r11 = _mm_set_epi64x(0x1d1e1f2c592e7c45, 0xd66ee03e410fd4edu64.cast_signed()); + + assert_eq_m128i(_mm_clmulepi64_si128::<0x00>(a, b), r00); + assert_eq_m128i(_mm_clmulepi64_si128::<0x10>(a, b), r01); + assert_eq_m128i(_mm_clmulepi64_si128::<0x01>(a, b), r10); + assert_eq_m128i(_mm_clmulepi64_si128::<0x11>(a, b), r11); + + let a0 = _mm_set_epi64x(0x0000000000000000, 0x8000000000000000u64.cast_signed()); + let r = _mm_set_epi64x(0x4000000000000000, 0x0000000000000000); + assert_eq_m128i(_mm_clmulepi64_si128::<0x00>(a0, a0), r); +} + +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "vpclmulqdq")] +#[cfg(not(jit))] +unsafe fn test_mm256_clmulepi64_epi128() { + let a = _mm256_setr_epi64x(1, 2, 3, 4); + let b = _mm256_setr_epi64x(5, 6, 7, 8); + + assert_eq_m256i(_mm256_clmulepi64_epi128::<0x00>(a, b), _mm256_setr_epi64x(5, 0, 9, 0)); + assert_eq_m256i(_mm256_clmulepi64_epi128::<0x01>(a, b), _mm256_setr_epi64x(10, 0, 28, 0)); + assert_eq_m256i(_mm256_clmulepi64_epi128::<0x10>(a, b), _mm256_setr_epi64x(6, 0, 24, 0)); + assert_eq_m256i(_mm256_clmulepi64_epi128::<0x11>(a, b), _mm256_setr_epi64x(12, 0, 32, 0)); +} + +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "vpclmulqdq,avx512f")] +#[cfg(not(jit))] +unsafe fn test_mm512_clmulepi64_epi128() { + let a = _mm512_setr_epi64(1, 2, 3, 4, 5, 6, 7, 8); + let b = _mm512_setr_epi64(9, 10, 11, 12, 13, 14, 15, 16); + + assert_eq_m512i( + _mm512_clmulepi64_epi128::<0x00>(a, b), + _mm512_setr_epi64(9, 0, 29, 0, 57, 0, 45, 0), + ); + assert_eq_m512i( + _mm512_clmulepi64_epi128::<0x10>(a, b), + _mm512_setr_epi64(10, 0, 20, 0, 54, 0, 112, 0), + ); + assert_eq_m512i( + _mm512_clmulepi64_epi128::<0x11>(a, b), + _mm512_setr_epi64(20, 0, 48, 0, 36, 0, 128, 0), + ); +} + #[cfg(target_arch = "x86_64")] #[target_feature(enable = "avx2")] #[cfg(not(jit))] diff --git a/compiler/rustc_codegen_cranelift/josh-sync.toml b/compiler/rustc_codegen_cranelift/josh-sync.toml index 2de9f9489cce3..d8b49ebac131d 100644 --- a/compiler/rustc_codegen_cranelift/josh-sync.toml +++ b/compiler/rustc_codegen_cranelift/josh-sync.toml @@ -1,3 +1,4 @@ repo = "rustc_codegen_cranelift" filter = ":~(history=\"keep-trivial-merges,no-splice\")[:rev(<=5e120485964f4857f1ad70f7d661fd244d087668:prefix=compiler/rustc_codegen_cranelift,<=7bd21608dfab11ea536f7be8936cc7dfac5864fb:SQUASH)]:/compiler/rustc_codegen_cranelift" filter-version = 2 +pull-mode = "Nightly" diff --git a/compiler/rustc_codegen_cranelift/patches/0001-stdarch-Disable-SVE.patch b/compiler/rustc_codegen_cranelift/patches/0001-stdarch-Disable-SVE.patch new file mode 100644 index 0000000000000..e7038699bc998 --- /dev/null +++ b/compiler/rustc_codegen_cranelift/patches/0001-stdarch-Disable-SVE.patch @@ -0,0 +1,51 @@ +From e90274ba5bc4bee03a24e8c134ea223497c3a46b Mon Sep 17 00:00:00 2001 +From: Cathal Mullan +Date: Sat, 13 Jun 2026 20:32:02 +0100 +Subject: [PATCH] Disable SVE + +Cranelift doesn't support scalable vectors. +--- + crates/core_arch/src/aarch64/mod.rs | 8 ++++---- + crates/intrinsic-test/src/arm/mod.rs | 1 + + 2 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/crates/core_arch/src/aarch64/mod.rs b/crates/core_arch/src/aarch64/mod.rs +index 34fa5c8..a870e31 100644 +--- a/crates/core_arch/src/aarch64/mod.rs ++++ b/crates/core_arch/src/aarch64/mod.rs +@@ -19,16 +19,16 @@ mod neon; + pub use self::neon::*; + + // The rest of `core_arch::aarch64` is available on `arm64ec` but SVE is not supported on `arm64ec`. +-#[cfg(any(all(target_arch = "aarch64", target_endian = "little"), doc))] ++#[cfg(all(not(test), any(all(target_arch = "aarch64", target_endian = "little"), doc)))] + mod sve; +-#[cfg(any(all(target_arch = "aarch64", target_endian = "little"), doc))] ++#[cfg(all(not(test), any(all(target_arch = "aarch64", target_endian = "little"), doc)))] + #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] + pub use self::sve::*; + + // The rest of `core_arch::aarch64` is available on `arm64ec` but SVE is not supported on `arm64ec`. +-#[cfg(any(all(target_arch = "aarch64", target_endian = "little"), doc))] ++#[cfg(all(not(test), any(all(target_arch = "aarch64", target_endian = "little"), doc)))] + mod sve2; +-#[cfg(any(all(target_arch = "aarch64", target_endian = "little"), doc))] ++#[cfg(all(not(test), any(all(target_arch = "aarch64", target_endian = "little"), doc)))] + #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] + pub use self::sve2::*; + +diff --git a/crates/intrinsic-test/src/arm/mod.rs b/crates/intrinsic-test/src/arm/mod.rs +index 9c2d0f3..3825f41 100644 +--- a/crates/intrinsic-test/src/arm/mod.rs ++++ b/crates/intrinsic-test/src/arm/mod.rs +@@ -66,6 +66,7 @@ impl SupportedArchitecture for Arm { + + let intrinsics = intrinsics + .into_iter() ++ .filter(|i| i.extension != "SVE" && i.extension != "SVE2") + // Skip intrinsics that don't return a value. + .filter(|i| i.results.kind() != TypeKind::Void) + // Skip bfloat intrinsics - not currently supported +-- +2.54.0 + diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain.toml b/compiler/rustc_codegen_cranelift/rust-toolchain.toml index d7e313a7a33ed..a6468283e1270 100644 --- a/compiler/rustc_codegen_cranelift/rust-toolchain.toml +++ b/compiler/rustc_codegen_cranelift/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2026-09-11" +channel = "nightly-2026-09-30" components = ["rust-src", "rustc-dev", "llvm-tools", "rustfmt"] profile = "minimal" diff --git a/compiler/rustc_codegen_cranelift/scripts/rustup.sh b/compiler/rustc_codegen_cranelift/scripts/rustup.sh index e26be307328f0..8bd41f98ce550 100755 --- a/compiler/rustc_codegen_cranelift/scripts/rustup.sh +++ b/compiler/rustc_codegen_cranelift/scripts/rustup.sh @@ -2,75 +2,34 @@ set -e -TOOLCHAIN=${TOOLCHAIN:-$(date +%Y-%m-%d)} - -function check_git_fixed_subtree() { - if [[ ! -e ./git-fixed-subtree.sh ]]; then - echo "Missing git-fixed-subtree.sh. Please run the following commands to download it:" - echo "curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/bjorn3/git/tqc-subtree-portable/contrib/subtree/git-subtree.sh -o git-fixed-subtree.sh" - echo "chmod u+x git-fixed-subtree.sh" - exit 1 - fi - if [[ ! -x ./git-fixed-subtree.sh ]]; then - echo "git-fixed-subtree.sh is not executable. Please run the following command to make it executable:" - echo "chmod u+x git-fixed-subtree.sh" - exit 1 - fi -} +export GIT_CONFIG_GLOBAL=$(pwd)/../rust/josh.gitconfig +export RUSTC_GIT=../rust case $1 in "prepare") - echo "=> Installing new nightly" - rustup toolchain install --profile minimal "nightly-${TOOLCHAIN}" # Sanity check to see if the nightly exists - sed -i "s/\"nightly-.*\"/\"nightly-${TOOLCHAIN}\"/" rust-toolchain.toml - echo "=> Uninstalling all old nightlies" - for nightly in $(rustup toolchain list | grep nightly | grep -v "$TOOLCHAIN" | grep -v nightly-x86_64); do + for nightly in $(RUSTUP_AUTO_INSTALL=0 rustup toolchain list | grep nightly | grep -v nightly-x86_64); do rustup toolchain uninstall "$nightly" done + echo "=> Installing new nightly" + rustup toolchain install + ./clean_all.sh ./y.sh prepare ;; - "commit") - git add rust-toolchain.toml - git commit -m "Rustup to $(rustc -V)" - ;; "push") - check_git_fixed_subtree - - cg_clif=$(pwd) - pushd ../rust - git pull origin main + username=${2:-bjorn3} branch=sync_cg_clif-$(date +%Y-%m-%d) - git checkout -b "$branch" - "$cg_clif/git-fixed-subtree.sh" pull --prefix=compiler/rustc_codegen_cranelift/ https://github.com/rust-lang/rustc_codegen_cranelift.git main - git push -u my "$branch" - - # immediately merge the merge commit into cg_clif to prevent merge conflicts when syncing - # from rust-lang/rust later - "$cg_clif/git-fixed-subtree.sh" push --prefix=compiler/rustc_codegen_cranelift/ "$cg_clif" sync_from_rust - popd - git merge sync_from_rust + rustc-josh-sync push "$branch" "$username" ;; "pull") - check_git_fixed_subtree - - RUST_VERS=$(curl "https://static.rust-lang.org/dist/$TOOLCHAIN/channel-rust-nightly-git-commit-hash.txt") - echo "Pulling $RUST_VERS ($TOOLCHAIN)" - - cg_clif=$(pwd) - pushd ../rust - git fetch origin main - git -c advice.detachedHead=false checkout "$RUST_VERS" - "$cg_clif/git-fixed-subtree.sh" push --prefix=compiler/rustc_codegen_cranelift/ "$cg_clif" sync_from_rust - popd - git merge sync_from_rust -m "Sync from rust $RUST_VERS" - git branch -d sync_from_rust + git checkout -b sync_from_rust + rustc-josh-sync pull ;; *) echo "Unknown command '$1'" - echo "Usage: ./rustup.sh prepare|commit" + echo "Usage: ./rustup.sh prepare|pull|push [fork]" ;; esac diff --git a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh index 5a1374fe56e09..648f68588e04b 100755 --- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh +++ b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh @@ -164,6 +164,7 @@ rm -r tests/run-make/const-trait-stable-toolchain # same rm -r tests/run-make/print-request-help-stable-unstable # same rm -r tests/run-make/issue-149402-suggest-unresolve # same rm -r tests/run-make/const-destruct-stable-toolchain # same +rm -r tests/run-make/unstable-target-feature # same rm -r tests/run-make/incr-add-rust-src-component rm tests/ui/errors/remap-path-prefix-sysroot.rs # different sysroot source path rm -r tests/run-make/export # something about rustc version mismatches diff --git a/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs b/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs index ca9157daae584..8e339167a5b12 100644 --- a/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs +++ b/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs @@ -135,8 +135,8 @@ builtin_functions! { // float intrinsics fn __powisf2(a: f32, b: i32) -> f32; fn __powidf2(a: f64, b: i32) -> f64; - // FIXME(f16_f128): `compiler-builtins` doesn't currently support `__powitf2` on MSVC. - // fn __powitf2(a: f128, b: i32) -> f128; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] + fn __powitf2(a: f128, b: i32) -> f128; fn powf(a: f32, b: f32) -> f32; fn pow(a: f64, b: f64) -> f64; fn expf(f: f32) -> f32; diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs index 136e98964bc35..f3763b5895eba 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs @@ -855,42 +855,59 @@ pub(super) fn codegen_x86_llvm_intrinsic_call<'tcx>( ); } - "llvm.x86.pclmulqdq" => { + "llvm.x86.pclmulqdq" | "llvm.x86.pclmulqdq.256" | "llvm.x86.pclmulqdq.512" => { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_clmulepi64_si128&ig_expand=772 + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_clmulepi64_epi128&ig_expand=752 + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm512_clmulepi64_epi128&ig_expand=753 intrinsic_args!(fx, args => (a, b, _imm8); intrinsic); - let a = a.load_scalar(fx); - let b = b.load_scalar(fx); + let (lane_count, intrinsic_name) = match intrinsic { + "llvm.x86.pclmulqdq" => (1, "_mm_clmulepi64_si128"), + "llvm.x86.pclmulqdq.256" => (2, "_mm256_clmulepi64_epi128"), + "llvm.x86.pclmulqdq.512" => (4, "_mm512_clmulepi64_epi128"), + _ => unreachable!(), + }; - let imm8 = - if let Some(imm8) = crate::constant::mir_operand_get_const_val(fx, &args[2].node) { - imm8 - } else { - fx.tcx.dcx().span_fatal( - span, - "Index argument for `_mm_clmulepi64_si128` is not a constant", - ); - }; + let Some(imm8) = crate::constant::mir_operand_get_const_val(fx, &args[2].node) else { + fx.tcx.dcx().span_fatal( + span, + format!("Index argument for `{intrinsic_name}` is not a constant"), + ) + }; let imm8 = imm8.to_u8(); - codegen_inline_asm_inner( - fx, - &[InlineAsmTemplatePiece::String(format!("pclmulqdq xmm0, xmm1, {imm8}").into())], - &[ - CInlineAsmOperand::InOut { - reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)), - _late: true, - in_value: a, - out_place: Some(ret), - }, - CInlineAsmOperand::In { - reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)), - value: b, - }, - ], - InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM, - ); + // Cranelift does not currently support 256-bit or 512-bit SSA values, so we use the + // 128-bit instruction on each 128-bit lane. + for lane in 0..lane_count { + let a = a.value_typed_lane(fx, fx.tcx.types.u128, lane).load_scalar(fx); + let b = b.value_typed_lane(fx, fx.tcx.types.u128, lane).load_scalar(fx); + let ret_lane = ret.place_typed_lane(fx, fx.tcx.types.u128, lane); + + codegen_inline_asm_inner( + fx, + &[InlineAsmTemplatePiece::String( + format!("pclmulqdq xmm0, xmm1, {imm8}").into(), + )], + &[ + CInlineAsmOperand::InOut { + reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86( + X86InlineAsmReg::xmm0, + )), + _late: true, + in_value: a, + out_place: Some(ret_lane), + }, + CInlineAsmOperand::In { + reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86( + X86InlineAsmReg::xmm1, + )), + value: b, + }, + ], + InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM, + ); + } } "llvm.x86.aesni.aeskeygenassist" => { diff --git a/compiler/rustc_codegen_gcc/src/base.rs b/compiler/rustc_codegen_gcc/src/base.rs index 07214096b3e49..acf5c75e4d8cd 100644 --- a/compiler/rustc_codegen_gcc/src/base.rs +++ b/compiler/rustc_codegen_gcc/src/base.rs @@ -55,19 +55,14 @@ pub fn global_linkage_to_gcc(linkage: Linkage) -> GlobalKind { | Linkage::LinkOnceODR | Linkage::WeakAny | Linkage::WeakODR - | Linkage::ExternalWeak - | Linkage::Common => GlobalKind::Exported, + | Linkage::ExternalWeak => GlobalKind::Exported, } } /// The attribute a global *definition* needs on top of its [`GlobalKind`] to get this linkage. #[cfg(feature = "master")] pub fn global_linkage_attribute<'gcc>(linkage: Linkage) -> Option> { - match linkage { - Linkage::Common => Some(VarAttribute::Common), - _ if linkage_needs_weak_attribute(linkage) => Some(VarAttribute::Weak), - _ => None, - } + if linkage_needs_weak_attribute(linkage) { Some(VarAttribute::Weak) } else { None } } /// The type of a function *definition* with an explicit `#[linkage]`. @@ -85,17 +80,12 @@ pub fn linkage_to_gcc(linkage: Linkage) -> FunctionType { | Linkage::LinkOnceODR | Linkage::WeakAny | Linkage::WeakODR - | Linkage::ExternalWeak - | Linkage::Common => FunctionType::Exported, + | Linkage::ExternalWeak => FunctionType::Exported, } } /// Whether a definition with this linkage must carry the `weak` attribute, so that a strong /// definition in another object file wins over it instead of clashing with it. -/// -/// `common` is in here for functions only: GCC honours that attribute on a variable, but drops it -/// on a function, so a common function falls back to weak. Globals go through -/// `global_linkage_attribute` instead. #[cfg(feature = "master")] pub fn linkage_needs_weak_attribute(linkage: Linkage) -> bool { match linkage { @@ -103,8 +93,7 @@ pub fn linkage_needs_weak_attribute(linkage: Linkage) -> bool { | Linkage::LinkOnceODR | Linkage::WeakAny | Linkage::WeakODR - | Linkage::ExternalWeak - | Linkage::Common => true, + | Linkage::ExternalWeak => true, Linkage::External | Linkage::AvailableExternally | Linkage::Internal => false, } } diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index c58ab6d2a9bef..0784064547e0f 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -13,8 +13,7 @@ use rustc_hir::def_id::LOCAL_CRATE; use rustc_log::tracing::trace; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::interpret::{ - self, Allocation, ConstAllocation, CtfeProvenance, ErrorHandled, Scalar as InterpScalar, - read_target_uint, + self, ConstAllocation, CtfeProvenance, ErrorHandled, Scalar as InterpScalar, read_target_uint, }; use rustc_middle::mono::MonoItem; use rustc_middle::ty::layout::LayoutOf; @@ -113,12 +112,7 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> { // NOTE: Alignment from attributes has already been applied to the allocation. set_global_alignment(self, global, alloc.align); - // A common symbol is storage the linker allocates and zero-fills, so giving the definition - // an initializer — even an all-zero one — takes it back out of `.comm`. A non-zero one is - // kept: the symbol is then an ordinary definition, which is what GCC does with it too. - if attrs.linkage != Some(Linkage::Common) || !is_zero_initializer(alloc) { - global.global_set_initializer_rvalue(value); - } + global.global_set_initializer_rvalue(value); // As an optimization, all shared statics which do not have interior // mutability are placed into read-only memory. @@ -458,17 +452,6 @@ pub(crate) fn const_alloc_to_gcc_uncached<'gcc>( cx.const_struct(&llvals, true) } -/// Whether this allocation is all zeroes, and so needs no initializer to be spelled out. -fn is_zero_initializer(alloc: &Allocation) -> bool { - alloc.provenance().ptrs().is_empty() - // This `inspect` is okay: it is within the bounds of the allocation, there is no provenance - // to misread, and it does not affect interpreter execution. - && alloc - .inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.size().bytes_usize()) - .iter() - .all(|&byte| byte == 0) -} - fn codegen_static_initializer<'gcc, 'tcx>( cx: &CodegenCx<'gcc, 'tcx>, def_id: DefId, diff --git a/compiler/rustc_codegen_gcc/tests/c/import_linkage.c b/compiler/rustc_codegen_gcc/tests/c/import_linkage.c index f2beb9603d08b..227fa1c848ddf 100644 --- a/compiler/rustc_codegen_gcc/tests/c/import_linkage.c +++ b/compiler/rustc_codegen_gcc/tests/c/import_linkage.c @@ -6,12 +6,9 @@ #include -int32_t external_value = 1; int32_t available_externally_value = 2; int32_t linkonce_value = 3; int32_t linkonce_odr_value = 4; int32_t weak_value = 5; int32_t weak_odr_value = 6; -int32_t common_value = 7; int32_t extern_weak_value = 8; -int32_t internal_value = 9; diff --git a/compiler/rustc_codegen_gcc/tests/c/static_linkage.c b/compiler/rustc_codegen_gcc/tests/c/static_linkage.c index 787e61f9cf105..00360d8633e68 100644 --- a/compiler/rustc_codegen_gcc/tests/c/static_linkage.c +++ b/compiler/rustc_codegen_gcc/tests/c/static_linkage.c @@ -1,9 +1,6 @@ /* Strong definitions of the statics that `tests/run/static_linkage.rs` also defines, but weakly. * The linker has to keep these and drop the Rust ones; a backend that emits the Rust definitions - * as ordinary global symbols fails the link with a duplicate definition instead. - * - * `internal_static` is the opposite case: the Rust side keeps its own, and the two definitions - * coexist because the Rust one is local. */ + * as ordinary global symbols fails the link with a duplicate definition instead. */ #include @@ -11,8 +8,6 @@ int32_t weak_static = 1; int32_t weak_odr_static = 2; int32_t linkonce_static = 3; int32_t linkonce_odr_static = 4; -int32_t common_static = 5; -int32_t internal_static = 200; /* `available_externally` promises the real definition lives elsewhere: a backend may read this one * or emit an equivalent copy of the Rust initializer, so the two have to hold the same value. */ @@ -29,9 +24,5 @@ int32_t c_read_all(void) return 13; if (linkonce_odr_static != 4) return 14; - if (common_static != 5) - return 15; - if (internal_static != 200) - return 16; return 0; } diff --git a/compiler/rustc_codegen_gcc/tests/run/import_linkage.rs b/compiler/rustc_codegen_gcc/tests/run/import_linkage.rs index bf5cb9e532799..58008ecbc9746 100644 --- a/compiler/rustc_codegen_gcc/tests/run/import_linkage.rs +++ b/compiler/rustc_codegen_gcc/tests/run/import_linkage.rs @@ -19,8 +19,6 @@ extern crate mini_core; use mini_core::*; extern "C" { - #[linkage = "external"] - static external_value: *const i32; #[linkage = "available_externally"] static available_externally_value: *const i32; #[linkage = "linkonce"] @@ -31,15 +29,8 @@ extern "C" { static weak_value: *const i32; #[linkage = "weak_odr"] static weak_odr_value: *const i32; - #[linkage = "common"] - static common_value: *const i32; #[linkage = "extern_weak"] static extern_weak_value: *const i32; - // An import is an undefined reference whatever the flavour says. Upstream bug: rustc lowers - // this one to an internal declaration, which LLVM's verifier rejects ("Global is external, but - // doesn't have external or weak linkage!") and which crashes cg_llvm at -O3. - #[linkage = "internal"] - static internal_value: *const i32; // Nothing defines this one, so it stays null instead of breaking the link. #[linkage = "extern_weak"] @@ -49,9 +40,6 @@ extern "C" { #[no_mangle] extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 { unsafe { - if *external_value != 1 { - return 1; - } if *available_externally_value != 2 { return 2; } @@ -67,15 +55,9 @@ extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 { if *weak_odr_value != 6 { return 6; } - if *common_value != 7 { - return 7; - } if *extern_weak_value != 8 { return 8; } - if *internal_value != 9 { - return 9; - } if undefined_value as usize != 0 { return 10; } diff --git a/compiler/rustc_codegen_gcc/tests/run/static_linkage.rs b/compiler/rustc_codegen_gcc/tests/run/static_linkage.rs index 7b911c064d797..3c9303fa8cf16 100644 --- a/compiler/rustc_codegen_gcc/tests/run/static_linkage.rs +++ b/compiler/rustc_codegen_gcc/tests/run/static_linkage.rs @@ -7,8 +7,7 @@ // `tests/c/static_linkage.c`, which defines the overridable ones strongly. // // If `predefine_static` were to ignore its `linkage` argument outright, every static would come out as -// an ordinary global symbol: the overridable ones would clash with the C definitions at link time, and -// `internal` would export a symbol it should have kept private. +// an ordinary global symbol: the overridable ones would clash with the C definitions at link time. #![feature(linkage, no_core)] #![no_std] @@ -34,16 +33,6 @@ pub static linkonce_static: i32 = 0; #[no_mangle] pub static linkonce_odr_static: i32 = 0; -// `common` is only valid on a mutable global: LLVM rejects a constant one. -#[linkage = "common"] -#[no_mangle] -pub static mut common_static: i32 = 0; - -// Private to this crate, so the C definition of the same name is a different object. -#[linkage = "internal"] -#[no_mangle] -pub static internal_static: i32 = 100; - // Not overridden by the C side: the definition here is the one that survives. #[linkage = "weak"] #[no_mangle] @@ -66,9 +55,6 @@ extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 { return result; } - if internal_static != 100 { - return 1; - } if only_weak_static != 6 { return 2; } diff --git a/compiler/rustc_codegen_gcc/tests/run/weak_function_linkage.rs b/compiler/rustc_codegen_gcc/tests/run/weak_function_linkage.rs index 677f01353401a..406b85df10b02 100644 --- a/compiler/rustc_codegen_gcc/tests/run/weak_function_linkage.rs +++ b/compiler/rustc_codegen_gcc/tests/run/weak_function_linkage.rs @@ -41,9 +41,6 @@ extern "C" fn linkonce_odr_function() -> i32 { 4 } -// `#[linkage = "common"]` is absent on purpose: a common symbol is `SHN_COMMON`, which the object -// format only allows for objects, so no backend can give a function that linkage. - // Not overridden by the C side: the definition here is the one that runs. #[linkage = "weak"] #[no_mangle] diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index cf278694399f3..77cb37edec770 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -237,7 +237,6 @@ pub(crate) fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage { Linkage::WeakODR => llvm::Linkage::WeakODRLinkage, Linkage::Internal => llvm::Linkage::InternalLinkage, Linkage::ExternalWeak => llvm::Linkage::ExternalWeakLinkage, - Linkage::Common => llvm::Linkage::CommonLinkage, } } diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index 7a05bf718663c..a5a4f0b3ddb25 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -67,30 +67,30 @@ pub(crate) fn maybe_sign_fn_ptr<'ll, 'tcx>( } /* -* A note on nomenclature of linking: "extern", "foreign", and "upcall". -* -* An "extern" is an LLVM symbol we wind up emitting an undefined external -* reference to. This means "we don't have the thing in this compilation unit, -* please make sure you link it in at runtime". This could be a reference to -* C code found in a C library, or rust code found in a rust crate. -* -* Most "externs" are implicitly declared (automatically) as a result of a -* user declaring an extern _module_ dependency; this causes the rust driver -* to locate an extern crate, scan its compilation metadata, and emit extern -* declarations for any symbols used by the declaring crate. -* -* A "foreign" is an extern that references C (or other non-rust ABI) code. -* There is no metadata to scan for extern references so in these cases either -* a header-digester like bindgen, or manual function prototypes, have to -* serve as declarators. So these are usually given explicitly as prototype -* declarations, in rust code, with ABI attributes on them noting which ABI to -* link via. -* -* An "upcall" is a foreign call generated by the compiler (not corresponding -* to any user-written call in the code) into the runtime library, to perform -* some helper task such as bringing a task to life, allocating memory, etc. -* -*/ + * A note on nomenclature of linking: "extern", "foreign", and "upcall". + * + * An "extern" is an LLVM symbol we wind up emitting an undefined external + * reference to. This means "we don't have the thing in this compilation unit, + * please make sure you link it in at runtime". This could be a reference to + * C code found in a C library, or rust code found in a rust crate. + * + * Most "externs" are implicitly declared (automatically) as a result of a + * user declaring an extern _module_ dependency; this causes the rust driver + * to locate an extern crate, scan its compilation metadata, and emit extern + * declarations for any symbols used by the declaring crate. + * + * A "foreign" is an extern that references C (or other non-rust ABI) code. + * There is no metadata to scan for extern references so in these cases either + * a header-digester like bindgen, or manual function prototypes, have to + * serve as declarators. So these are usually given explicitly as prototype + * declarations, in rust code, with ABI attributes on them noting which ABI to + * link via. + * + * An "upcall" is a foreign call generated by the compiler (not corresponding + * to any user-written call in the code) into the runtime library, to perform + * some helper task such as bringing a task to life, allocating memory, etc. + * + */ /// A structure representing an active landing pad for the duration of a basic /// block. diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 19bbf0cf3d8d8..93ef87eea026d 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -5,7 +5,6 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(trim_prefix_suffix))] #![feature(extern_types)] #![feature(file_buffered)] #![feature(impl_trait_in_assoc_type)] diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs index 2fa6f3fc06550..5433b9da6f2b6 100644 --- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs +++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs @@ -228,7 +228,6 @@ fn prefix_and_suffix<'tcx>( // LTO can fail when internal linkage is used. emit_fatal("naked functions may not have internal linkage") } - Linkage::Common => emit_fatal("Functions may not have common linkage"), Linkage::AvailableExternally => { // this would make the function equal an extern definition emit_fatal("Functions may not have available_externally linkage") diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index a853dd63d3435..981813f13c97f 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -1,5 +1,4 @@ // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(never_type))] #![feature(array_try_map)] #![feature(decl_macro)] #![feature(deref_patterns)] diff --git a/compiler/rustc_data_structures/src/fx.rs b/compiler/rustc_data_structures/src/fx.rs index cad775cc98641..76b2c428ec84d 100644 --- a/compiler/rustc_data_structures/src/fx.rs +++ b/compiler/rustc_data_structures/src/fx.rs @@ -28,7 +28,7 @@ macro_rules! define_stable_id_collections { } pub mod default { - use super::{FxBuildHasher, FxHashMap, FxHashSet}; + use super::{FxBuildHasher, FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; // FIXME: These two functions will become unnecessary after // lands and we start using the corresponding @@ -40,4 +40,12 @@ pub mod default { pub const fn fx_hash_set() -> FxHashSet { FxHashSet::with_hasher(FxBuildHasher) } + + pub const fn fx_index_map() -> FxIndexMap { + FxIndexMap::with_hasher(FxBuildHasher) + } + + pub const fn fx_index_set() -> FxIndexSet { + FxIndexSet::with_hasher(FxBuildHasher) + } } diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 4ebd6ef9f92b3..aae378939452b 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -10,12 +10,10 @@ #![allow(internal_features)] #![allow(rustc::default_hash_types)] #![allow(rustc::potential_query_instability)] -#![cfg_attr(bootstrap, feature(allocator_api))] -#![cfg_attr(bootstrap, feature(never_type))] #![cfg_attr(bootstrap, feature(unwrap_infallible))] -#![cfg_attr(not(bootstrap), feature(allocator_ext))] #![cfg_attr(test, feature(test))] #![deny(unsafe_op_in_unsafe_fn)] +#![feature(allocator_ext)] #![feature(ascii_char)] #![feature(ascii_char_variants)] #![feature(auto_traits)] diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 210f04a115831..7940dc3978496 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -5,7 +5,6 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(trim_prefix_suffix))] #![feature(decl_macro)] #![feature(file_buffered)] #![feature(panic_backtrace_config)] diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 37a3594e374ea..4eb7408244728 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -47,7 +47,7 @@ declare_features! ( /// Allows `#[target_feature(...)]` on aarch64 platforms (accepted, aarch64_target_feature, "1.61.0", Some(44839)), /// Allows `extern "custom" fn()`. - (accepted, abi_custom, "CURRENT_RUSTC_VERSION", Some(140829)), + (accepted, abi_custom, "1.100.0", Some(140829)), /// Allows using the `efiapi` ABI. (accepted, abi_efiapi, "1.68.0", Some(65815)), /// Allows the sysV64 ABI to be specified on all platforms @@ -336,7 +336,7 @@ declare_features! ( /// Allows specifying the whole-archive link modifier (accepted, native_link_modifiers_whole_archive, "1.61.0", Some(81490)), /// Allows the `!` type. - (accepted, never_type, "CURRENT_RUSTC_VERSION", Some(35121)), + (accepted, never_type, "1.100.0", Some(35121)), /// Allows using non lexical lifetimes (RFC 2094). (accepted, nll, "1.63.0", Some(43234)), /// Allows using `#![no_std]`. diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 5e89a060e3335..eca2567ab20ff 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -55,7 +55,7 @@ declare_features! ( /// Allows using the `amdgpu-kernel` ABI. (removed, abi_amdgpu_kernel, "1.77.0", Some(51575), None, 120495), (removed, abi_c_cmse_nonsecure_call, "1.90.0", Some(81391), Some("renamed to abi_cmse_nonsecure_call"), 142146), - (removed, abi_unadjusted, "CURRENT_RUSTC_VERSION", None, Some("merged into link_llvm_intrinsics"), 161398), + (removed, abi_unadjusted, "1.100.0", None, Some("merged into link_llvm_intrinsics"), 161398), (removed, advanced_slice_patterns, "1.42.0", Some(62254), Some("merged into `#![feature(slice_patterns)]`"), 67712), (removed, allocator, "1.0.0", None, None), @@ -67,7 +67,7 @@ declare_features! ( (removed, await_macro, "1.38.0", Some(50547), Some("subsumed by `.await` syntax"), 62293), /// Allows using `box` in patterns (RFC 469). - (removed, box_patterns, "CURRENT_RUSTC_VERSION", Some(29641), Some("superseded by `deref_patterns`")), + (removed, box_patterns, "1.100.0", Some(29641), Some("superseded by `deref_patterns`")), /// Allows using the `box $expr` syntax. (removed, box_syntax, "1.70.0", Some(49733), Some("replaced with `#[rustc_box]`"), 108471), /// Allows capturing disjoint fields in a closure/coroutine (RFC 2229). @@ -167,7 +167,7 @@ declare_features! ( ), 133768 ), - (removed, generic_const_args, "CURRENT_RUSTC_VERSION", Some(151972), Some("renamed to `gca_const_items`")), + (removed, generic_const_args, "1.100.0", Some(151972), Some("renamed to `gca_const_items`")), (removed, import_shadowing, "1.0.0", None, None), /// Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`). (removed, in_band_lifetimes, "1.61.0", Some(44524), @@ -193,12 +193,12 @@ declare_features! ( which is available from cargo build scripts with `cargo:rustc-link-arg` now"), 83820), (removed, macro_reexport, "1.0.0", Some(29638), Some("subsumed by `pub use`"), 49982), - (removed, macroless_const_item_generic_const_args, "CURRENT_RUSTC_VERSION", Some(162540), Some("renamed to `gca_macroless_items`")), - (removed, macroless_generic_const_args, "CURRENT_RUSTC_VERSION", Some(159006), Some("renamed to `gca_macroless_args`")), + (removed, macroless_const_item_generic_const_args, "1.100.0", Some(162540), Some("renamed to `gca_macroless_items`")), + (removed, macroless_generic_const_args, "1.100.0", Some(159006), Some("renamed to `gca_macroless_args`")), /// Allows using `#[main]` to replace the entrypoint `#[lang = "start"]` calls. (removed, main, "1.53.0", Some(29634), None, 84217), (removed, managed_boxes, "1.0.0", None, None), - (removed, min_generic_const_args, "CURRENT_RUSTC_VERSION", Some(132980), Some("renamed to `gca_min_const_items`")), + (removed, min_generic_const_args, "1.100.0", Some(132980), Some("renamed to `gca_min_const_items`")), /// Allows the use of type alias impl trait in function return positions (removed, min_type_alias_impl_trait, "1.56.0", Some(63063), Some("removed in favor of full type_alias_impl_trait"), 87564), diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index cb6a1d39b1dd8..1af55be52abde 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -235,7 +235,7 @@ declare_features! ( /// Allows checking whether or not the backend correctly supports unstable float types. (internal, cfg_target_has_reliable_f16_f128, "1.88.0", None), /// Allows checking whether or not the backend correctly supports the unstable `f16b` type. - (internal, cfg_target_has_reliable_f16b, "CURRENT_RUSTC_VERSION", None), + (internal, cfg_target_has_reliable_f16b, "1.100.0", None), /// Allows checking whether or not the target might have thread support. (internal, cfg_target_has_threads, "1.99.0", None), /// Allows identifying the `compiler_builtins` crate. @@ -257,7 +257,7 @@ declare_features! ( /// Allows `#[link(..., cfg(..))]`; perma-unstable per #37406 (internal, link_cfg, "1.14.0", None), /// Allows using `#[link_name="__enzyme_*"]`. - (internal, link_enzyme_intrinsics, "CURRENT_RUSTC_VERSION", None), + (internal, link_enzyme_intrinsics, "1.100.0", None), /// Allows using `?Trait` trait bounds in more contexts. (internal, more_maybe_bounds, "1.82.0", None), /// Allow negative trait bounds. This is an internal-only feature for testing the trait solver! @@ -273,7 +273,7 @@ declare_features! ( /// Allows using the `#[stable]` and `#[unstable]` attributes. (internal, staged_api, "1.0.0", None), /// Perma-unstable, only used in the test suite for binders (`for<'a>`). - (internal, test_binder_constraints, "CURRENT_RUSTC_VERSION", None), + (internal, test_binder_constraints, "1.100.0", None), /// Perma-unstable, only used to test the `incomplete_features` lint. (incomplete, test_incomplete_feature, "1.96.0", None), /// Added for testing unstable lints; perma-unstable. @@ -530,7 +530,7 @@ declare_features! ( /// Allow using 16-bit (half precision) floating point numbers. (unstable, f16, "1.78.0", Some(116909)), /// Allow using bfloat16 floating point numbers. - (unstable, f16b, "CURRENT_RUSTC_VERSION", Some(160630)), + (unstable, f16b, "1.100.0", Some(160630)), /// Allows the use of `#[ffi_const]` on foreign functions. (unstable, ffi_const, "1.45.0", Some(58328)), /// Allows the use of `#[ffi_pure]` on foreign functions. @@ -548,7 +548,7 @@ declare_features! ( /// Support delegating implementation of functions to other already implemented functions. (incomplete, fn_delegation, "1.76.0", Some(118212)), /// Traits for function pointers and items - (unstable, fn_static, "CURRENT_RUSTC_VERSION", Some(148768)), + (unstable, fn_static, "1.100.0", Some(148768)), /// Allows using forced keywords `k#fn`. (unstable, forced_keywords, "CURRENT_RUSTC_VERSION", Some(153839)), /// Allows impls for the Freeze trait. @@ -563,7 +563,7 @@ declare_features! ( (incomplete, gca_macroless_args, "1.99.0", Some(159006)), /// Allows directly represented gca_const_items as the rhs of const items without the /// `gca!` macro. - (incomplete, gca_macroless_items, "CURRENT_RUSTC_VERSION", Some(162540)), + (incomplete, gca_macroless_items, "1.100.0", Some(162540)), /// Enables the generic const args MVP (paths to type const items and constructors /// for ADTs and primitives). (incomplete, gca_min_const_items, "1.84.0", Some(132980)), diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 92ef008610098..0f6041b44b2f2 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -3,7 +3,6 @@ //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(never_type))] #![feature(associated_type_defaults)] #![feature(closure_track_caller)] #![feature(const_default)] diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index efed5994f63fe..e7f20766bc8eb 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -115,7 +115,11 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran Err(CopyImplementationError::HasDestructor(did)) => { let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; let impl_ = tcx.def_span(did); - Err(tcx.dcx().emit_err(diagnostics::CopyImplOnTypeWithDtor { span, impl_ })) + Err(tcx.dcx().emit_err(diagnostics::TraitImplOnTypeWithDtor { + span, + impl_, + trait_name: sym::Copy, + })) } Err(CopyImplementationError::HasUnsafeFields) => { let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; @@ -537,6 +541,15 @@ pub(crate) fn reborrow_info<'tcx>( assert_field_type_is_copy(tcx, &infcx, impl_did, param_env, field.ty, field.span)?; } + if let Some(did) = def.destructor(tcx).map(|dtor| dtor.did) { + let impl_ = tcx.def_span(did); + return Err(tcx.dcx().emit_err(diagnostics::TraitImplOnTypeWithDtor { + span, + impl_, + trait_name: sym::Reborrow, + })); + } + Ok(()) } diff --git a/compiler/rustc_hir_analysis/src/diagnostics.rs b/compiler/rustc_hir_analysis/src/diagnostics.rs index 421f0b52d5a3b..7e5e794b75f78 100644 --- a/compiler/rustc_hir_analysis/src/diagnostics.rs +++ b/compiler/rustc_hir_analysis/src/diagnostics.rs @@ -296,13 +296,14 @@ pub(crate) struct FieldAlreadyDeclaredNestedHelp { } #[derive(Diagnostic)] -#[diag("the trait `Copy` cannot be implemented for this type; the type has a destructor", code = E0184)] -pub(crate) struct CopyImplOnTypeWithDtor { +#[diag("the trait `{$trait_name}` cannot be implemented for this type; the type has a destructor", code = E0184)] +pub(crate) struct TraitImplOnTypeWithDtor { #[primary_span] - #[label("`Copy` not allowed on types with destructors")] + #[label("`{$trait_name}` not allowed on types with destructors")] pub span: Span, #[note("destructor declared here")] pub impl_: Span, + pub trait_name: Symbol, } #[derive(Diagnostic)] diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index c0abcc3a6119a..1cd9d008194fc 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -56,7 +56,6 @@ This API is completely unstable and subject to change. */ // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(never_type))] #![cfg_attr(bootstrap, feature(unwrap_infallible))] #![feature(default_field_values)] #![feature(gen_blocks)] diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 02e6b8188a876..14cb73e28c871 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -39,7 +39,7 @@ use rustc_lint_defs::builtin::{TRIVIAL_CASTS, TRIVIAL_NUMERIC_CASTS}; use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::mir::Mutability; use rustc_middle::ty::adjustment::AllowTwoPhase; -use rustc_middle::ty::cast::{CastKind, CastTy}; +use rustc_middle::ty::cast::CastTy; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, Unnormalized, VariantDef, elaborate, @@ -52,6 +52,22 @@ use tracing::{debug, instrument}; use super::FnCtxt; use crate::{diagnostics, type_error_struct}; +/// Cast Kind. See [RFC 401](https://rust-lang.github.io/rfcs/0401-coercions.html) +/// (or rustc_hir_typeck/src/cast.rs). +#[derive(Copy, Clone, Debug)] +pub enum CastKind { + PtrPtrCast, + PtrAddrCast, + AddrPtrCast, + NumericCast, + EnumCast, + PrimIntCast, + U8CharCast, + ArrayPtrCast, + FnPtrPtrCast, + FnPtrAddrCast, +} + /// Reifies a cast check to be checked once we have full type information for /// a function context. #[derive(Debug)] @@ -912,7 +928,6 @@ impl<'a, 'tcx> CastCheck<'tcx> { /// directly. coercion-cast is handled in check instead of here. fn do_check(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result> { use rustc_middle::ty::cast::CastTy::*; - use rustc_middle::ty::cast::IntTy::*; let (t_from, t_cast) = match (CastTy::from_ty(self.expr_ty), CastTy::from_ty(self.cast_ty)) { @@ -947,7 +962,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { // a cast. ty::Ref(_, inner_ty, mutbl) => { return match t_cast { - Int(_) | Float => match *inner_ty.kind() { + Int | CEnum | Bool | Char | Float => match *inner_ty.kind() { ty::Int(_) | ty::Uint(_) | ty::Float(_) @@ -979,19 +994,21 @@ impl<'a, 'tcx> CastCheck<'tcx> { } match (t_from, t_cast) { // These types have invariants! can't cast into them. - (_, Int(CEnum) | FnPtr) => Err(CastError::NonScalar), + (_, CEnum | FnPtr) => Err(CastError::NonScalar), // * -> Bool - (_, Int(Bool)) => Err(CastError::CastToBool), + (_, Bool) => Err(CastError::CastToBool), // * -> Char - (Int(U(ty::UintTy::U8)), Int(Char)) => Ok(CastKind::U8CharCast), // u8-char-cast - (_, Int(Char)) => Err(CastError::CastToChar), + (Int, Char) if self.expr_ty == fcx.tcx.types.u8 => { + Ok(CastKind::U8CharCast) // u8-char-cast + } + (_, Char) => Err(CastError::CastToChar), // prim -> float,ptr - (Int(Bool) | Int(CEnum) | Int(Char), Float) => Err(CastError::NeedViaInt), + (Bool | CEnum | Char, Float) => Err(CastError::NeedViaInt), - (Int(Bool) | Int(CEnum) | Int(Char) | Float, Ptr(_)) | (Ptr(_) | FnPtr, Float) => { + (Bool | CEnum | Char | Float, Ptr(_)) | (Ptr(_) | FnPtr, Float) => { Err(CastError::IllegalCast) } @@ -999,24 +1016,24 @@ impl<'a, 'tcx> CastCheck<'tcx> { (Ptr(m_e), Ptr(m_c)) => self.check_ptr_ptr_cast(fcx, m_e, m_c), // ptr-ptr-cast // ptr-addr-cast - (Ptr(m_expr), Int(_)) => self.check_ptr_addr_cast(fcx, m_expr), + (Ptr(m_expr), Int) => self.check_ptr_addr_cast(fcx, m_expr), - (FnPtr, Int(_)) => { + (FnPtr, Int) => { // FIXME(#95489): there should eventually be a lint for these casts Ok(CastKind::FnPtrAddrCast) } // addr-ptr-cast - (Int(_), Ptr(mt)) => self.check_addr_ptr_cast(fcx, mt), + (Int, Ptr(mt)) => self.check_addr_ptr_cast(fcx, mt), // fn-ptr-cast (FnPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt), // enum -> int - (Int(CEnum), Int(_)) => self.check_enum_cast(fcx), + (CEnum, Int) => self.check_enum_cast(fcx), // prim -> prim - (Int(Char) | Int(Bool), Int(_)) => Ok(CastKind::PrimIntCast), + (Char | Bool, Int) => Ok(CastKind::PrimIntCast), - (Int(_) | Float, Int(_) | Float) => Ok(CastKind::NumericCast), + (Int | Float, Int | Float) => Ok(CastKind::NumericCast), } } diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 474a390171514..5efb2775c77fe 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -1,6 +1,4 @@ // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(never_type))] -#![cfg_attr(bootstrap, feature(trim_prefix_suffix))] #![feature(deref_patterns)] #![feature(iter_intersperse)] #![feature(iter_order_by)] diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 2a0901e0243b6..a722f0e103ea1 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2825,8 +2825,7 @@ declare_lint! { /// /// ### Example /// - #[cfg_attr(bootstrap, doc = "```rust,ignore")] - #[cfg_attr(not(bootstrap), doc = "```rust,compile_fail")] + /// ```rust,compile_fail /// #![feature(staged_api)] /// #![stable(feature = "test", since = "1.0.0")] /// @@ -2837,9 +2836,9 @@ declare_lint! { /// pub use self::S as T; /// /// fn main() {} - #[doc = "```"] + /// ``` /// - #[cfg_attr(not(bootstrap), doc = "{{produces}}")] + /// {{produces}} /// /// ### Explanation /// diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index b522fa00872de..fb918c2fba487 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -3,7 +3,6 @@ rustc::default_hash_types, reason = "we like performance but can't use `rustc_data_structures`" )] -#![cfg_attr(bootstrap, feature(never_type))] #![deny( rustc::potential_query_instability, reason = "macros shall produce deterministic output/errors" diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index dd963fc8773c7..1706fece29a8b 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -1,6 +1,5 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![cfg_attr(bootstrap, feature(never_type))] #![feature(error_iter)] #![feature(file_buffered)] #![feature(gen_blocks)] diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 7dd920c7e39bd..5348ee0ccaac1 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1544,10 +1544,12 @@ impl CrateMetadata { fn get_proc_macro_quoted_span(&self, tcx: TyCtxt<'_>, index: usize) -> Span { self.root - .tables + .proc_macro_data + .as_ref() + .expect("missing proc macro data") .proc_macro_quoted_spans .get(self, index) - .unwrap_or_else(|| panic!("Missing proc macro quoted span: {index:?}")) + .unwrap_or_else(|| panic!("missing proc macro quoted span: {index:?}")) .decode((self, tcx)) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 40b61a52d2310..03493d0e1b6a9 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -404,35 +404,42 @@ impl<'a, 'tcx> TyEncoder<'tcx> for EncodeContext<'a, 'tcx> { // Shorthand for `$self.$tables.$table.set_some($def_id.index, $self.lazy($value))`, which would // normally need extra variables to avoid errors about multiple mutable borrows. -macro_rules! record { +// Also those macros greatly simplify refactorings and modifications of writing to tables. +macro_rules! record_some_lazy { ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{ - { - let value = $value; - let lazy = $self.lazy(value); - $self.$tables.$table.set_some($def_id.index, lazy); - } + let value = $value; + let lazy = $self.lazy(value); + $self.$tables.$table.set_some($def_id.index, lazy); }}; } +macro_rules! record_some { + ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => { + $self.$tables.$table.set_some($def_id.index, $value) + }; +} + +macro_rules! record_value { + ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => { + $self.$tables.$table.set($def_id.index, $value) + }; +} + // Shorthand for `$self.$tables.$table.set_some($def_id.index, $self.lazy_array($value))`, which would // normally need extra variables to avoid errors about multiple mutable borrows. macro_rules! record_array { ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{ - { - let value = $value; - let lazy = $self.lazy_array(value); - $self.$tables.$table.set_some($def_id.index, lazy); - } + let value = $value; + let lazy = $self.lazy_array(value); + $self.$tables.$table.set_some($def_id.index, lazy); }}; } macro_rules! record_defaulted_array { ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{ - { - let value = $value; - let lazy = $self.lazy_array(value); - $self.$tables.$table.set($def_id.index, lazy); - } + let value = $value; + let lazy = $self.lazy_array(value); + $self.$tables.$table.set($def_id.index, lazy); }}; } @@ -527,18 +534,18 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for def_id in std::iter::once(CRATE_DEF_ID) .chain(self.tcx.resolutions(()).proc_macros.iter().copied()) { - let def_key = self.lazy(defs.def_key(def_id)); + let def_key = defs.def_key(def_id); let def_path_hash = defs.def_path_hash(def_id); - self.tables.def_keys.set_some(def_id.local_def_index, def_key); - self.tables - .def_path_hashes - .set(def_id.local_def_index, def_path_hash.local_hash().as_u64()); + let def_id = def_id.to_def_id(); + + record_some_lazy!(self.tables.def_keys[def_id] <- def_key); + record_value!(self.tables.def_path_hashes[def_id] <- def_path_hash.local_hash().as_u64()) } } else { for (def_index, def_key, def_path_hash) in defs.enumerated_keys_and_path_hashes() { - let def_key = self.lazy(def_key); - self.tables.def_keys.set_some(def_index, def_key); - self.tables.def_path_hashes.set(def_index, def_path_hash.local_hash().as_u64()); + let def_id = LocalDefId { local_def_index: def_index }.to_def_id(); + record_some_lazy!(self.tables.def_keys[def_id] <- def_key); + record_value!(self.tables.def_path_hashes[def_id] <- def_path_hash.local_hash().as_u64()) } } } @@ -1444,7 +1451,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if state.is_doc_hidden { attr_flags |= AttrFlags::IS_DOC_HIDDEN; } - self.tables.attr_flags.set(def_id.local_def_index, attr_flags); + + record_value!(self.tables.attr_flags[def_id.to_def_id()] <- attr_flags) } fn encode_def_ids(&mut self) { @@ -1461,7 +1469,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for local_id in tcx.iter_local_def_id() { let def_id = local_id.to_def_id(); let def_kind = tcx.def_kind(local_id); - self.tables.def_kind.set_some(def_id.index, def_kind); + record_some!(self.tables.def_kind[def_id] <- def_kind); // The `DefCollector` will sometimes create unnecessary `DefId`s // for trivial const arguments which are directly lowered to @@ -1482,33 +1490,33 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { && let hir::Node::Field(field) = tcx.hir_node_by_def_id(local_id) && let Some(anon) = field.default { - record!(self.tables.default_fields[def_id] <- anon.def_id.to_def_id()); + record_some_lazy!(self.tables.default_fields[def_id] <- anon.def_id.to_def_id()); } if should_encode_span(def_kind) { let def_span = tcx.def_span(local_id); - record!(self.tables.def_span[def_id] <- def_span); + record_some_lazy!(self.tables.def_span[def_id] <- def_span); } if should_encode_attrs(def_kind) { self.encode_attrs(local_id); } if should_encode_expn_that_defined(def_kind) { - record!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id)); + record_some_lazy!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id)); } if should_encode_span(def_kind) && let Some(ident_span) = tcx.def_ident_span(def_id) { - record!(self.tables.def_ident_span[def_id] <- ident_span); + record_some_lazy!(self.tables.def_ident_span[def_id] <- ident_span); } if def_kind.has_codegen_attrs() { - record!(self.tables.codegen_fn_attrs[def_id] <- self.tcx.codegen_fn_attrs(def_id)); + record_some_lazy!(self.tables.codegen_fn_attrs[def_id] <- self.tcx.codegen_fn_attrs(def_id)); } if should_encode_visibility(def_kind) { let vis = self .tcx .local_visibility(local_id) .map_id(|mod_id| mod_id.to_local_def_id().local_def_index); - record!(self.tables.visibility[def_id] <- vis); + record_some_lazy!(self.tables.visibility[def_id] <- vis); } if should_encode_stability(def_kind) { self.encode_stability(def_id); @@ -1521,46 +1529,46 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record_array!(self.tables.variances_of[def_id] <- v); } if should_encode_fn_sig(def_kind) { - record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); + record_some_lazy!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); } if should_encode_generics(def_kind) { let g = tcx.generics_of(def_id); - record!(self.tables.generics_of[def_id] <- g); - record!(self.tables.explicit_clauses_of[def_id] <- self.tcx.explicit_clauses_of(def_id)); + record_some_lazy!(self.tables.generics_of[def_id] <- g); + record_some_lazy!(self.tables.explicit_clauses_of[def_id] <- self.tcx.explicit_clauses_of(def_id)); let inferred_outlives = self.tcx.inferred_outlives_of(def_id); record_defaulted_array!(self.tables.inferred_outlives_of[def_id] <- inferred_outlives); for param in &g.own_params { if let ty::GenericParamDefKind::Const { has_default: true, .. } = param.kind { let default = self.tcx.const_param_default(param.def_id); - record!(self.tables.const_param_default[param.def_id] <- default); + record_some_lazy!(self.tables.const_param_default[param.def_id] <- default); } } } if tcx.is_conditionally_const(def_id) { - record!(self.tables.const_conditions[def_id] <- self.tcx.const_conditions(def_id)); + record_some_lazy!(self.tables.const_conditions[def_id] <- self.tcx.const_conditions(def_id)); } if should_encode_type(tcx, local_id, def_kind) { - record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id)); + record_some_lazy!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id)); } if should_encode_constness(def_kind) { let constness = self.tcx.constness(def_id); - self.tables.constness.set(def_id.index, constness); + record_value!(self.tables.constness[def_id] <- constness) } if let DefKind::Fn | DefKind::AssocFn = def_kind { let asyncness = tcx.asyncness(def_id); - self.tables.asyncness.set(def_id.index, asyncness); + record_value!(self.tables.asyncness[def_id] <- asyncness); record_array!(self.tables.fn_arg_idents[def_id] <- tcx.fn_arg_idents(def_id)); } if let Some(name) = tcx.intrinsic(def_id) { - record!(self.tables.intrinsic[def_id] <- name); + record_some_lazy!(self.tables.intrinsic[def_id] <- name); } if let DefKind::TyParam | DefKind::Trait = def_kind { let default = self.tcx.object_lifetime_default(def_id); - record!(self.tables.object_lifetime_default[def_id] <- default); + record_some_lazy!(self.tables.object_lifetime_default[def_id] <- default); } if let DefKind::Trait = def_kind { - record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); + record_some_lazy!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); record_defaulted_array!(self.tables.explicit_super_clauses_of[def_id] <- self.tcx.explicit_super_clauses_of(def_id).skip_binder()); record_defaulted_array!(self.tables.explicit_implied_clauses_of[def_id] <- @@ -1574,7 +1582,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } if let DefKind::TraitAlias = def_kind { - record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); + record_some_lazy!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); record_defaulted_array!(self.tables.explicit_super_clauses_of[def_id] <- self.tcx.explicit_super_clauses_of(def_id).skip_binder()); record_defaulted_array!(self.tables.explicit_implied_clauses_of[def_id] <- @@ -1595,28 +1603,28 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let DefKind::Closure | DefKind::SyntheticCoroutineBody = def_kind && let Some(coroutine_kind) = self.tcx.coroutine_kind(def_id) { - self.tables.coroutine_kind.set(def_id.index, Some(coroutine_kind)) + record_value!(self.tables.coroutine_kind[def_id] <- Some(coroutine_kind)) } if def_kind == DefKind::Closure && tcx.type_of(def_id).skip_binder().is_coroutine_closure() { let coroutine_for_closure = self.tcx.coroutine_for_closure(def_id); - self.tables - .coroutine_for_closure - .set_some(def_id.index, coroutine_for_closure.into()); + record_some!(self.tables.coroutine_for_closure[def_id] <- coroutine_for_closure.into()); // If this async closure has a by-move body, record it too. if tcx.needs_coroutine_by_move_body_def_id(coroutine_for_closure) { - self.tables.coroutine_by_move_body_def_id.set_some( - coroutine_for_closure.index, - self.tcx.coroutine_by_move_body_def_id(coroutine_for_closure).into(), - ); + let id = self.tcx.coroutine_by_move_body_def_id(coroutine_for_closure); + record_some!( + self.tables.coroutine_by_move_body_def_id[coroutine_for_closure] <- id.into() + ) } } if let DefKind::Static { .. } = def_kind { if !self.tcx.is_foreign_item(def_id) { match self.tcx.eval_static_initializer(def_id) { - Ok(data) => record!(self.tables.eval_static_initializer[def_id] <- data), + Ok(data) => { + record_some_lazy!(self.tables.eval_static_initializer[def_id] <- data) + } Err(err) => match err { interpret::ErrorHandled::Reported(_, _) => { self.tcx.dcx().delayed_bug(format!( @@ -1640,50 +1648,49 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.encode_info_for_macro(local_id); } if let DefKind::TyAlias = def_kind { - self.tables - .type_alias_is_checked - .set(def_id.index, self.tcx.type_alias_is_checked(def_id)); + record_value!(self.tables.type_alias_is_checked[def_id] <- self.tcx.type_alias_is_checked(def_id)); + if self.tcx.type_alias_is_checked(def_id) { - record!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); + record_some_lazy!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); } } if let DefKind::OpaqueTy = def_kind { self.encode_explicit_item_bounds(def_id); self.encode_explicit_item_self_bounds(def_id); - record!(self.tables.opaque_ty_origin[def_id] <- self.tcx.opaque_ty_origin(def_id)); + record_some_lazy!(self.tables.opaque_ty_origin[def_id] <- self.tcx.opaque_ty_origin(def_id)); self.encode_precise_capturing_args(def_id); if tcx.is_conditionally_const(def_id) { record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id] <- tcx.explicit_implied_const_bounds(def_id).skip_binder()); } - record!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); + record_some_lazy!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); } if let DefKind::AssocTy = def_kind { let assoc_item = tcx.associated_item(def_id); match assoc_item.container { ty::AssocContainer::Trait => { - record!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); + record_some_lazy!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); } ty::AssocContainer::InherentImpl => { - record!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); + record_some_lazy!(self.tables.args_known_to_outlive_alias_params[def_id] <- tcx.args_known_to_outlive_alias_params(def_id)); } ty::AssocContainer::TraitImpl(_) => {} } } if let DefKind::AnonConst = def_kind { - record!(self.tables.anon_const_kind[def_id] <- self.tcx.anon_const_kind(def_id)); + record_some_lazy!(self.tables.anon_const_kind[def_id] <- self.tcx.anon_const_kind(def_id)); } if let DefKind::Const | DefKind::AssocConst = def_kind { - record!(self.tables.const_of_item[def_id] <- self.tcx.const_of_item(def_id)); + record_some_lazy!(self.tables.const_of_item[def_id] <- self.tcx.const_of_item(def_id)); } if tcx.impl_method_has_trait_impl_trait_tys(def_id) && let Ok(table) = self.tcx.collect_return_position_impl_trait_in_trait_tys(def_id) { - record!(self.tables.collect_return_position_impl_trait_in_trait_tys[def_id] <- table); + record_some_lazy!(self.tables.collect_return_position_impl_trait_in_trait_tys[def_id] <- table); } if let DefKind::Impl { .. } | DefKind::Trait = def_kind { let table = tcx.associated_types_for_impl_traits_in_trait_or_impl(def_id); - record!(self.tables.associated_types_for_impl_traits_in_trait_or_impl[def_id] <- table); + record_some_lazy!(self.tables.associated_types_for_impl_traits_in_trait_or_impl[def_id] <- table); } } @@ -1695,7 +1702,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } for (def_id, res_map) in &tcx.resolutions(()).doc_link_resolutions { - record!(self.tables.doc_link_resolutions[def_id.to_def_id()] <- res_map); + record_some_lazy!(self.tables.doc_link_resolutions[def_id.to_def_id()] <- res_map); } for (def_id, traits) in &tcx.resolutions(()).doc_link_traits_in_scope { @@ -1722,10 +1729,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let def_id = local_def_id.to_def_id(); let tcx = self.tcx; let adt_def = tcx.adt_def(def_id); - record!(self.tables.repr_options[def_id] <- adt_def.repr()); + record_some_lazy!(self.tables.repr_options[def_id] <- adt_def.repr()); let params_in_repr = self.tcx.params_in_repr(def_id); - record!(self.tables.params_in_repr[def_id] <- params_in_repr); + record_some_lazy!(self.tables.params_in_repr[def_id] <- params_in_repr); if adt_def.is_enum() { let module_children = tcx.module_children_local(local_def_id); @@ -1745,7 +1752,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)), is_non_exhaustive: variant.is_field_list_non_exhaustive(), }; - record!(self.tables.variant_data[variant.def_id] <- data); + record_some_lazy!(self.tables.variant_data[variant.def_id] <- data); record_array!(self.tables.associated_item_or_field_def_ids[variant.def_id] <- variant.fields.iter().map(|f| { assert!(f.did.is_local()); @@ -1753,8 +1760,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { })); for field in &variant.fields { - self.tables.safety.set(field.did.index, field.safety); - record!( + record_value!(self.tables.safety[field.did] <- field.safety); + record_some_lazy!( self.tables.mut_restriction[field.did] <- field.mut_restriction ); } @@ -1762,16 +1769,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let Some((CtorKind::Fn, ctor_def_id)) = variant.ctor { let fn_sig = tcx.fn_sig(ctor_def_id); // FIXME only encode signature for ctor_def_id - record!(self.tables.fn_sig[variant.def_id] <- fn_sig); + record_some_lazy!(self.tables.fn_sig[variant.def_id] <- fn_sig); } } if let Some(destructor) = tcx.adt_destructor(local_def_id) { - record!(self.tables.adt_destructor[def_id] <- destructor); + record_some_lazy!(self.tables.adt_destructor[def_id] <- destructor); } if let Some(destructor) = tcx.adt_async_destructor(local_def_id) { - record!(self.tables.adt_async_destructor[def_id] <- destructor); + record_some_lazy!(self.tables.adt_async_destructor[def_id] <- destructor); } } @@ -1787,7 +1794,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // items - we encode information about proc-macros later on. if self.is_proc_macro { // Encode this here because we don't do it in encode_def_ids. - record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id)); + record_some_lazy!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id)); } else { let module_children = tcx.module_children_local(local_def_id); @@ -1826,10 +1833,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let item = tcx.associated_item(def_id); if matches!(item.container, AssocContainer::Trait | AssocContainer::TraitImpl(_)) { - self.tables.defaultness.set(def_id.index, item.defaultness(tcx)); + record_value!(self.tables.defaultness[def_id] <- item.defaultness(tcx)); } - record!(self.tables.assoc_container[def_id] <- item.container); + record_some_lazy!(self.tables.assoc_container[def_id] <- item.container); if let AssocContainer::Trait = item.container && item.is_type() @@ -1842,7 +1849,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } if let ty::AssocKind::Type { data: ty::AssocTypeData::Rpitit(rpitit_info) } = item.kind { - record!(self.tables.opt_rpitit_info[def_id] <- rpitit_info); + record_some_lazy!(self.tables.opt_rpitit_info[def_id] <- rpitit_info); if matches!(rpitit_info, ty::ImplTraitInTraitData::Trait { .. }) { record_array!( self.tables.assumed_wf_types_for_rpitit[def_id] @@ -1878,53 +1885,53 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("EntryBuilder::encode_mir({:?})", def_id); if encode_opt { - record!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id)); - self.tables - .cross_crate_inlinable - .set(def_id.to_def_id().index, self.tcx.cross_crate_inlinable(def_id)); - record!(self.tables.closure_saved_names_of_captured_variables[def_id.to_def_id()] + record_some_lazy!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id)); + + record_value!(self.tables.cross_crate_inlinable[def_id.to_def_id()] <- self.tcx.cross_crate_inlinable(def_id)); + + record_some_lazy!(self.tables.closure_saved_names_of_captured_variables[def_id.to_def_id()] <- tcx.closure_saved_names_of_captured_variables(def_id)); if self.tcx.is_coroutine(def_id.to_def_id()) && let Some(witnesses) = tcx.mir_coroutine_witnesses(def_id) { - record!(self.tables.mir_coroutine_witnesses[def_id.to_def_id()] <- witnesses); + record_some_lazy!(self.tables.mir_coroutine_witnesses[def_id.to_def_id()] <- witnesses); } } let mut is_trivial = false; if encode_const { if let Some((val, ty)) = tcx.trivial_const(def_id) { is_trivial = true; - record!(self.tables.trivial_const[def_id.to_def_id()] <- (val, ty)); + record_some_lazy!(self.tables.trivial_const[def_id.to_def_id()] <- (val, ty)); } else { is_trivial = false; - record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- tcx.mir_for_ctfe(def_id)); + record_some_lazy!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- tcx.mir_for_ctfe(def_id)); } // FIXME(generic_const_exprs): this feels wrong to have in `encode_mir` let abstract_const = tcx.thir_abstract_const(def_id); if let Ok(Some(abstract_const)) = abstract_const { - record!(self.tables.thir_abstract_const[def_id.to_def_id()] <- abstract_const); + record_some_lazy!(self.tables.thir_abstract_const[def_id.to_def_id()] <- abstract_const); } if should_encode_const(tcx.def_kind(def_id)) { let qualifs = tcx.mir_const_qualif(def_id); - record!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs); + record_some_lazy!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs); let body = tcx.hir_maybe_body_owned_by(def_id); if let Some(body) = body { let const_data = rendered_const(self.tcx, &body, def_id); - record!(self.tables.rendered_const[def_id.to_def_id()] <- const_data); + record_some_lazy!(self.tables.rendered_const[def_id.to_def_id()] <- const_data); } } } if !is_trivial { - record!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id)); + record_some_lazy!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id)); } if self.tcx.is_coroutine(def_id.to_def_id()) && let Some(witnesses) = tcx.mir_coroutine_witnesses(def_id) { - record!(self.tables.mir_coroutine_witnesses[def_id.to_def_id()] <- witnesses); + record_some_lazy!(self.tables.mir_coroutine_witnesses[def_id.to_def_id()] <- witnesses); } } @@ -1950,7 +1957,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // the stability attributes are even enabled before using their queries. if self.feat.staged_api() || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked { if let Some(stab) = self.tcx.lookup_stability(def_id) { - record!(self.tables.lookup_stability[def_id] <- stab) + record_some_lazy!(self.tables.lookup_stability[def_id] <- stab) } } } @@ -1961,7 +1968,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // the stability attributes are even enabled before using their queries. if self.feat.staged_api() || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked { if let Some(stab) = self.tcx.lookup_const_stability(def_id) { - record!(self.tables.lookup_const_stability[def_id] <- stab) + record_some_lazy!(self.tables.lookup_const_stability[def_id] <- stab) } } } @@ -1972,7 +1979,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // the stability attributes are even enabled before using their queries. if self.feat.staged_api() || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked { if let Some(stab) = self.tcx.lookup_default_body_stability(def_id) { - record!(self.tables.lookup_default_body_stability[def_id] <- stab) + record_some_lazy!(self.tables.lookup_default_body_stability[def_id] <- stab) } } } @@ -1980,7 +1987,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn encode_deprecation(&mut self, def_id: DefId) { if let Some(depr) = self.tcx.lookup_deprecation(def_id) { - record!(self.tables.lookup_deprecation_entry[def_id] <- depr); + record_some_lazy!(self.tables.lookup_deprecation_entry[def_id] <- depr); } } @@ -1989,8 +1996,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let tcx = self.tcx; let (_, macro_def, _) = tcx.hir_expect_item(def_id).expect_macro(); - self.tables.is_macro_rules.set(def_id.local_def_index, macro_def.macro_rules); - record!(self.tables.macro_definition[def_id.to_def_id()] <- &*macro_def.body); + record_value!(self.tables.is_macro_rules[def_id.to_def_id()] <- macro_def.macro_rules); + record_some_lazy!(self.tables.macro_definition[def_id.to_def_id()] <- &*macro_def.body); } fn encode_native_libraries(&mut self) -> LazyArray { @@ -2039,24 +2046,20 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let tcx = self.tcx; let proc_macro_decls_static = tcx.proc_macro_decls_static(()).unwrap().local_def_index; let stability = tcx.lookup_stability(CRATE_DEF_ID); - for (i, span) in self.tcx.sess.proc_macro_quoted_spans() { - let span = self.lazy(span); - self.tables.proc_macro_quoted_spans.set_some(i, span); - } - self.tables.def_kind.set_some(LOCAL_CRATE.as_def_id().index, DefKind::Mod); - record!(self.tables.def_span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id())); + record_some!(self.tables.def_kind[LOCAL_CRATE.as_def_id()] <- DefKind::Mod); + record_some_lazy!(self.tables.def_span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id())); self.encode_attrs(LOCAL_CRATE.as_def_id().expect_local()); let vis = tcx .local_visibility(CRATE_DEF_ID) .map_id(|mod_id| mod_id.to_local_def_id().local_def_index); - record!(self.tables.visibility[LOCAL_CRATE.as_def_id()] <- vis); + record_some_lazy!(self.tables.visibility[LOCAL_CRATE.as_def_id()] <- vis); if let Some(stability) = stability { - record!(self.tables.lookup_stability[LOCAL_CRATE.as_def_id()] <- stability); + record_some_lazy!(self.tables.lookup_stability[LOCAL_CRATE.as_def_id()] <- stability); } self.encode_deprecation(LOCAL_CRATE.as_def_id()); if let Some(res_map) = tcx.resolutions(()).doc_link_resolutions.get(&CRATE_MOD_ID) { - record!(self.tables.doc_link_resolutions[LOCAL_CRATE.as_def_id()] <- res_map); + record_some_lazy!(self.tables.doc_link_resolutions[LOCAL_CRATE.as_def_id()] <- res_map); } if let Some(traits) = tcx.resolutions(()).doc_link_traits_in_scope.get(&CRATE_MOD_ID) { record_array!(self.tables.doc_link_traits_in_scope[LOCAL_CRATE.as_def_id()] <- traits); @@ -2103,20 +2106,33 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { def_key.disambiguated_data.data = DefPathData::MacroNs(name); let def_id = id.to_def_id(); - self.tables.def_kind.set_some(def_id.index, DefKind::Macro(macro_kind.into())); + record_some!(self.tables.def_kind[def_id] <- DefKind::Macro(macro_kind.into())); + self.encode_attrs(id); - record!(self.tables.def_keys[def_id] <- def_key); - record!(self.tables.def_ident_span[def_id] <- span); - record!(self.tables.def_span[def_id] <- span); - record!(self.tables.visibility[def_id] <- ty::Visibility::Public); + record_some_lazy!(self.tables.def_keys[def_id] <- def_key); + record_some_lazy!(self.tables.def_ident_span[def_id] <- span); + record_some_lazy!(self.tables.def_span[def_id] <- span); + record_some_lazy!(self.tables.visibility[def_id] <- ty::Visibility::Public); if let Some(stability) = stability { - record!(self.tables.lookup_stability[def_id] <- stability); + record_some_lazy!(self.tables.lookup_stability[def_id] <- stability); } } let macros = self.lazy_array(macros); - Some(ProcMacroData { proc_macro_decls_static, stability, macros }) + let mut proc_macro_quoted_spans = TableBuilder::default(); + for (i, span) in self.tcx.sess.proc_macro_quoted_spans() { + proc_macro_quoted_spans.set_some(i, self.lazy(span)); + } + + let proc_macro_quoted_spans = proc_macro_quoted_spans.encode(&mut self.opaque); + + Some(ProcMacroData { + proc_macro_decls_static, + stability, + macros, + proc_macro_quoted_spans, + }) } else { None } @@ -2263,15 +2279,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if of_trait { let header = tcx.impl_trait_header(def_id); - record!(self.tables.impl_trait_header[def_id] <- header); + record_some_lazy!(self.tables.impl_trait_header[def_id] <- header); let impl_is_fully_generic_for_reflection = tcx.impl_is_fully_generic_for_reflection(def_id); - self.tables - .impl_is_fully_generic_for_reflection - .set(def_id.index, impl_is_fully_generic_for_reflection); - self.tables.defaultness.set(def_id.index, tcx.defaultness(def_id)); + record_value!(self.tables.impl_is_fully_generic_for_reflection[def_id] <- impl_is_fully_generic_for_reflection); + record_value!(self.tables.defaultness[def_id] <- tcx.defaultness(def_id)); let trait_ref = header.trait_ref.instantiate_identity().skip_norm_wip(); let simplified_self_ty = fast_reject::simplify_type( @@ -2288,14 +2302,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let Ok(mut an) = trait_def.ancestors(tcx, def_id) && let Some(specialization_graph::Node::Impl(parent)) = an.nth(1) { - self.tables.impl_parent.set_some(def_id.index, parent.into()); + record_some!(self.tables.impl_parent[def_id] <- parent.into()); } // if this is an impl of `CoerceUnsized`, create its // "unsized info", else just store None if tcx.is_lang_item(trait_ref.def_id, LangItem::CoerceUnsized) { let coerce_unsized_info = tcx.coerce_unsized_info(def_id).unwrap(); - record!(self.tables.coerce_unsized_info[def_id] <- coerce_unsized_info); + record_some_lazy!(self.tables.coerce_unsized_info[def_id] <- coerce_unsized_info); } } } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index b70151604f679..f7a437043dade 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -214,6 +214,7 @@ pub(crate) struct ProcMacroData { proc_macro_decls_static: DefIndex, stability: Option, macros: LazyArray<(DefIndex, LazyValue)>, + proc_macro_quoted_spans: LazyTableSingleIdx>>, } #[derive(MetadataEncodable, LazyDecodable)] @@ -503,7 +504,6 @@ define_tables! { // `DefPathTable` up front, since we may only ever use a few // definitions from any given crate. def_keys: Table>, - proc_macro_quoted_spans: Table>, variant_data: Table>, assoc_container: Table>, macro_definition: Table>, diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 5acf9e150bb5c..d964faa30b1f8 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -27,10 +27,8 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::direct_use_of_rustc_type_ir)] -#![cfg_attr(bootstrap, feature(allocator_api))] -#![cfg_attr(bootstrap, feature(never_type))] #![cfg_attr(doc, feature(intra_doc_pointers))] -#![cfg_attr(not(bootstrap), feature(allocator_ext))] +#![feature(allocator_ext)] #![feature(associated_type_defaults)] #![feature(closure_track_caller)] #![feature(const_default)] diff --git a/compiler/rustc_middle/src/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs index 9685ac89011e5..3a008514f7d07 100644 --- a/compiler/rustc_middle/src/middle/privacy.rs +++ b/compiler/rustc_middle/src/middle/privacy.rs @@ -5,7 +5,7 @@ use std::cmp::Ordering; use std::hash::Hash; -use rustc_data_structures::fx::{FxIndexMap, IndexEntry}; +use rustc_data_structures::fx::{FxIndexMap, IndexEntry, default}; use rustc_data_structures::stable_hash::{StableHash, StableHashCtxt, StableHasher}; use rustc_hir::def::DefKind; use rustc_hir::{ItemKind, Node, UseKind, UseTree}; @@ -277,9 +277,9 @@ impl EffectiveVisibilities { } } -impl Default for EffectiveVisibilities { +const impl Default for EffectiveVisibilities { fn default() -> Self { - EffectiveVisibilities { map: Default::default() } + EffectiveVisibilities { map: default::fx_index_map() } } } diff --git a/compiler/rustc_middle/src/query/arena_cached.rs b/compiler/rustc_middle/src/query/arena_cached.rs index 4ab2fbe914965..8faf6f68f49c9 100644 --- a/compiler/rustc_middle/src/query/arena_cached.rs +++ b/compiler/rustc_middle/src/query/arena_cached.rs @@ -5,13 +5,15 @@ use rustc_span::ErrorGuaranteed; use crate::ty::TyCtxt; -/// Helper trait that allows `arena_cache` queries to return `Option<&T>` -/// instead of `&Option`, and avoid allocating `None` in the arena. +/// Helper trait that allows `arena_cache` queries to return: +/// - `Option<&T>` instead of `&Option`, and avoid allocating `None` in the arena; or +/// - `Result<&T, ErrorGuaranteed>` instead of `&Result`, and avoid allocating +/// `Err(ErrorGuaranteed)` in the arena. /// -/// An arena-cached query must be declared to return a type that implements -/// this trait, i.e. either `&'tcx T` or `Option<&'tcx T>`. This trait then -/// determines the types returned by the provider and stored in the arena, -/// and provides a function to bridge between the three types. +/// An arena-cached query must be declared to return a type that implements this trait, i.e. +/// `&'tcx T`, `Option<&'tcx T>`, or `Result<&'tcx T, ErrorGuaranteed>`. This trait then determines +/// the types returned by the provider and stored in the arena, and provides a function to bridge +/// between the three types. pub trait ArenaCached<'tcx>: Sized { /// Type that is returned by the query provider. type Provided; diff --git a/compiler/rustc_middle/src/query/modifiers.rs b/compiler/rustc_middle/src/query/modifiers.rs index 4fd91caa94cd7..3e057e96ddb6b 100644 --- a/compiler/rustc_middle/src/query/modifiers.rs +++ b/compiler/rustc_middle/src/query/modifiers.rs @@ -1,4 +1,5 @@ -//! This contains documentation which is linked from query modifiers used in the `rustc_queries!` proc macro. +//! This contains documentation which is linked from query modifiers used in the `rustc_queries!` +//! proc macro. //! //! The dummy items in this module are used to enable hover documentation for //! modifier names in the query list, and to allow find-all-references to list @@ -10,10 +11,12 @@ /// # `arena_cache` query modifier /// /// Query return values must impl `Copy` and be small, but some queries must return values that -/// doesn't meet those criteria. Queries marked with this modifier have their values allocated in -/// an arena and the query returns a reference to the value. There are two cases. +/// don't meet those criteria. Queries marked with this modifier have their values allocated in +/// an arena and the query returns a reference to the value. There are three cases. /// - If the provider function returns `T` then the query will return `&'tcx T`. /// - If the provider function returns `Option` then the query will return `Option<&'tcx T>`. +/// - If the provider function returns `Result` then the query will return +/// `Result<&'tcx T, ErrorGuaranteed>`. /// /// The query plumbing takes care of the arenas and the type manipulations. pub(crate) struct arena_cache; diff --git a/compiler/rustc_middle/src/ty/cast.rs b/compiler/rustc_middle/src/ty/cast.rs index 25fc0775b1a32..fc8a6de5d232e 100644 --- a/compiler/rustc_middle/src/ty/cast.rs +++ b/compiler/rustc_middle/src/ty/cast.rs @@ -1,35 +1,20 @@ -// Helpers for handling cast expressions, used in both -// typeck and codegen. +// Helpers for handling cast expressions. -use rustc_macros::{StableHash, TyDecodable, TyEncodable}; use rustc_span::bug; use crate::mir; use crate::ty::{self, Ty}; -/// Types that are represented as ints. +/// Valid types for the result of a non-coercion cast #[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum IntTy { - U(ty::UintTy), - I, +pub enum CastTy<'tcx> { + /// `iN`, `uN`, and integer inference variables. + Int, + /// C-like (fieldless) enums. CEnum, Bool, Char, -} - -impl IntTy { - pub fn is_signed(self) -> bool { - matches!(self, Self::I) - } -} - -// Valid types for the result of a non-coercion cast -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum CastTy<'tcx> { - /// Various types that are represented as ints and handled mostly - /// in the same way, merged for easier matching. - Int(IntTy), - /// Floating-point types. + /// `fN` and float inference variables. Float, /// Function pointers. FnPtr, @@ -37,40 +22,28 @@ pub enum CastTy<'tcx> { Ptr(ty::TypeAndMut<'tcx>), } -/// Cast Kind. See [RFC 401](https://rust-lang.github.io/rfcs/0401-coercions.html) -/// (or rustc_hir_analysis/check/cast.rs). -#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, StableHash)] -pub enum CastKind { - PtrPtrCast, - PtrAddrCast, - AddrPtrCast, - NumericCast, - EnumCast, - PrimIntCast, - U8CharCast, - ArrayPtrCast, - FnPtrPtrCast, - FnPtrAddrCast, -} - impl<'tcx> CastTy<'tcx> { /// Returns `Some` for integral/pointer casts. /// Casts like unsizing casts will return `None`. pub fn from_ty(t: Ty<'tcx>) -> Option> { match *t.kind() { - ty::Bool => Some(CastTy::Int(IntTy::Bool)), - ty::Char => Some(CastTy::Int(IntTy::Char)), - ty::Int(_) => Some(CastTy::Int(IntTy::I)), - ty::Infer(ty::InferTy::IntVar(_)) => Some(CastTy::Int(IntTy::I)), - ty::Infer(ty::InferTy::FloatVar(_)) => Some(CastTy::Float), - ty::Uint(u) => Some(CastTy::Int(IntTy::U(u))), - ty::Float(_) => Some(CastTy::Float), - ty::Adt(d, _) if d.is_enum() && d.is_payloadfree() => Some(CastTy::Int(IntTy::CEnum)), + ty::Bool => Some(CastTy::Bool), + ty::Char => Some(CastTy::Char), + ty::Int(_) | ty::Uint(_) | ty::Infer(ty::InferTy::IntVar(_)) => Some(CastTy::Int), + ty::Float(_) | ty::Infer(ty::InferTy::FloatVar(_)) => Some(CastTy::Float), + ty::Adt(d, _) if d.is_enum() && d.is_payloadfree() => Some(CastTy::CEnum), ty::RawPtr(ty, mutbl) => Some(CastTy::Ptr(ty::TypeAndMut { ty, mutbl })), ty::FnPtr(..) => Some(CastTy::FnPtr), _ => None, } } + + pub fn is_int_like(self) -> bool { + match self { + CastTy::Int | CastTy::CEnum | CastTy::Bool | CastTy::Char => true, + CastTy::Float | CastTy::FnPtr | CastTy::Ptr(_) => false, + } + } } /// Returns `mir::CastKind` from the given parameters. @@ -78,15 +51,17 @@ pub fn mir_cast_kind<'tcx>(from_ty: Ty<'tcx>, cast_ty: Ty<'tcx>) -> mir::CastKin let from = CastTy::from_ty(from_ty); let cast = CastTy::from_ty(cast_ty); let cast_kind = match (from, cast) { - (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_))) => { + (Some(from), Some(cast)) if from.is_int_like() && cast.is_int_like() => { + mir::CastKind::IntToInt + } + (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int)) => { mir::CastKind::PointerExposeProvenance } - (Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PointerWithExposedProvenance, - (Some(CastTy::Int(_)), Some(CastTy::Int(_))) => mir::CastKind::IntToInt, + (Some(CastTy::Int), Some(CastTy::Ptr(_))) => mir::CastKind::PointerWithExposedProvenance, (Some(CastTy::FnPtr), Some(CastTy::Ptr(_))) => mir::CastKind::FnPtrToPtr, - (Some(CastTy::Float), Some(CastTy::Int(_))) => mir::CastKind::FloatToInt, - (Some(CastTy::Int(_)), Some(CastTy::Float)) => mir::CastKind::IntToFloat, + (Some(CastTy::Float), Some(CastTy::Int)) => mir::CastKind::FloatToInt, + (Some(CastTy::Int), Some(CastTy::Float)) => mir::CastKind::IntToFloat, (Some(CastTy::Float), Some(CastTy::Float)) => mir::CastKind::FloatToFloat, (Some(CastTy::Ptr(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PtrToPtr, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index b6e204dd52a11..be4679320e9c7 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1135,7 +1135,7 @@ impl<'tcx> TyCtxt<'tcx> { | CrateType::Cdylib | CrateType::Sdylib => false, CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true, - }) + }) && !self.sess.opts.actually_rustdoc } pub fn needs_hir_hash(self) -> bool { diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index 078a171491520..1133b87002450 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -5,7 +5,6 @@ //! //! # Example //! ```rust -#![cfg_attr(bootstrap, doc = "#![feature(never_type)]")] //! mod a { //! pub mod b { //! pub struct SecretlyUninhabited { @@ -175,7 +174,6 @@ impl<'tcx> Ty<'tcx> { /// /// # Example /// ``` - #[cfg_attr(bootstrap, doc = "#![feature(never_type)]")] /// # fn main() {} /// enum Void {} /// mod a { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 243ad73e3dfb8..925915c88cdb4 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -2115,28 +2115,9 @@ impl<'tcx> Ty<'tcx> { match self.kind() { ty::Bool => Some(sym::bool), ty::Char => Some(sym::char), - ty::Float(f) => match f { - ty::FloatTy::F16 => Some(sym::f16), - ty::FloatTy::F32 => Some(sym::f32), - ty::FloatTy::F64 => Some(sym::f64), - ty::FloatTy::F128 => Some(sym::f128), - }, - ty::Int(f) => match f { - ty::IntTy::Isize => Some(sym::isize), - ty::IntTy::I8 => Some(sym::i8), - ty::IntTy::I16 => Some(sym::i16), - ty::IntTy::I32 => Some(sym::i32), - ty::IntTy::I64 => Some(sym::i64), - ty::IntTy::I128 => Some(sym::i128), - }, - ty::Uint(f) => match f { - ty::UintTy::Usize => Some(sym::usize), - ty::UintTy::U8 => Some(sym::u8), - ty::UintTy::U16 => Some(sym::u16), - ty::UintTy::U32 => Some(sym::u32), - ty::UintTy::U64 => Some(sym::u64), - ty::UintTy::U128 => Some(sym::u128), - }, + ty::Int(i) => Some(i.name()), + ty::Uint(u) => Some(u.name()), + ty::Float(f) => Some(f.name()), ty::Str => Some(sym::str), _ => None, } diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index 07e42459c7a99..8e320e0982077 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -1,5 +1,4 @@ // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(never_type))] #![feature(associated_type_defaults)] #![feature(deref_patterns)] #![feature(exact_size_is_empty)] diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 9547b5bb93dff..38021f4b76a4d 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -1161,7 +1161,7 @@ fn new_call_temp<'tcx>( * Integrates blocks from the callee function into the calling function. * Updates block indices, references to locals and other control flow * stuff. -*/ + */ struct Integrator<'a, 'tcx> { args: &'a [Local], new_locals: RangeFrom, diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 43ce9634cc203..16df895b0f728 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -1252,7 +1252,6 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> MonoItemPartitio Linkage::WeakODR => "WeakODR", Linkage::Internal => "Internal", Linkage::ExternalWeak => "ExternalWeak", - Linkage::Common => "Common", }; output.push('['); diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index c841845392429..40febd26806a6 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -63,6 +63,8 @@ enum CurrentGoalKind { /// These are currently the only goals whose impl where-clauses are considered to be /// productive steps. CoinductiveTrait, + /// A `ProjectionGoal`. These are temporarily special wrt to cycle handling. + Projection, // FIXME: Consider renaming `PredicateKind::NormalizesTo` to match with this /// Unlike other goals, `NormalizesTo` goals aren't independent goals but just implementation /// details for handling projections of associated terms. When we encounter a `Projection` goal @@ -89,6 +91,7 @@ impl CurrentGoalKind { CurrentGoalKind::Misc } } + ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) => CurrentGoalKind::Projection, ty::PredicateKind::NormalizesTo(_) => { CurrentGoalKind::ProjectionComputeAssocTermCandidate } @@ -428,46 +431,29 @@ where } /// Computes the `PathKind` for the step from the current goal to the - /// nested goal required due to `source`. + /// nested goal. See #136824 for a more detailed reasoning for this why we care about + /// the step from a goal to its nested goals. /// - /// See #136824 for a more detailed reasoning for this behavior. We - /// consider cycles to be coinductive if they 'step into' a where-clause - /// of a coinductive trait. We will likely extend this function in the future - /// and will need to clearly document it in the rustc-dev-guide before - /// stabilization. - pub(super) fn step_kind_for_source(&self, source: GoalSource) -> PathKind { - match source { - // We treat these goals as unknown for now. It is likely that most miscellaneous - // nested goals will be converted to an inductive variant in the future. - // - // Having unknown cycles is always the safer option, as changing that to either - // succeed or hard error is backwards compatible. If we incorrectly treat a cycle - // as inductive even though it should not be, it may be unsound during coherence and - // fixing it may cause inference breakage or introduce ambiguity. - GoalSource::Misc => PathKind::Unknown, - GoalSource::NormalizeGoal(path_kind) => path_kind, - GoalSource::ImplWhereBound => match self.current_goal_kind { - // We currently only consider a cycle coinductive if it steps - // into a where-clause of a coinductive trait. - CurrentGoalKind::CoinductiveTrait => PathKind::Coinductive, - // We probably want to make all traits coinductive in the future, - // so we treat cycles involving where-clauses of not-yet coinductive - // traits as ambiguous for now. - CurrentGoalKind::Misc | CurrentGoalKind::ProjectionComputeAssocTermCandidate => { - PathKind::Unknown - } - }, - // Relating types is always unproductive. If we were to map proof trees to - // corecursive functions as explained in #136824, relating types never - // introduces a constructor which could cause the recursion to be guarded. - // - // FIXME(-Znext-solver=coinductive): For now we treat all inductive cycles as - // `Unknown`. See the comment in `fn initial_provisional_result`. - GoalSource::TypeRelating => PathKind::Unknown, - // These goal sources are likely unproductive and can be changed to - // `PathKind::Inductive`. Keeping them as unknown until we're confident - // about this and have an example where it is necessary. - GoalSource::AliasBoundConstCondition | GoalSource::AliasWellFormed => PathKind::Unknown, + /// For now we're entirely ignoring the reason why the current goal depends on the + /// nested goal and instead only depend on the current goal itself. This closely + /// matches the old solver. This is something we'll likely improve as we go forward + /// afterwards. + // FIXME(-Znext-solver=coinductive): Nothing interesting going on here right now + // and we're ignoring the goal source. We should change this going forward. + pub(super) fn step_kind_to_nested(&self, _source: GoalSource) -> PathKind { + match self.current_goal_kind { + // We currently consider a cycle involving a trait goal for a coinductive + // trait as coinductive as long as it otherwise only includes normalization. + CurrentGoalKind::CoinductiveTrait => PathKind::Coinductive, + // We do need to treat cycles involving only coinductive trait goals + // and normalization as coinductive due to trait-system-refactor-initiative#10. + CurrentGoalKind::ProjectionComputeAssocTermCandidate | CurrentGoalKind::Projection => { + PathKind::Unknown + } + // We probably want to make all traits coinductive in the future, + // so we treat cycles involving where-clauses of not-yet coinductive + // traits as ambiguous for now. + CurrentGoalKind::Misc => PathKind::ForcedAmbiguity, } } @@ -771,7 +757,7 @@ where let (goal, opaque_types) = self.delegate.deeply_resolve_via_unification_table((goal, opaque_types)); let typing_mode = self.typing_mode(); - let step_kind = self.step_kind_for_source(source); + let step_kind = self.step_kind_to_nested(source); let tracing_span = tracing::span!( Level::DEBUG, @@ -1109,11 +1095,8 @@ where source: GoalSource, mut goal: Goal, ) -> Result<(), NoSolutionOrRerunNonErased> { - goal.predicate = self.normalize( - GoalSource::NormalizeGoal(self.step_kind_for_source(source)), - goal.param_env, - ty::Unnormalized::new_wip(goal.predicate), - )?; + goal.predicate = + self.normalize(goal.param_env, ty::Unnormalized::new_wip(goal.predicate))?; self.inspect.add_goal(self.delegate, self.max_input_universe, source, goal); if let Some(GoalEvaluation { goal, certainty, has_changed: _, stalled_on }) = @@ -1339,10 +1322,12 @@ where let goals = self.delegate.relate(param_env, lhs, variance, rhs, self.origin_span)?; for &goal in goals.iter() { let source = match goal.predicate.kind().skip_binder() { - ty::PredicateKind::Subtype { .. } - | ty::PredicateKind::Clause(ty::ClauseKind::Projection(..)) => { - GoalSource::TypeRelating + ty::PredicateKind::Clause(ty::ClauseKind::Projection(..)) => { + GoalSource::Normalization } + // FIXME(-Znext-solver=coinductive): subtyping goals should + // likely be unproductive + ty::PredicateKind::Subtype { .. } => GoalSource::Misc, // FIXME(-Znext-solver=coinductive): should these WF goals also be unproductive? ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => GoalSource::Misc, p => unreachable!("unexpected nested goal in `relate`: {p:?}"), @@ -1519,9 +1504,7 @@ where match self.opaque_accesses.rerun_always(RerunReason::EvaluateConst)? {} } - self.delegate.evaluate_const(param_env, alias_const, |ty| { - self.normalize(GoalSource::Misc, param_env, ty) - }) + self.delegate.evaluate_const(param_env, alias_const, |ty| self.normalize(param_env, ty)) } pub(super) fn evaluate_const_and_instantiate_projection_term( @@ -1803,7 +1786,6 @@ where pub(super) fn normalize>( &mut self, - source: GoalSource, param_env: I::ParamEnv, value: ty::Unnormalized, ) -> Result { @@ -1819,6 +1801,7 @@ where let infer_term = self.next_term_infer_of_alias_kind(alias_term); let pred = ty::ProjectionClause { projection_term: alias_term, term: infer_term }; let goal = Goal::new(self.cx(), param_env, pred); + let source = GoalSource::Normalization; self.inspect.add_goal(self.delegate, self.max_input_universe, source, goal); let GoalEvaluation { goal, certainty, has_changed: _, stalled_on } = self.evaluate_goal(source, goal, None)?; diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 924a705205e1c..099c755d78427 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -118,7 +118,7 @@ where goal: Goal>, ) -> QueryResultOrRerunNonErased { let ty::OutlivesClause(ty, lt) = goal.predicate; - let ty = self.normalize(GoalSource::Misc, goal.param_env, ty::Unnormalized::new_wip(ty))?; + let ty = self.normalize(goal.param_env, ty::Unnormalized::new_wip(ty))?; // The normalized type can still contain non-rigid higher ranked aliases if their // normalization ends up with ambiguity. Or we have non-rigid aliases inside rigid ones. @@ -456,7 +456,7 @@ where ); // We normalize the self type to be able to relate it with // types from candidates. - self.add_goal(GoalSource::TypeRelating, projection_goal)?; + self.add_goal(GoalSource::Normalization, projection_goal)?; self.try_evaluate_added_goals()?; Ok(self.deeply_resolve_ignoring_regions(normalized_term)) } else { diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs index 388b334ccf618..4203ae8c509cc 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs @@ -439,7 +439,7 @@ where let term = match target_item_kind { ty::AliasTermKind::ProjectionTy { .. } => { let t = cx.type_of(target_item_def_id).instantiate(cx, target_args); - let t = ecx.normalize(GoalSource::Misc, goal.param_env, t)?; + let t = ecx.normalize(goal.param_env, t)?; t.into() } ty::AliasTermKind::ProjectionConst { def_id } @@ -447,7 +447,7 @@ where cx.const_of_item(ty::AliasConstKind::Projection { def_id }) => { let c = c.instantiate(cx, target_args); - let c = ecx.normalize(GoalSource::Misc, goal.param_env, c)?; + let c = ecx.normalize(goal.param_env, c)?; c.into() } ty::AliasTermKind::ProjectionConst { .. } => { diff --git a/compiler/rustc_next_trait_solver/src/solve/project_goals/free_alias.rs b/compiler/rustc_next_trait_solver/src/solve/project_goals/free_alias.rs index 4481e1bc144ac..dfcc89b91a4f2 100644 --- a/compiler/rustc_next_trait_solver/src/solve/project_goals/free_alias.rs +++ b/compiler/rustc_next_trait_solver/src/solve/project_goals/free_alias.rs @@ -34,14 +34,14 @@ where let actual = match free_alias.kind { ty::AliasTermKind::FreeTy { def_id } => { let free = cx.type_of(def_id.into()).instantiate(cx, free_alias.args); - let free = self.normalize(GoalSource::Misc, goal.param_env, free)?; + let free = self.normalize(goal.param_env, free)?; free.into() } ty::AliasTermKind::FreeConst { def_id } if let Some(free) = cx.const_of_item(ty::AliasConstKind::Free { def_id }) => { let free = free.instantiate(cx, free_alias.args); - let free = self.normalize(GoalSource::Misc, goal.param_env, free)?; + let free = self.normalize(goal.param_env, free)?; free.into() } diff --git a/compiler/rustc_next_trait_solver/src/solve/project_goals/inherent.rs b/compiler/rustc_next_trait_solver/src/solve/project_goals/inherent.rs index d519d1e538f1a..45ece5a0589fb 100644 --- a/compiler/rustc_next_trait_solver/src/solve/project_goals/inherent.rs +++ b/compiler/rustc_next_trait_solver/src/solve/project_goals/inherent.rs @@ -45,7 +45,7 @@ where let normalized: I::Term = match inherent_kind { ty::AliasTermKind::InherentTy { def_id } => { let inherent = cx.type_of(def_id.into()).instantiate(cx, inherent_args); - let inherent = self.normalize(GoalSource::Misc, goal.param_env, inherent)?; + let inherent = self.normalize(goal.param_env, inherent)?; inherent.into() } ty::AliasTermKind::InherentConstImpl { def_id } @@ -53,7 +53,7 @@ where cx.const_of_item(ty::AliasConstKind::InherentImpl { def_id }) => { let inherent = inherent.instantiate(cx, inherent_args); - let normalized_ct = self.normalize(GoalSource::Misc, goal.param_env, inherent)?; + let normalized_ct = self.normalize(goal.param_env, inherent)?; let normalized = normalized_ct.into(); let term = ty::AliasTerm::new_from_args(cx, inherent_kind, inherent_args); self.push_const_arg_has_type_goal(goal.param_env, term, normalized)?; diff --git a/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs b/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs index 9d6b8875071ba..f6521e579d722 100644 --- a/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs @@ -69,7 +69,7 @@ where let ( NestedNormalizationGoals(nested_goals), GoalEvaluation { goal: _, certainty, stalled_on: _, has_changed: _ }, - ) = self.evaluate_goal_raw(GoalSource::TypeRelating, normalizes_to)?; + ) = self.evaluate_goal_raw(GoalSource::Normalization, normalizes_to)?; trace!(?nested_goals); diff --git a/compiler/rustc_next_trait_solver/src/solve/project_goals/opaque_types.rs b/compiler/rustc_next_trait_solver/src/solve/project_goals/opaque_types.rs index 2f56056449779..048c8bb45361b 100644 --- a/compiler/rustc_next_trait_solver/src/solve/project_goals/opaque_types.rs +++ b/compiler/rustc_next_trait_solver/src/solve/project_goals/opaque_types.rs @@ -99,8 +99,7 @@ where _ => re, }) }); - let actual = - self.normalize(GoalSource::Misc, goal.param_env, actual)?; + let actual = self.normalize(goal.param_env, actual)?; self.eq(goal.param_env, expected, actual)?; } TypingMode::Coherence @@ -145,7 +144,7 @@ where _ => re, }) }); - let actual = self.normalize(GoalSource::Misc, goal.param_env, actual)?; + let actual = self.normalize(goal.param_env, actual)?; self.eq(goal.param_env, expected, actual)?; self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) .map_err(Into::into) @@ -154,7 +153,7 @@ where TypingMode::Reflection | TypingMode::PostAnalysis | TypingMode::Codegen => { // FIXME: Add an assertion that opaque type storage is empty. let actual = cx.type_of(def_id.into()).instantiate(cx, opaque_ty.args); - let actual = self.normalize(GoalSource::Misc, goal.param_env, actual)?; + let actual = self.normalize(goal.param_env, actual)?; self.eq(goal.param_env, expected, actual)?; self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) .map_err(Into::into) diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs index 6deec10071a16..0f636f323e5fd 100644 --- a/compiler/rustc_pattern_analysis/src/constructor.rs +++ b/compiler/rustc_pattern_analysis/src/constructor.rs @@ -114,7 +114,6 @@ //! //! ```rust //! # #![feature(exhaustive_patterns)] -#![cfg_attr(feature = "rustc", cfg_attr(bootstrap, doc = "#![feature(never_type)]"))] //! # let x = None::; //! match x { //! None => {} diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index ab595de3e39e7..1fe0fbdd2b6cd 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -4105,7 +4105,6 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { /// `Result` could look like: /// ```rust /// # #![feature(never_patterns)] - #[cfg_attr(bootstrap, doc = "#![feature(never_type)]")] /// # fn bar(_x: u32) {} /// let foo: Result = Ok(0); /// match foo { @@ -4171,7 +4170,6 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { /// `Result` could look like: /// ```rust /// # #![feature(never_patterns)] - #[cfg_attr(bootstrap, doc = "#![feature(never_type)]")] /// # fn foo() -> Result { Ok(true) } /// let (Ok(x) | Err(&!)) = foo(); /// # let _ = x; diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b92da685bc6a5..196a499d76baf 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -8,7 +8,6 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![cfg_attr(bootstrap, feature(trim_prefix_suffix))] #![feature(arbitrary_self_types)] #![feature(const_default)] #![feature(const_trait_impl)] @@ -1425,11 +1424,11 @@ pub struct Resolver<'ra, 'tcx> { extern_module_map: RwLock>>, /// Maps glob imports to the names of items actually imported. - glob_map: FxIndexMap>, + glob_map: FxIndexMap> = default::fx_index_map(), glob_error: Option = None, visibilities_for_hashing: Vec<(LocalDefId, Visibility)> = Vec::new(), used_imports: FxHashSet = default::fx_hash_set(), - maybe_unused_trait_imports: FxIndexSet, + maybe_unused_trait_imports: FxIndexSet = default::fx_index_set(), /// Privacy errors are delayed until the end in order to deduplicate them. privacy_errors: Vec> = Vec::new(), @@ -1450,7 +1449,7 @@ pub struct Resolver<'ra, 'tcx> { builtin_macros: FxHashMap = default::fx_hash_map(), registered_attr_tools: &'tcx RegisteredTools, registered_lint_tools: &'tcx RegisteredTools, - macro_use_prelude: FxIndexMap>, + macro_use_prelude: FxIndexMap> = default::fx_index_map(), /// Eagerly populated map of all local macro definitions. local_macro_map: FxHashMap> = default::fx_hash_map(), /// Lazily populated cache of macro definitions loaded from external crates. @@ -1460,9 +1459,9 @@ pub struct Resolver<'ra, 'tcx> { non_macro_attr: &'ra Arc, local_macro_def_scopes: FxHashMap> = default::fx_hash_map(), ast_transform_scopes: FxHashMap> = default::fx_hash_map(), - unused_macros: FxIndexMap, + unused_macros: FxIndexMap = default::fx_index_map(), /// A map from the macro to all its potentially unused arms and the `LocalDefId` of the macro itself. - unused_macro_rules: FxIndexMap)>, + unused_macro_rules: FxIndexMap)> = default::fx_index_map(), proc_macro_stubs: FxHashSet = default::fx_hash_set(), /// Traces collected during macro resolution and validated when it's complete. single_segment_macro_resolutions: @@ -1529,25 +1528,25 @@ pub struct Resolver<'ra, 'tcx> { /// Generic args to suggest for required params (e.g. `<'_>`, `<_, _>`), if any. item_required_generic_args_suggestions: FxHashMap = default::fx_hash_map(), delegation_fn_sigs: LocalDefIdMap = Default::default(), - delegation_infos: FxIndexMap, - delegation_inherent_fn_map: FxIndexMap>, + delegation_infos: FxIndexMap = default::fx_index_map(), + delegation_inherent_fn_map: FxIndexMap> = default::fx_index_map(), main_def: Option = None, - trait_impls: FxIndexMap>, + trait_impls: FxIndexMap> = default::fx_index_map(), /// A list of proc macro LocalDefIds, written out in the order in which /// they are declared in the static array generated by proc_macro_harness. proc_macros: Vec = Vec::new(), - paths_matching_assoc_types: UnordSet, - confused_type_with_std_module: FxIndexMap, + paths_matching_assoc_types: UnordSet = Default::default(), + confused_type_with_std_module: FxIndexMap = default::fx_index_map(), /// Names of items that were stripped out via cfg with their corresponding cfg meta item. stripped_cfg_items: Vec> = Vec::new(), - effective_visibilities: EffectiveVisibilities, - macro_reachable_adts: FxIndexMap>, + effective_visibilities: EffectiveVisibilities = Default::default(), + macro_reachable_adts: FxIndexMap> = default::fx_index_map(), - doc_link_resolutions: FxIndexMap, - doc_link_traits_in_scope: FxIndexMap>, + doc_link_resolutions: FxIndexMap = default::fx_index_map(), + doc_link_traits_in_scope: FxIndexMap> = default::fx_index_map(), all_macro_rules: UnordSet = Default::default(), /// Invocation ids of all glob delegations. @@ -1860,9 +1859,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { local_module_map, extern_module_map: Default::default(), - glob_map: Default::default(), - maybe_unused_trait_imports: Default::default(), - arenas, dummy_decl: arenas.new_pub_def_decl(Res::Err, DUMMY_SP, LocalExpnId::ROOT), builtin_type_decls: PrimTy::ALL @@ -1891,31 +1887,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .collect(), registered_attr_tools, registered_lint_tools, - macro_use_prelude: Default::default(), extern_macro_map: Default::default(), dummy_ext_bang: arenas.alloc_macro(SyntaxExtension::dummy_bang(edition)), dummy_ext_derive: arenas.alloc_macro(SyntaxExtension::dummy_derive(edition)), non_macro_attr: arenas.alloc_macro(SyntaxExtension::non_macro_attr(edition)), - unused_macros: Default::default(), - unused_macro_rules: Default::default(), single_segment_macro_resolutions: Default::default(), multi_segment_macro_resolutions: Default::default(), lint_buffer: LintBuffer::default(), owners, current_owner: PerOwnerResolverData::new(DUMMY_NODE_ID, CRATE_DEF_ID), invocation_parents, - trait_impls: Default::default(), - confused_type_with_std_module: Default::default(), - paths_matching_assoc_types: Default::default(), - stripped_cfg_items: Default::default(), - effective_visibilities: Default::default(), - macro_reachable_adts: Default::default(), - doc_link_resolutions: Default::default(), - doc_link_traits_in_scope: Default::default(), current_crate_outer_attr_insert_span, disambiguators: Default::default(), - delegation_infos: Default::default(), - delegation_inherent_fn_map: Default::default(), features: tcx.features(), .. }; diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index ae7c3854d00b4..364ae2a10a1e7 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -3,7 +3,6 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::internal)] -#![cfg_attr(bootstrap, feature(never_type))] #![doc(test(attr(allow(unused_variables), deny(warnings))))] #![feature(core_intrinsics)] #![feature(min_specialization)] diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 3debf3248ff80..a003f20e3512d 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -671,7 +671,6 @@ symbols! { cold_path, collapse_debuginfo, column, - common, compare_bytes, compare_exchange, compare_exchange_weak, @@ -1176,7 +1175,6 @@ symbols! { integer_max, integer_min, integral, - internal, internal_eq_trait_method_impls, internal_features, interrupt, diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index edc23b6c50b45..487de8f54ee62 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -733,17 +733,17 @@ impl<'a, Ty> FnAbi<'a, Ty> { let spec = cx.target_spec(); match &spec.arch { Arch::X86 => { - let (flavor, regparm) = match abi { + let flavor = match abi { ExternAbi::Fastcall { .. } | ExternAbi::Vectorcall { .. } => { - (x86::Flavor::FastcallOrVectorcall, None) + x86::Flavor::FastcallOrVectorcall } ExternAbi::C { .. } | ExternAbi::Cdecl { .. } | ExternAbi::Stdcall { .. } => { - (x86::Flavor::General, cx.x86_abi_opt().regparm) + x86::Flavor::General { regparam: cx.x86_abi_opt().regparm } } - _ => (x86::Flavor::General, None), + _ => x86::Flavor::General { regparam: None }, }; let reg_struct_return = cx.x86_abi_opt().reg_struct_return; - let opts = x86::X86Options { flavor, regparm, reg_struct_return }; + let opts = x86::X86Options { flavor, reg_struct_return }; if spec.is_like_msvc { x86_win32::compute_abi_info(cx, self, opts); } else { diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs index 3476f41e3bc75..efe88bff6504c 100644 --- a/compiler/rustc_target/src/callconv/x86.rs +++ b/compiler/rustc_target/src/callconv/x86.rs @@ -2,7 +2,7 @@ use rustc_abi::{ AddressSpace, Align, BackendRepr, Float, HasDataLayout, Primitive, Reg, RegKind, TyAndLayout, }; -use crate::callconv::{ArgAttribute, FnAbi, PassMode, TyAbiInterface}; +use crate::callconv::{ArgAbi, ArgAttribute, FnAbi, PassMode, TyAbiInterface}; use crate::spec::{HasTargetSpec, RustcAbi}; /// Is this a struct with a single float field? @@ -37,65 +37,135 @@ where } } -#[derive(PartialEq)] +#[derive(Clone, Copy, PartialEq)] pub(crate) enum Flavor { - General, + General { regparam: Option }, FastcallOrVectorcall, } +#[derive(Clone, Copy)] pub(crate) struct X86Options { pub flavor: Flavor, - pub regparm: Option, pub reg_struct_return: bool, } -pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, opts: X86Options) +fn classify_ret<'a, Ty, C>(cx: &C, opts: X86Options, ret: &mut ArgAbi<'a, Ty>) where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout + HasTargetSpec, { - if !fn_abi.ret.is_ignore() { - if fn_abi.ret.layout.is_aggregate() && fn_abi.ret.layout.is_sized() { - // Returning a structure. Most often, this will use - // a hidden first argument. On some platforms, though, - // small structs are returned as integers. - // - // Some links: - // https://www.angelcode.com/dev/callconv/callconv.html - // Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp - let t = cx.target_spec(); - if let Some(Float::F16) = fn_abi.ret.layout.complex_float(cx) { - // `_Complex _Float16` is returned as `<2 x half>`. - let kind = RegKind::Vector { hint_vector_elem: Primitive::Float(Float::F16) }; - fn_abi.ret.cast_to(Reg { kind, size: fn_abi.ret.layout.size }); - } else if t.abi_return_struct_as_int - || opts.reg_struct_return - || fn_abi.ret.layout.is_complex_number(cx) - { - // According to Clang, everyone but MSVC returns single-element - // float aggregates directly in a floating-point register. - if is_single_fp_element(fn_abi.ret.layout, cx) { - match fn_abi.ret.layout.size.bytes() { - 2 => fn_abi.ret.cast_to(Reg::f16()), - 4 => fn_abi.ret.cast_to(Reg::f32()), - 8 => fn_abi.ret.cast_to(Reg::f64()), - _ => fn_abi.ret.make_indirect(), - } - } else { - match fn_abi.ret.layout.size.bytes() { - 1 => fn_abi.ret.cast_to(Reg::i8()), - 2 => fn_abi.ret.cast_to(Reg::i16()), - 4 => fn_abi.ret.cast_to(Reg::i32()), - 8 => fn_abi.ret.cast_to(Reg::i64()), - _ => fn_abi.ret.make_indirect(), - } + if ret.layout.is_aggregate() && ret.layout.is_sized() { + // Returning a structure. Most often, this will use + // a hidden first argument. On some platforms, though, + // small structs are returned as integers. + // + // Some links: + // https://www.angelcode.com/dev/callconv/callconv.html + // Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp + let t = cx.target_spec(); + if let Some(Float::F16) = ret.layout.complex_float(cx) { + // `_Complex _Float16` is returned as `<2 x half>`. + let kind = RegKind::Vector { hint_vector_elem: Primitive::Float(Float::F16) }; + ret.cast_to(Reg { kind, size: ret.layout.size }); + } else if t.abi_return_struct_as_int + || opts.reg_struct_return + || ret.layout.is_complex_number(cx) + { + // According to Clang, everyone but MSVC returns single-element + // float aggregates directly in a floating-point register. + if is_single_fp_element(ret.layout, cx) { + match ret.layout.size.bytes() { + 2 => ret.cast_to(Reg::f16()), + 4 => ret.cast_to(Reg::f32()), + 8 => ret.cast_to(Reg::f64()), + _ => ret.make_indirect(), } } else { - fn_abi.ret.make_indirect(); + match ret.layout.size.bytes() { + 1 => ret.cast_to(Reg::i8()), + 2 => ret.cast_to(Reg::i16()), + 4 => ret.cast_to(Reg::i32()), + 8 => ret.cast_to(Reg::i64()), + _ => ret.make_indirect(), + } } } else { - fn_abi.ret.extend_integer_width_to(32); + ret.make_indirect(); } + } else { + ret.extend_integer_width_to(32); + } +} + +fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout + HasTargetSpec, +{ + let t = cx.target_spec(); + let align_4 = Align::from_bytes(4).unwrap(); + let align_16 = Align::from_bytes(16).unwrap(); + + if arg.layout.is_aggregate() { + // We need to compute the alignment of the `byval` argument. The rules can be found in + // `X86_32ABIInfo::getTypeStackAlignInBytes` in Clang's `TargetInfo.cpp`. Summarized + // here, they are: + // + // 1. If the natural alignment of the type is <= 4, the alignment is 4. + // + // 2. Otherwise, on Linux, the alignment of any vector type is the natural alignment. + // This doesn't matter here because we only pass aggregates via `byval`, not vectors. + // + // 3. Otherwise, on Apple platforms, the alignment of anything that contains a vector + // type is 16. + // + // 4. If none of these conditions are true, the alignment is 4. + + fn contains_vector<'a, Ty, C>(cx: &C, layout: TyAndLayout<'a, Ty>) -> bool + where + Ty: TyAbiInterface<'a, C> + Copy, + { + match layout.backend_repr { + BackendRepr::Scalar(_) | BackendRepr::ScalarPair { .. } => false, + BackendRepr::SimdVector { .. } => true, + BackendRepr::Memory { .. } => { + for i in 0..layout.fields.count() { + if contains_vector(cx, layout.field(cx, i)) { + return true; + } + } + false + } + BackendRepr::SimdScalableVector { .. } => { + panic!("scalable vectors are unsupported") + } + } + } + + let byval_align = if arg.layout.align.abi < align_4 { + // (1.) + align_4 + } else if t.is_like_darwin && contains_vector(cx, arg.layout) { + // (3.) + align_16 + } else { + // (4.) + align_4 + }; + + arg.pass_by_stack_offset(Some(byval_align)); + } else { + arg.extend_integer_width_to(32); + } +} + +pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, opts: X86Options) +where + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout + HasTargetSpec, +{ + if !fn_abi.ret.is_ignore() { + classify_ret(cx, opts, &mut fn_abi.ret); } for arg in fn_abi.args.iter_mut() { @@ -108,61 +178,7 @@ where continue; } - let t = cx.target_spec(); - let align_4 = Align::from_bytes(4).unwrap(); - let align_16 = Align::from_bytes(16).unwrap(); - - if arg.layout.is_aggregate() { - // We need to compute the alignment of the `byval` argument. The rules can be found in - // `X86_32ABIInfo::getTypeStackAlignInBytes` in Clang's `TargetInfo.cpp`. Summarized - // here, they are: - // - // 1. If the natural alignment of the type is <= 4, the alignment is 4. - // - // 2. Otherwise, on Linux, the alignment of any vector type is the natural alignment. - // This doesn't matter here because we only pass aggregates via `byval`, not vectors. - // - // 3. Otherwise, on Apple platforms, the alignment of anything that contains a vector - // type is 16. - // - // 4. If none of these conditions are true, the alignment is 4. - - fn contains_vector<'a, Ty, C>(cx: &C, layout: TyAndLayout<'a, Ty>) -> bool - where - Ty: TyAbiInterface<'a, C> + Copy, - { - match layout.backend_repr { - BackendRepr::Scalar(_) | BackendRepr::ScalarPair { .. } => false, - BackendRepr::SimdVector { .. } => true, - BackendRepr::Memory { .. } => { - for i in 0..layout.fields.count() { - if contains_vector(cx, layout.field(cx, i)) { - return true; - } - } - false - } - BackendRepr::SimdScalableVector { .. } => { - panic!("scalable vectors are unsupported") - } - } - } - - let byval_align = if arg.layout.align.abi < align_4 { - // (1.) - align_4 - } else if t.is_like_darwin && contains_vector(cx, arg.layout) { - // (3.) - align_16 - } else { - // (4.) - align_4 - }; - - arg.pass_by_stack_offset(Some(byval_align)); - } else { - arg.extend_integer_width_to(32); - } + classify_arg(cx, arg); } fill_inregs(cx, fn_abi, opts, false); @@ -176,9 +192,6 @@ pub(crate) fn fill_inregs<'a, Ty, C>( ) where Ty: TyAbiInterface<'a, C> + Copy, { - if opts.flavor != Flavor::FastcallOrVectorcall && opts.regparm.is_none_or(|x| x == 0) { - return; - } // Mark arguments as InReg like clang does it, // so our fastcall/vectorcall is compatible with C/C++ fastcall/vectorcall. @@ -188,8 +201,19 @@ pub(crate) fn fill_inregs<'a, Ty, C>( // IsSoftFloatABI is only set to true on ARM platforms, // which in turn can't be x86? - // 2 for fastcall/vectorcall, regparm limited by 3 otherwise - let mut free_regs = opts.regparm.unwrap_or(2).into(); + // The number of registers available for argument passing. + // + // An `extern "fastcall"` and `extern "vectorcall"` function always have 2 registers available. + // Otherwise the `regparam` count (in the range 0..=3) determines the number of available + // registers. If unspecified, no registers are used for argument passing. + let mut free_regs = match opts.flavor { + Flavor::FastcallOrVectorcall => 2, + Flavor::General { regparam } => u64::from(regparam.unwrap_or(0)), + }; + + if free_regs == 0 { + return; + } // For types generating PassMode::Cast, InRegs will not be set. // Maybe, this is a FIXME diff --git a/compiler/rustc_target/src/callconv/x86_64.rs b/compiler/rustc_target/src/callconv/x86_64.rs index 5ab2834807d67..57e997f45d4c5 100644 --- a/compiler/rustc_target/src/callconv/x86_64.rs +++ b/compiler/rustc_target/src/callconv/x86_64.rs @@ -131,17 +131,16 @@ where } fn reg_component(cls: &[Option], i: &mut usize, size: Size) -> Option { - if *i >= cls.len() { + let Some(Some(class)) = cls.get(*i) else { return None; - } + }; - match cls[*i] { - None => None, - Some(Class::Int) => { + match class { + Class::Int => { *i += 1; Some(if size.bytes() < 8 { Reg { kind: RegKind::Integer, size } } else { Reg::i64() }) } - Some(Class::Sse) => { + Class::Sse => { let vec_len = 1 + cls[*i + 1..].iter().take_while(|&&c| c == Some(Class::SseUp)).count(); *i += vec_len; @@ -154,7 +153,7 @@ fn reg_component(cls: &[Option], i: &mut usize, size: Size) -> Option unreachable!("reg_component: unhandled class {:?}", c), + c => unreachable!("reg_component: unhandled class {:?}", c), } } diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index a5cb7d0c7bb1a..9a3948f0ac440 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -11,7 +11,6 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(never_type))] #![cfg_attr(bootstrap, feature(unwrap_infallible))] #![feature(associated_type_defaults)] #![feature(default_field_values)] diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs index d30421a762ea9..5ccd7ff7ef55b 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs @@ -510,7 +510,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { match (child_mode, nested_goal.source()) { ( ChildMode::Trait(_) | ChildMode::Host(_), - GoalSource::Misc | GoalSource::TypeRelating | GoalSource::NormalizeGoal(_), + GoalSource::Misc | GoalSource::Normalization, ) => { continue; } diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index cb5a76b51df1b..a7b07529f0bd1 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -7,7 +7,6 @@ //! [`Condition`]s for the trait solver to discharge. // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(never_type))] #![cfg_attr(test, feature(test))] #![feature(option_into_flat_iter)] // tidy-alphabetical-end diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index ba37f7f72691a..2b4c17c5fb94c 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -5,7 +5,6 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(never_type))] #![feature(deref_patterns)] #![feature(iterator_try_collect)] #![feature(option_into_flat_iter)] diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index c6d88bb6603de..5d1472d5941f2 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -16,7 +16,6 @@ use tracing::debug; use crate::inherent::*; use crate::lang_items::SolverTraitLangItem; use crate::region_constraint::RegionConstraint; -use crate::search_graph::PathKind; use crate::{ self as ty, Canonical, CanonicalVarValues, CantBeErased, Const, ConstVid, FloatVid, GenericArgKind, InferConst, IntVid, Interner, TermKind, TyVid, TypingMode, Upcast, @@ -411,22 +410,15 @@ impl Goal { /// Why a specific goal has to be proven. /// -/// This is necessary as we treat nested goals different depending on -/// their source. This is used to decide whether a cycle is coinductive. -/// See the documentation of `EvalCtxt::step_kind_for_source` for more details -/// about this. +/// This is used by proof tree visitors, especially for diagnostics purposes. /// -/// It is also used by proof tree visitors, e.g. for diagnostics purposes. +/// FIXME(-Znext-solver=coinductive): This will also matter in the future when +/// deciding whether a step in a cycle is coinductive. We're currently still +/// matching the old solver behavior here for now, so the `GoalSource` is ignored. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "nightly", derive(StableHash))] pub enum GoalSource { Misc, - /// A nested goal required to prove that types are equal/subtypes. - /// This is always an unproductive step. - /// - /// This is also used for all `NormalizesTo` goals as we they are used - /// to relate types in `AliasRelate`. - TypeRelating, /// We're proving a where-bound of an impl. ImplWhereBound, /// Const conditions that need to hold for `[const]` alias bounds to hold. @@ -438,12 +430,8 @@ pub enum GoalSource { /// 2. for rigid projections's trait goal, /// 3. for GAT where clauses. AliasWellFormed, - /// In case normalizing aliases in nested goals cycles, eagerly normalizing these - /// aliases in the context of the parent may incorrectly change the cycle kind. - /// Normalizing aliases in goals therefore tracks the original path kind for this - /// nested goal. See the comment of the `ReplaceAliasWithInfer` visitor for more - /// details. - NormalizeGoal(PathKind), + /// Normalizing happens in the current context and is unproductive by itself. + Normalization, } #[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, Goal)] diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index b32e5e991cc74..a1071d2cde5f0 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -31,3 +31,7 @@ check-cfg = [ 'cfg(no_rc)', 'cfg(no_sync)', ] + +[lints.cargo] +# compiler-builtins is claimed unused? +unused_dependencies = "allow" diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index de65820cf9a75..2174c7df32fcd 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -78,7 +78,7 @@ unsafe extern "Rust" { /// This may change in the future. You must not rely on it for correctness! /// /// [*equivalent*]: Allocator#equivalent-allocators -#[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "allocator_api", since = "1.100.0")] #[derive(Copy, Debug)] #[derive_const(Clone, Default)] // the compiler needs to know when a Box uses the global allocator vs a custom one @@ -566,7 +566,7 @@ impl Global { } } -#[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "allocator_api", since = "1.100.0")] #[rustc_const_unstable(feature = "const_heap", issue = "79597")] const unsafe impl Allocator for Global { #[inline] diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 7504763120532..beb6522e94bb0 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -235,7 +235,7 @@ pub use thin::ThinBox; // compiler or ICEs will happen. pub struct Box< T: ?Sized, - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] A: Allocator = Global, + #[stable(feature = "allocator_api", since = "1.100.0")] A: Allocator = Global, >(Unique, A); /// Monomorphic function for allocating an uninit `Box`. @@ -443,7 +443,7 @@ impl Box { /// let five = Box::new_in(5, System); /// ``` #[cfg(not(no_global_oom_handling))] - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "allocator_api", since = "1.100.0")] #[must_use] #[inline] pub fn new_in(x: T, alloc: A) -> Self { @@ -676,7 +676,7 @@ impl Box { /// let c = Box::write(uninit, 6); /// assert_eq!(*c, 6); /// ``` - #[stable(feature = "box_take", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "box_take", since = "1.100.0")] pub fn take(boxed: Self) -> (T, Box, A>) { // SAFETY: Reading out an initialised value & leaving behind a // box with uninit contents. @@ -704,7 +704,7 @@ impl Box { /// assert_eq!(*new, 14); /// ``` #[cfg(not(no_global_oom_handling))] - #[stable(feature = "smart_pointer_map", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "smart_pointer_map", since = "1.100.0")] pub fn map(this: Self, f: impl FnOnce(T) -> U) -> Box { let (value, allocation) = Box::take(this); let (raw, alloc) = Box::into_non_null_with_allocator(allocation); @@ -1562,7 +1562,7 @@ impl Box { /// /// [memory layout]: self#memory-layout /// [considerations for unsafe code]: self#considerations-for-unsafe-code - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "allocator_api", since = "1.100.0")] #[inline] pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self { // SAFETY: Upheld by caller. @@ -1615,7 +1615,7 @@ impl Box { /// /// [memory layout]: self#memory-layout /// [considerations for unsafe code]: self#considerations-for-unsafe-code - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "allocator_api", since = "1.100.0")] #[inline] pub unsafe fn from_non_null_in(raw: NonNull, alloc: A) -> Self { // SAFETY: guaranteed by the caller. @@ -1665,7 +1665,7 @@ impl Box { /// /// [memory layout]: self#memory-layout #[must_use = "losing the pointer will leak memory"] - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "allocator_api", since = "1.100.0")] #[rustc_const_unstable(feature = "const_heap", issue = "79597")] #[inline] pub const fn into_raw_with_allocator(b: Self) -> (*mut T, A) { @@ -1723,7 +1723,7 @@ impl Box { /// /// [memory layout]: self#memory-layout #[must_use = "losing the pointer will leak memory"] - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "allocator_api", since = "1.100.0")] #[inline] pub fn into_non_null_with_allocator(b: Self) -> (NonNull, A) { let (ptr, alloc) = Box::into_raw_with_allocator(b); @@ -1869,7 +1869,7 @@ impl Box { /// Note: this is an associated function, which means that you have /// to call it as `Box::allocator(&b)` instead of `b.allocator()`. This /// is so that there is no conflict with a method on the inner type. - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "allocator_api", since = "1.100.0")] #[inline] pub fn allocator(b: &Self) -> &A { &b.1 @@ -2490,7 +2490,7 @@ impl Error for Box { } } -#[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "allocator_api", since = "1.100.0")] unsafe impl Allocator for Box { #[inline] fn allocate(&self, layout: Layout) -> Result, AllocError> { diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index 0129b04137a50..334d49706dbb9 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -595,7 +595,7 @@ pub use core::fmt::Alignment; #[stable(feature = "rust1", since = "1.0.0")] pub use core::fmt::Error; -#[stable(feature = "fmt_numbuffer", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "fmt_numbuffer", since = "1.100.0")] pub use core::fmt::NumBuffer; #[stable(feature = "rust1", since = "1.0.0")] pub use core::fmt::{Arguments, write}; diff --git a/library/alloc/src/rcs/arc.rs b/library/alloc/src/rcs/arc.rs index e61ea5193eccb..4f612dc2bb19a 100644 --- a/library/alloc/src/rcs/arc.rs +++ b/library/alloc/src/rcs/arc.rs @@ -1210,7 +1210,7 @@ impl Arc { /// assert_eq!(*new, 14); /// ``` #[cfg(not(no_global_oom_handling))] - #[stable(feature = "smart_pointer_map", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "smart_pointer_map", since = "1.100.0")] pub fn map(this: Self, f: impl FnOnce(&T) -> U) -> Arc { if size_of::() == size_of::() && align_of::() == align_of::() @@ -5148,7 +5148,7 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for UniqueArc { } } -#[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "allocator_api", since = "1.100.0")] unsafe impl Allocator for Arc { #[inline] fn allocate(&self, layout: Layout) -> Result, AllocError> { diff --git a/library/alloc/src/rcs/rc.rs b/library/alloc/src/rcs/rc.rs index 8cca09d1d4a8c..f1469c06d8fd3 100644 --- a/library/alloc/src/rcs/rc.rs +++ b/library/alloc/src/rcs/rc.rs @@ -1056,7 +1056,7 @@ impl Rc { /// assert_eq!(*new, 14); /// ``` #[cfg(not(no_global_oom_handling))] - #[stable(feature = "smart_pointer_map", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "smart_pointer_map", since = "1.100.0")] pub fn map(this: Self, f: impl FnOnce(&T) -> U) -> Rc { if size_of::() == size_of::() && align_of::() == align_of::() @@ -1985,10 +1985,55 @@ impl Rc { unsafe { drop(Rc::from_raw_in(ptr, alloc)) }; } - /// Returns `true` if there are no other `Rc` or [`Weak`] pointers to - /// this allocation. + /// Determine whether this is the unique reference to the underlying data. + /// + /// Returns `true` if there are no other `Rc` or [`Weak`] pointers to the same allocation; + /// returns `false` otherwise. + /// + /// If this function returns `true`, it is safe to call [`get_mut_unchecked`] + /// immediately afterward. + /// + /// # Examples + /// + /// ``` + /// #![feature(arc_is_unique)] + /// + /// use std::rc::Rc; + /// + /// let x = Rc::new(3); + /// assert!(Rc::is_unique(&x)); + /// + /// let y = Rc::clone(&x); + /// assert!(!Rc::is_unique(&x)); + /// drop(y); + /// + /// // Weak references also count, because they could be upgraded at any time. + /// let z = Rc::downgrade(&x); + /// assert!(!Rc::is_unique(&x)); + /// ``` + /// + /// # Pointer invalidation + /// + /// This function will always return the same value as `Rc::get_mut(rc).is_some()`. However, + /// unlike that operation it does not produce any mutable references to the underlying data, + /// meaning no pointers to the data inside the `Rc` are invalidated by the call. Thus, the + /// following code is valid, even though it would be UB if it used `Rc::get_mut`: + /// + /// ``` + /// #![feature(arc_is_unique)] + /// + /// use std::rc::Rc; + /// + /// let rc = Rc::new(5); + /// let pointer: *const i32 = &*rc; + /// assert!(Rc::is_unique(&rc)); + /// assert_eq!(unsafe { *pointer }, 5); + /// ``` + /// + /// [`get_mut_unchecked`]: Self::get_mut_unchecked #[inline] - fn is_unique(this: &Self) -> bool { + #[unstable(feature = "arc_is_unique", issue = "138938")] + pub fn is_unique(this: &Self) -> bool { Rc::weak_count(this) == 0 && Rc::strong_count(this) == 1 } @@ -4741,7 +4786,7 @@ impl Drop for UniqueRcUninit { } } -#[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "allocator_api", since = "1.100.0")] unsafe impl Allocator for Rc { #[inline] fn allocate(&self, layout: Layout) -> Result, AllocError> { diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index f837d963a572e..8bcad62226a0b 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -436,10 +436,7 @@ mod sve_retain; #[rustc_insignificant_dtor] #[doc(alias = "list")] #[doc(alias = "vector")] -pub struct Vec< - T, - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] A: Allocator = Global, -> { +pub struct Vec { buf: RawVec, len: usize, } @@ -791,7 +788,7 @@ impl Vec { /// ``` #[cfg(not(no_global_oom_handling))] #[inline] - #[stable(feature = "vec_from_fn", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "vec_from_fn", since = "1.100.0")] pub fn from_fn(length: usize, f: F) -> Self where F: FnMut(usize) -> T, @@ -969,7 +966,7 @@ const impl Vec { /// assert_eq!(vec_units.capacity(), usize::MAX); /// ``` #[inline] - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "allocator_api", since = "1.100.0")] pub fn with_capacity_in(capacity: usize, alloc: A) -> Self { Vec { buf: RawVec::with_capacity_in(capacity, alloc), len: 0 } } @@ -1061,7 +1058,7 @@ impl Vec { /// let vec: Vec = Vec::new_in(System); /// ``` #[inline] - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "allocator_api", since = "1.100.0")] #[rustc_const_unstable(feature = "allocator_ext", issue = "163177")] pub const fn new_in(alloc: A) -> Self { Vec { buf: RawVec::new_in(alloc), len: 0 } @@ -1181,7 +1178,7 @@ impl Vec { /// } /// ``` #[inline] - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "allocator_api", since = "1.100.0")] #[rustc_const_unstable(feature = "const_heap", issue = "79597")] pub const unsafe fn from_raw_parts_in( ptr: *mut T, @@ -1293,7 +1290,7 @@ impl Vec { /// } /// ``` #[inline] - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "allocator_api", since = "1.100.0")] #[rustc_const_unstable(feature = "const_heap", issue = "79597")] pub const unsafe fn from_parts_in( ptr: NonNull, @@ -1346,7 +1343,7 @@ impl Vec { /// assert_eq!(rebuilt, [4294967295, 0, 1]); /// ``` #[must_use = "losing the pointer will leak memory"] - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "allocator_api", since = "1.100.0")] #[rustc_const_unstable(feature = "const_heap", issue = "79597")] pub const fn into_raw_parts_with_allocator(self) -> (*mut T, usize, usize, A) { let mut me = ManuallyDrop::new(self); @@ -1395,7 +1392,7 @@ impl Vec { /// assert_eq!(rebuilt, [4294967295, 0, 1]); /// ``` #[must_use = "losing the pointer will leak memory"] - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "allocator_api", since = "1.100.0")] #[rustc_const_unstable(feature = "const_heap", issue = "79597")] pub const fn into_parts_with_allocator(self) -> (NonNull, usize, usize, A) { let (ptr, len, capacity, alloc) = self.into_raw_parts_with_allocator(); @@ -2114,7 +2111,7 @@ impl Vec { } /// Returns a reference to the underlying allocator. - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "allocator_api", since = "1.100.0")] #[rustc_const_unstable(feature = "const_heap", issue = "79597")] #[inline] pub const fn allocator(&self) -> &A { diff --git a/library/alloc/src/vec/partial_eq.rs b/library/alloc/src/vec/partial_eq.rs index 2d5a839cc8c30..aad307c0a0a10 100644 --- a/library/alloc/src/vec/partial_eq.rs +++ b/library/alloc/src/vec/partial_eq.rs @@ -33,11 +33,11 @@ __impl_slice_eq1! { [] Cow<'_, [T]>, &[U] where T: Clone, #[stable(feature = "ru #[cfg(not(no_global_oom_handling))] __impl_slice_eq1! { [] Cow<'_, [T]>, &mut [U] where T: Clone, #[stable(feature = "rust1", since = "1.0.0")] } #[cfg(not(no_global_oom_handling))] -__impl_slice_eq1! { [A: Allocator] Vec, Cow<'_, [U]> where U: Clone, #[stable(feature = "partialeq_cow_for_vec_and_slice", since = "CURRENT_RUSTC_VERSION")] } +__impl_slice_eq1! { [A: Allocator] Vec, Cow<'_, [U]> where U: Clone, #[stable(feature = "partialeq_cow_for_vec_and_slice", since = "1.100.0")] } #[cfg(not(no_global_oom_handling))] -__impl_slice_eq1! { [] &[T], Cow<'_, [U]> where U: Clone, #[stable(feature = "partialeq_cow_for_vec_and_slice", since = "CURRENT_RUSTC_VERSION")] } +__impl_slice_eq1! { [] &[T], Cow<'_, [U]> where U: Clone, #[stable(feature = "partialeq_cow_for_vec_and_slice", since = "1.100.0")] } #[cfg(not(no_global_oom_handling))] -__impl_slice_eq1! { [] &mut [T], Cow<'_, [U]> where U: Clone, #[stable(feature = "partialeq_cow_for_vec_and_slice", since = "CURRENT_RUSTC_VERSION")] } +__impl_slice_eq1! { [] &mut [T], Cow<'_, [U]> where U: Clone, #[stable(feature = "partialeq_cow_for_vec_and_slice", since = "1.100.0")] } __impl_slice_eq1! { const, [A: Allocator, const N: usize] Vec, [U; N], #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] #[stable(feature = "rust1", since = "1.0.0")] } __impl_slice_eq1! { const, [A: Allocator, const N: usize] Vec, &[U; N], #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] #[stable(feature = "rust1", since = "1.0.0")] } diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs index 11b9da3032ae7..a69c86d68a117 100644 --- a/library/core/src/alloc/mod.rs +++ b/library/core/src/alloc/mod.rs @@ -27,15 +27,15 @@ use crate::ptr::{self, NonNull}; /// that may be due to resource exhaustion or to /// something wrong when combining the given input arguments with this /// allocator. -#[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "allocator_api", since = "1.100.0")] #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct AllocError; -#[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "allocator_api", since = "1.100.0")] impl Error for AllocError {} // (we need this for downstream impl of trait Error) -#[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "allocator_api", since = "1.100.0")] impl fmt::Display for AllocError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("memory allocation failed") @@ -193,7 +193,7 @@ impl fmt::Display for AllocError { // and make sure they cannot be triggered before relaxing this: // https://rust.tf/156490 // https://rust.tf/159982 -#[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "allocator_api", since = "1.100.0")] #[rustc_const_unstable(feature = "const_heap", issue = "79597")] pub const unsafe trait Allocator { /// Attempts to allocate a block of memory. @@ -228,7 +228,7 @@ pub const unsafe trait Allocator { /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar. /// /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "allocator_api", since = "1.100.0")] fn allocate(&self, layout: Layout) -> Result, AllocError>; /// Behaves like `allocate`, but also ensures that the returned memory is zero-initialized. @@ -246,7 +246,7 @@ pub const unsafe trait Allocator { /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar. /// /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "allocator_api", since = "1.100.0")] fn allocate_zeroed(&self, layout: Layout) -> Result, AllocError> { let ptr = self.allocate(layout)?; // SAFETY: `alloc` returns a valid memory block @@ -270,7 +270,7 @@ pub const unsafe trait Allocator { /// /// [*currently allocated*]: #currently-allocated-memory /// [*fit*]: #memory-fitting - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "allocator_api", since = "1.100.0")] unsafe fn deallocate(&self, ptr: NonNull, layout: Layout); /// Attempts to extend the memory block. @@ -312,7 +312,7 @@ pub const unsafe trait Allocator { /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar. /// /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "allocator_api", since = "1.100.0")] unsafe fn grow( &self, ptr: NonNull, @@ -373,7 +373,7 @@ pub const unsafe trait Allocator { /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar. /// /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "allocator_api", since = "1.100.0")] unsafe fn grow_zeroed( &self, ptr: NonNull, @@ -440,7 +440,7 @@ pub const unsafe trait Allocator { /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar. /// /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html - #[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "allocator_api", since = "1.100.0")] unsafe fn shrink( &self, ptr: NonNull, @@ -574,7 +574,7 @@ pub unsafe trait AllocatorClone: Allocator + Clone {} #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] pub unsafe trait StaticAllocator: Allocator {} -#[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "allocator_api", since = "1.100.0")] #[rustc_const_unstable(feature = "const_heap", issue = "79597")] const unsafe impl Allocator for &A where @@ -630,7 +630,7 @@ where } } -#[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "allocator_api", since = "1.100.0")] #[rustc_const_unstable(feature = "const_heap", issue = "79597")] const unsafe impl Allocator for &mut A where diff --git a/library/core/src/attribute_docs.rs b/library/core/src/attribute_docs.rs index 97629be8ec6ef..9a70ea74345be 100644 --- a/library/core/src/attribute_docs.rs +++ b/library/core/src/attribute_docs.rs @@ -189,7 +189,7 @@ const _: () = (); /// /// For more information, see the Reference on [the `cfg` attribute]. /// -/// [`cfg_attr`]: ../reference/conditional-compilation.html#the-cfg_attr-attribute +/// [`cfg_attr`]: ./attribute.cfg_attr.html /// [the `cfg` attribute]: ../reference/conditional-compilation.html#the-cfg-attribute /// [`if`]: ./keyword.if.html const _: () = (); @@ -707,3 +707,48 @@ const _: () = (); /// [Clippy]: https://github.com/rust-lang/rust-clippy /// [the `automatically_derived` attribute]: ../reference/attributes/derive.html#the-automatically_derived-attribute const _: () = (); + +#[doc(attribute = "cfg_attr")] +// +/// The `cfg_attr` attribute is used to conditionally apply one or more attributes to an item. +/// +/// Example: +/// +/// ```rust +/// // The struct derives `Debug` when the `debug_impls` feature is enabled. +/// #[cfg_attr(feature = "debug_impls", derive(Debug))] +/// struct X; +/// ``` +/// +/// You can apply multiple attributes by separating them with commas: +/// +/// ```rust +/// #[cfg_attr(feature = "nightly", allow(dead_code), deny(unused_variables))] +/// // This function only gets the `allow(dead_code)` and `deny(unused_variables)` attributes when +/// // `feature = "nightly"` is active. +/// fn nightly_only_function() { +/// let x = 42; +/// } +/// ``` +/// +/// For complex conditions, you can combine `all(...)`, `any(...)`, and `not(...)`. +/// +/// * `all`: True if all given predicates are true. +/// * `any`: True if at least one of the given predicates is true. +/// * `not`: True if the predicate is false. +/// +/// ```rust +/// #[cfg_attr( +/// all(feature = "system", feature = "disk"), +/// doc = "These docs only show up if both `system`, and `disk` are enabled.", +/// )] +/// mod my_module { +/// // ... +/// } +/// ``` +/// +/// For more information, see the Reference on [the `cfg_attr` attribute]. +/// +/// [`cfg`]: ./attribute.cfg.html +/// [the `cfg_attr` attribute]: ../reference/conditional-compilation.html#the-cfg_attr-attribute +const _: () = (); diff --git a/library/core/src/bool.rs b/library/core/src/bool.rs index b3d7686b6336e..e4ca53b59323f 100644 --- a/library/core/src/bool.rs +++ b/library/core/src/bool.rs @@ -151,8 +151,8 @@ impl bool { /// /// [`true`]: ../std/keyword.true.html /// [`false`]: ../std/keyword.false.html - #[stable(feature = "bool_toggle", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "bool_toggle", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "bool_toggle", since = "1.100.0")] + #[rustc_const_stable(feature = "bool_toggle", since = "1.100.0")] #[inline] pub const fn toggle(&mut self) { *self = !*self; diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 47312b2bd5649..3dcf033bbd757 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -2376,8 +2376,8 @@ impl UnsafeCell { /// assert_eq!(old, 5); /// ``` #[inline] - #[stable(feature = "unsafe_cell_access", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unsafe_cell_access", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "unsafe_cell_access", since = "1.100.0")] + #[rustc_const_stable(feature = "unsafe_cell_access", since = "1.100.0")] #[rustc_should_not_be_called_on_const_items] pub const unsafe fn replace(&self, value: T) -> T { // SAFETY: pointer comes from `&self` so naturally satisfies invariants. @@ -2518,8 +2518,8 @@ impl UnsafeCell { /// assert_eq!(val, &5); /// ``` #[inline] - #[stable(feature = "unsafe_cell_access", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unsafe_cell_access", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "unsafe_cell_access", since = "1.100.0")] + #[rustc_const_stable(feature = "unsafe_cell_access", since = "1.100.0")] #[rustc_should_not_be_called_on_const_items] pub const unsafe fn as_ref_unchecked(&self) -> &T { // SAFETY: pointer comes from `&self` so naturally satisfies ptr-to-ref invariants. @@ -2546,8 +2546,8 @@ impl UnsafeCell { /// assert_eq!(uc.into_inner(), 6); /// ``` #[inline] - #[stable(feature = "unsafe_cell_access", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unsafe_cell_access", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "unsafe_cell_access", since = "1.100.0")] + #[rustc_const_stable(feature = "unsafe_cell_access", since = "1.100.0")] #[allow(clippy::mut_from_ref)] #[rustc_should_not_be_called_on_const_items] pub const unsafe fn as_mut_unchecked(&self) -> &mut T { diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index 126ab37bc0b71..bd6d929c6d2b0 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -732,7 +732,7 @@ mod impls { bool char } - #[stable(feature = "never_type", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "never_type", since = "1.100.0")] #[rustc_const_unstable(feature = "const_clone", issue = "142757")] const impl Clone for ! { #[inline] diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 2792c7cde57be..1b57bed2738f7 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -2409,7 +2409,7 @@ mod impls { ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } - #[stable(feature = "never_type", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "never_type", since = "1.100.0")] #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] const impl PartialEq for ! { #[inline] @@ -2418,11 +2418,11 @@ mod impls { } } - #[stable(feature = "never_type", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "never_type", since = "1.100.0")] #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] const impl Eq for ! {} - #[stable(feature = "never_type", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "never_type", since = "1.100.0")] #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] const impl PartialOrd for ! { #[inline] @@ -2431,7 +2431,7 @@ mod impls { } } - #[stable(feature = "never_type", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "never_type", since = "1.100.0")] #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] const impl Ord for ! { #[inline] diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 214c12686c204..b0f74a8afb598 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -886,7 +886,7 @@ const impl AsMut for str { /// } /// ``` /// -/// Note: Since [`!`] (the "never" type) was stabilized in Rust CURRENT_RUSTC_VERSION, it is +/// Note: Since [`!`] (the "never" type) was stabilized in Rust 1.100.0, it is /// preferred to use `!` directly unless targeting older Rust versions. `Infallible` may be /// deprecated in a future Rust version. #[stable(feature = "convert_infallible", since = "1.34.0")] diff --git a/library/core/src/error.rs b/library/core/src/error.rs index 7386c52849eab..1b640f2d99803 100644 --- a/library/core/src/error.rs +++ b/library/core/src/error.rs @@ -268,7 +268,7 @@ mod private { pub struct Internal; } -#[stable(feature = "never_type", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "never_type", since = "1.100.0")] impl Error for ! {} // Copied from `any.rs`. diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 43dba18375992..55296a62e947a 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -2881,7 +2881,7 @@ macro_rules! fmt_refs { fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp } -#[stable(feature = "never_type", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "never_type", since = "1.100.0")] impl Debug for ! { #[inline] fn fmt(&self, _: &mut Formatter<'_>) -> Result { @@ -2889,7 +2889,7 @@ impl Debug for ! { } } -#[stable(feature = "never_type", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "never_type", since = "1.100.0")] impl Display for ! { #[inline] fn fmt(&self, _: &mut Formatter<'_>) -> Result { diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index d1a68412247ef..530af0c3af656 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -480,7 +480,7 @@ marker_impls! { } -#[stable(feature = "never_type", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "never_type", since = "1.100.0")] impl Copy for ! {} /// Shared references can be copied, but mutable references *cannot*! diff --git a/library/core/src/mem/drop_guard.rs b/library/core/src/mem/drop_guard.rs index 31f1f93b65378..81104ccce29f1 100644 --- a/library/core/src/mem/drop_guard.rs +++ b/library/core/src/mem/drop_guard.rs @@ -27,7 +27,7 @@ use crate::ops::{Deref, DerefMut}; /// // "Chashu likes tuna!!!" /// } /// ``` -#[stable(feature = "drop_guard", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "drop_guard", since = "1.100.0")] #[doc(alias = "ScopeGuard")] #[doc(alias = "defer")] pub struct DropGuard @@ -54,7 +54,7 @@ where /// let value = String::from("Chashu likes tuna"); /// let guard = DropGuard::new(value, |s| println!("{s}")); /// ``` - #[stable(feature = "drop_guard", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "drop_guard", since = "1.100.0")] #[rustc_const_unstable(feature = "const_drop_guard", issue = "none")] #[must_use] pub const fn new(inner: T, f: F) -> Self { @@ -79,7 +79,7 @@ where /// let guard = DropGuard::new(value, |s| println!("{s}")); /// assert_eq!(DropGuard::dismiss(guard), "Nori likes chicken"); /// ``` - #[stable(feature = "drop_guard", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "drop_guard", since = "1.100.0")] #[rustc_const_unstable(feature = "const_drop_guard", issue = "none")] #[inline] pub const fn dismiss(guard: Self) -> T @@ -105,7 +105,7 @@ where } } -#[stable(feature = "drop_guard", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "drop_guard", since = "1.100.0")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] const impl Deref for DropGuard where @@ -118,7 +118,7 @@ where } } -#[stable(feature = "drop_guard", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "drop_guard", since = "1.100.0")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] const impl DerefMut for DropGuard where @@ -129,7 +129,7 @@ where } } -#[stable(feature = "drop_guard", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "drop_guard", since = "1.100.0")] #[rustc_const_unstable(feature = "const_drop_guard", issue = "none")] const impl Drop for DropGuard where @@ -146,7 +146,7 @@ where } } -#[stable(feature = "drop_guard", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "drop_guard", since = "1.100.0")] impl Debug for DropGuard where T: Debug, diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index e149e2b4a7039..a22e52f3a3bc7 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -59,7 +59,7 @@ mod transmutability; pub use transmutability::{Assume, TransmuteFrom}; mod drop_guard; -#[stable(feature = "drop_guard", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "drop_guard", since = "1.100.0")] pub use drop_guard::DropGuard; // This one has to be a re-export (rather than wrapping the underlying intrinsic) so that we can do @@ -1708,8 +1708,8 @@ pub macro offset_of($Container:ty, $($fields:expr)+ $(,)?) { /// ``` /// /// [inhabited]: https://doc.rust-lang.org/reference/glossary.html#inhabited -#[stable(feature = "mem_conjure_zst", since = "CURRENT_RUSTC_VERSION")] -#[rustc_const_stable(feature = "mem_conjure_zst", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "mem_conjure_zst", since = "1.100.0")] +#[rustc_const_stable(feature = "mem_conjure_zst", since = "1.100.0")] #[rustc_allow_const_fn_unstable(const_type_name)] // type_name() called only at run time pub const unsafe fn conjure_zst() -> T { const_assert!( diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index d102c456f3b4a..6a8a2d5b636ed 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -34,7 +34,7 @@ impl fmt::Display for TryFromIntError { #[stable(feature = "try_from", since = "1.34.0")] impl Error for TryFromIntError {} -#[stable(feature = "never_type", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "never_type", since = "1.100.0")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] const impl From for TryFromIntError { #[inline] diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index db05d7fdc5087..e53e4df1ea43d 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1544,9 +1544,10 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "clamp_magnitude", issue = "148519")] - #[must_use = "this returns the clamped value and does not modify the original"] + #[rustc_const_unstable(feature = "clamp_magnitude", issue = "148519")] + #[must_use = "method returns a new number and does not mutate the original value"] #[expect(clippy::neg_cmp_op_on_partial_ord, reason = "NaN is also invalid")] - pub fn clamp_magnitude(self, limit: f128) -> f128 { + pub const fn clamp_magnitude(self, limit: f128) -> f128 { assert!(limit >= 0.0, "limit must be non-negative and not NaN"); let limit = limit.abs(); // Canonicalises -0.0 to 0.0 self.clamp(-limit, limit) diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 273ef3688ca5f..4ad41bd6cfa4b 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1530,9 +1530,10 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "clamp_magnitude", issue = "148519")] - #[must_use = "this returns the clamped value and does not modify the original"] + #[rustc_const_unstable(feature = "clamp_magnitude", issue = "148519")] + #[must_use = "method returns a new number and does not mutate the original value"] #[expect(clippy::neg_cmp_op_on_partial_ord, reason = "NaN is also invalid")] - pub fn clamp_magnitude(self, limit: f16) -> f16 { + pub const fn clamp_magnitude(self, limit: f16) -> f16 { assert!(limit >= 0.0, "limit must be non-negative and not NaN"); let limit = limit.abs(); // Canonicalises -0.0 to 0.0 self.clamp(-limit, limit) diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index d3dea38dc2fcf..2dc3ddf31cac5 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1699,11 +1699,11 @@ impl f32 { /// assert_eq!(2.0f32.clamp_magnitude(3.0), 2.0); /// assert_eq!((-2.0f32).clamp_magnitude(3.0), -2.0); /// ``` - #[must_use = "this returns the clamped value and does not modify the original"] - #[unstable(feature = "clamp_magnitude", issue = "148519")] #[inline] + #[unstable(feature = "clamp_magnitude", issue = "148519")] + #[must_use = "method returns a new number and does not mutate the original value"] #[expect(clippy::neg_cmp_op_on_partial_ord, reason = "NaN is also invalid")] - pub fn clamp_magnitude(self, limit: f32) -> f32 { + pub const fn clamp_magnitude(self, limit: f32) -> f32 { assert!(limit >= 0.0, "limit must be non-negative and not NaN"); let limit = limit.abs(); // Canonicalises -0.0 to 0.0 self.clamp(-limit, limit) diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 7c5082749cd11..cd3cfe1bd4c60 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1677,11 +1677,11 @@ impl f64 { /// assert_eq!(2.0f64.clamp_magnitude(3.0), 2.0); /// assert_eq!((-2.0f64).clamp_magnitude(3.0), -2.0); /// ``` - #[must_use = "this returns the clamped value and does not modify the original"] - #[unstable(feature = "clamp_magnitude", issue = "148519")] #[inline] + #[unstable(feature = "clamp_magnitude", issue = "148519")] + #[must_use = "method returns a new number and does not mutate the original value"] #[expect(clippy::neg_cmp_op_on_partial_ord, reason = "NaN is also invalid")] - pub fn clamp_magnitude(self, limit: f64) -> f64 { + pub const fn clamp_magnitude(self, limit: f64) -> f64 { assert!(limit >= 0.0, "limit must be non-negative and not NaN"); let limit = limit.abs(); // Canonicalises -0.0 to 0.0 self.clamp(-limit, limit) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 4cbd012e0021b..058c0229aa530 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -3961,14 +3961,15 @@ macro_rules! int_impl { /// ``` /// #![feature(clamp_magnitude)] #[doc = concat!("assert_eq!(120", stringify!($SelfT), ".clamp_magnitude(100), 100);")] - #[doc = concat!("assert_eq!(-120", stringify!($SelfT), ".clamp_magnitude(100), -100);")] + #[doc = concat!("assert_eq!((-120", stringify!($SelfT), ").clamp_magnitude(100), -100);")] #[doc = concat!("assert_eq!(80", stringify!($SelfT), ".clamp_magnitude(100), 80);")] - #[doc = concat!("assert_eq!(-80", stringify!($SelfT), ".clamp_magnitude(100), -80);")] + #[doc = concat!("assert_eq!((-80", stringify!($SelfT), ").clamp_magnitude(100), -80);")] /// ``` - #[must_use = "this returns the clamped value and does not modify the original"] - #[unstable(feature = "clamp_magnitude", issue = "148519")] #[inline] - pub fn clamp_magnitude(self, limit: $UnsignedT) -> Self { + #[must_use = "method returns a new number and does not mutate the original value"] + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + #[unstable(feature = "clamp_magnitude", issue = "148519")] + pub const fn clamp_magnitude(self, limit: $UnsignedT) -> Self { if let Ok(limit) = core::convert::TryInto::<$SelfT>::try_into(limit) { self.clamp(-limit, limit) } else { diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 355e9a3c59da7..c97e6f4c45395 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -2612,6 +2612,50 @@ macro_rules! nonzero_integer_signedness_dependent_methods { unsafe { NonZero::new_unchecked(self.get().cast_unsigned()) } } + /// Clamps this number to a symmetric range centred around zero. + /// + /// The method clamps the number's magnitude (absolute value) to be at most `limit`. + /// + /// This is functionally equivalent to `self.clamp(-limit, limit)`, but is more + /// explicit about the intent. + /// + /// # Examples + /// + /// ``` + /// #![feature(clamp_magnitude)] + /// # use std::num::NonZero; + /// # + #[doc = concat!("let limit = NonZero::<", stringify!($Uint), ">::new(100).unwrap();")] + /// + /// assert_eq!( + #[doc = concat!(" NonZero::<", stringify!($Int), ">::new(120).unwrap().clamp_magnitude(limit),")] + #[doc = concat!(" NonZero::<", stringify!($Int), ">::new(100).unwrap(),")] + /// ); + /// + /// assert_eq!( + #[doc = concat!(" NonZero::<", stringify!($Int), ">::new(-120).unwrap().clamp_magnitude(limit),")] + #[doc = concat!(" NonZero::<", stringify!($Int), ">::new(-100).unwrap(),")] + /// ); + /// + /// assert_eq!( + #[doc = concat!(" NonZero::<", stringify!($Int), ">::new(80).unwrap().clamp_magnitude(limit),")] + #[doc = concat!(" NonZero::<", stringify!($Int), ">::new(80).unwrap(),")] + /// ); + /// + /// assert_eq!( + #[doc = concat!(" NonZero::<", stringify!($Int), ">::new(-80).unwrap().clamp_magnitude(limit),")] + #[doc = concat!(" NonZero::<", stringify!($Int), ">::new(-80).unwrap(),")] + /// ); + /// ``` + #[inline] + #[must_use = "method returns a new number and does not mutate the original value"] + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] + #[unstable(feature = "clamp_magnitude", issue = "148519")] + pub const fn clamp_magnitude(self, limit: NonZero<$Uint>) -> Self { + // SAFETY: a non-zero value clamped to the magnitude of a non-zero value is still non-zero. + unsafe { Self::new_unchecked(self.get().clamp_magnitude(limit.get())) } + } + }; } diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 4b84a9de4ce72..5054afdc3490d 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -282,7 +282,7 @@ const _: () = (); /// todo!() as std::iter::Empty<_> /// } /// ``` -#[stable(feature = "never_type", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "never_type", since = "1.100.0")] const _: () = (); // Required to make auto trait impls render. diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index d89d212111527..6deba9ce9752e 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -2801,7 +2801,7 @@ impl [T] { /// assert_eq!(b"hello".trim_prefix(prefix.as_bytes()), b"llo".as_ref()); /// ``` #[must_use = "returns the subslice without modifying the original"] - #[stable(feature = "trim_prefix_suffix", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "trim_prefix_suffix", since = "1.100.0")] pub fn trim_prefix + ?Sized>(&self, prefix: &P) -> &[T] where T: PartialEq, @@ -2839,7 +2839,7 @@ impl [T] { /// assert_eq!(v.trim_suffix(&[50, 30]), &[10, 40, 30][..]); /// ``` #[must_use = "returns the subslice without modifying the original"] - #[stable(feature = "trim_prefix_suffix", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "trim_prefix_suffix", since = "1.100.0")] pub fn trim_suffix + ?Sized>(&self, suffix: &P) -> &[T] where T: PartialEq, diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 99eb935cb2715..017d3f50eba32 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -2556,7 +2556,7 @@ impl str { /// ``` #[must_use = "this returns the remaining substring as a new slice, \ without modifying the original"] - #[stable(feature = "trim_prefix_suffix", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "trim_prefix_suffix", since = "1.100.0")] pub fn trim_prefix(&self, prefix: P) -> &str { prefix.strip_prefix_of(self).unwrap_or(self) } @@ -2591,7 +2591,7 @@ impl str { /// ``` #[must_use = "this returns the remaining substring as a new slice, \ without modifying the original"] - #[stable(feature = "trim_prefix_suffix", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "trim_prefix_suffix", since = "1.100.0")] pub fn trim_suffix(&self, suffix: P) -> &str where for<'a> P::Searcher<'a>: ReverseSearcher<'a>, diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 1334b551217a8..fc2430a10edb4 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -15,6 +15,7 @@ #![feature(cfg_overflow_checks)] #![feature(cfg_target_has_reliable_f16_f128)] #![feature(char_internals)] +#![feature(clamp_magnitude)] #![feature(clamp_to)] #![feature(clone_to_uninit)] #![feature(cmp_minmax)] diff --git a/library/coretests/tests/num/clamp_magnitude.rs b/library/coretests/tests/num/clamp_magnitude.rs index 0f96e55f6914e..fdb605780a2c6 100644 --- a/library/coretests/tests/num/clamp_magnitude.rs +++ b/library/coretests/tests/num/clamp_magnitude.rs @@ -1,3 +1,7 @@ +use core::num::*; + +use crate::num::assert_biteq; + macro_rules! check_int_clamp { ($t:ty, $ut:ty) => { let min = <$t>::MIN; @@ -32,6 +36,16 @@ macro_rules! check_int_clamp { // Limit larger than type max (uN > iN::MAX) assert_eq!(max.clamp_magnitude(max_u), max); assert_eq!(min.clamp_magnitude(max_u), min); + + // Const clamping + const C1: $t = (100 as $t).clamp_magnitude(50); + assert_eq!(C1, 50); + const C2: $t = (-100 as $t).clamp_magnitude(50); + assert_eq!(C2, -50); + const C3: $t = (30 as $t).clamp_magnitude(50); + assert_eq!(C3, 30); + const C4: $t = (-30 as $t).clamp_magnitude(50); + assert_eq!(C4, -30); }; } @@ -65,8 +79,81 @@ fn test_clamp_magnitude_isize() { check_int_clamp!(isize, usize); } +macro_rules! check_nonzero_clamp { + ($t:ty, $ut:ty) => { + let min = <$t>::MIN; + let max = <$t>::MAX; + let max_u = <$ut>::MAX; + + // Basic clamping + let lim = <$ut>::new(50).unwrap(); + assert_eq!(<$t>::new(100).unwrap().clamp_magnitude(lim), <$t>::new(50).unwrap()); + assert_eq!(<$t>::new(-100).unwrap().clamp_magnitude(lim), <$t>::new(-50).unwrap()); + assert_eq!(<$t>::new(30).unwrap().clamp_magnitude(lim), <$t>::new(30).unwrap()); + assert_eq!(<$t>::new(-30).unwrap().clamp_magnitude(lim), <$t>::new(-30).unwrap()); + + // Exact boundary + assert_eq!(<$t>::new(50).unwrap().clamp_magnitude(lim), <$t>::new(50).unwrap()); + assert_eq!(<$t>::new(-50).unwrap().clamp_magnitude(lim), <$t>::new(-50).unwrap()); + + // MIN/MAX values + // Symmetric range [-MAX, MAX] + assert_eq!(max.clamp_magnitude(max.try_into().unwrap()), max); + assert_eq!(min.clamp_magnitude(max.try_into().unwrap()), -max); + + // Full range (limit covers MIN) + let min_abs = min.unsigned_abs(); + assert_eq!(min.clamp_magnitude(min_abs), min); + + // Limit larger than type max (uN > iN::MAX) + assert_eq!(max.clamp_magnitude(max_u), max); + assert_eq!(min.clamp_magnitude(max_u), min); + + // Const clamping + const LIM: $ut = <$ut>::new(50).unwrap(); + const C1: $t = <$t>::new(100).unwrap().clamp_magnitude(LIM); + assert_eq!(C1, <$t>::new(50).unwrap()); + const C2: $t = <$t>::new(-100).unwrap().clamp_magnitude(LIM); + assert_eq!(C2, <$t>::new(-50).unwrap()); + const C3: $t = <$t>::new(30).unwrap().clamp_magnitude(LIM); + assert_eq!(C3, <$t>::new(30).unwrap()); + const C4: $t = <$t>::new(-30).unwrap().clamp_magnitude(LIM); + assert_eq!(C4, <$t>::new(-30).unwrap()); + }; +} + +#[test] +fn test_clamp_magnitude_nonzero_i8() { + check_nonzero_clamp!(NonZeroI8, NonZeroU8); +} + +#[test] +fn test_clamp_magnitude_nonzero_i16() { + check_nonzero_clamp!(NonZeroI16, NonZeroU16); +} + +#[test] +fn test_clamp_magnitude_nonzero_i32() { + check_nonzero_clamp!(NonZeroI32, NonZeroU32); +} + +#[test] +fn test_clamp_magnitude_nonzero_i64() { + check_nonzero_clamp!(NonZeroI64, NonZeroU64); +} + +#[test] +fn test_clamp_magnitude_nonzero_i128() { + check_nonzero_clamp!(NonZeroI128, NonZeroU128); +} + +#[test] +fn test_clamp_magnitude_nonzero_isize() { + check_nonzero_clamp!(NonZeroIsize, NonZeroUsize); +} + macro_rules! check_float_clamp { - ($t:ty) => { + ($t:ty, $huge: expr) => { // Basic clamping assert_eq!((5.0 as $t).clamp_magnitude(3.0), 3.0); assert_eq!((-5.0 as $t).clamp_magnitude(3.0), -3.0); @@ -78,10 +165,13 @@ macro_rules! check_float_clamp { assert_eq!((-3.0 as $t).clamp_magnitude(3.0), -3.0); // Zero cases - assert_eq!((0.0 as $t).clamp_magnitude(1.0), 0.0); - assert_eq!((-0.0 as $t).clamp_magnitude(1.0), 0.0); - assert_eq!((5.0 as $t).clamp_magnitude(0.0), 0.0); - assert_eq!((-5.0 as $t).clamp_magnitude(0.0), 0.0); + type Float = $t; + assert_biteq!((0.0 as $t).clamp_magnitude(1.0), 0.0); + assert_biteq!((-0.0 as $t).clamp_magnitude(1.0), -0.0); + assert_biteq!((5.0 as $t).clamp_magnitude(0.0), 0.0); + assert_biteq!((-5.0 as $t).clamp_magnitude(0.0), -0.0); + assert_biteq!((5.0 as $t).clamp_magnitude(-0.0), 0.0); + assert_biteq!((-5.0 as $t).clamp_magnitude(-0.0), -0.0); // Special values - Infinity let inf = <$t>::INFINITY; @@ -98,42 +188,95 @@ macro_rules! check_float_clamp { let max = <$t>::MAX; let min = <$t>::MIN; // Large limit - let huge = 1e30; - assert_eq!(max.clamp_magnitude(huge), huge); - assert_eq!(min.clamp_magnitude(huge), -huge); + assert_eq!(max.clamp_magnitude($huge), $huge); + assert_eq!(min.clamp_magnitude($huge), -$huge); + + // NaN + let nan = <$t>::NAN; + assert!(nan.clamp_magnitude(1.0).is_nan()); + + // Const clamping + const C1: $t = (5.0 as $t).clamp_magnitude(3.0); + assert_eq!(C1, 3.0); + const C2: $t = (-5.0 as $t).clamp_magnitude(3.0); + assert_eq!(C2, -3.0); + const C3: $t = (2.0 as $t).clamp_magnitude(3.0); + assert_eq!(C3, 2.0); + const C4: $t = (-2.0 as $t).clamp_magnitude(3.0); + assert_eq!(C4, -2.0); }; } +#[test] +#[cfg(target_has_reliable_f16)] +fn test_clamp_magnitude_f16() { + check_float_clamp!(f16, 1e3); +} + #[test] fn test_clamp_magnitude_f32() { - check_float_clamp!(f32); + check_float_clamp!(f32, 1e30); } #[test] fn test_clamp_magnitude_f64() { - check_float_clamp!(f64); + check_float_clamp!(f64, 1e300); +} + +#[test] +#[cfg(target_has_reliable_f128)] +fn test_clamp_magnitude_f128() { + check_float_clamp!(f128, 1e3000); } #[test] -#[should_panic(expected = "limit must be non-negative")] +#[cfg(target_has_reliable_f16)] +#[should_panic(expected = "limit must be non-negative and not NaN")] +fn test_clamp_magnitude_f16_panic_negative_limit() { + let _ = 1.0f16.clamp_magnitude(-1.0); +} + +#[test] +#[should_panic(expected = "limit must be non-negative and not NaN")] fn test_clamp_magnitude_f32_panic_negative_limit() { let _ = 1.0f32.clamp_magnitude(-1.0); } #[test] -#[should_panic(expected = "limit must be non-negative")] +#[should_panic(expected = "limit must be non-negative and not NaN")] fn test_clamp_magnitude_f64_panic_negative_limit() { let _ = 1.0f64.clamp_magnitude(-1.0); } #[test] -#[should_panic] +#[cfg(target_has_reliable_f128)] +#[should_panic(expected = "limit must be non-negative and not NaN")] +fn test_clamp_magnitude_f128_panic_negative_limit() { + let _ = 1.0f128.clamp_magnitude(-1.0); +} + +#[test] +#[cfg(target_has_reliable_f16)] +#[should_panic(expected = "limit must be non-negative and not NaN")] +fn test_clamp_magnitude_f16_panic_nan_limit() { + let _ = 1.0f16.clamp_magnitude(f16::NAN); +} + +#[test] +#[should_panic(expected = "limit must be non-negative and not NaN")] fn test_clamp_magnitude_f32_panic_nan_limit() { let _ = 1.0f32.clamp_magnitude(f32::NAN); } #[test] -#[should_panic] +#[should_panic(expected = "limit must be non-negative and not NaN")] fn test_clamp_magnitude_f64_panic_nan_limit() { let _ = 1.0f64.clamp_magnitude(f64::NAN); } + +#[test] +#[cfg(target_has_reliable_f128)] +#[should_panic(expected = "limit must be non-negative and not NaN")] +fn test_clamp_magnitude_f128_panic_nan_limit() { + let _ = 1.0f128.clamp_magnitude(f128::NAN); +} diff --git a/library/coretests/tests/num/mod.rs b/library/coretests/tests/num/mod.rs index b1c3001790f07..f892734d8b95d 100644 --- a/library/coretests/tests/num/mod.rs +++ b/library/coretests/tests/num/mod.rs @@ -24,6 +24,7 @@ mod u8; mod bignum; mod carryless_mul; mod cast; +mod clamp_magnitude; mod complex; mod const_from; mod dec2flt; diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index a3709adfc2c37..886f258f8fe98 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -28,7 +28,6 @@ #![feature(rustc_attrs)] #![feature(extend_one)] #![feature(f16)] -#![cfg_attr(bootstrap, feature(mem_conjure_zst))] #![recursion_limit = "256"] #![allow(internal_features)] #![deny(ffi_unwind_calls)] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 1d35b42a53947..67eebd820ca59 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -167,3 +167,7 @@ check-cfg = [ 'cfg(target_has_reliable_f128)', 'cfg(target_has_reliable_f128_math)', ] + +[lints.cargo] +# panic_abort is not directly used but must be linked in +unused_dependencies = "allow" diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index c6f94944006c9..fa977d16e2311 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -216,7 +216,7 @@ impl System { // The Allocator impl checks the layout size to be non-zero and forwards to the // platform functions in `std::sys::*::alloc`. -#[stable(feature = "allocator_api", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "allocator_api", since = "1.100.0")] unsafe impl Allocator for System { #[inline] fn allocate(&self, layout: Layout) -> Result, AllocError> { diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs index dd6e4a690e326..0520da62ffae9 100644 --- a/library/std/src/os/unix/net/addr.rs +++ b/library/std/src/os/unix/net/addr.rs @@ -87,7 +87,7 @@ enum AddressKind<'a> { /// return /// } /// }; -/// let addr = socket.local_addr().expect("Couldn't get local address"); +/// let addr = socket.local_addr().expect("`UnixListener::local_addr` should not fail"); /// ``` #[derive(Clone)] #[stable(feature = "unix_socket", since = "1.10.0")] @@ -188,7 +188,7 @@ impl SocketAddr { /// /// fn main() -> std::io::Result<()> { /// let socket = UnixListener::bind("/tmp/sock")?; - /// let addr = socket.local_addr().expect("Couldn't get local address"); + /// let addr = socket.local_addr().expect("`UnixListener::local_addr` should not fail"); /// assert_eq!(addr.is_unnamed(), false); /// Ok(()) /// } @@ -202,7 +202,7 @@ impl SocketAddr { /// /// fn main() -> std::io::Result<()> { /// let socket = UnixDatagram::unbound()?; - /// let addr = socket.local_addr().expect("Couldn't get local address"); + /// let addr = socket.local_addr().expect("`UnixListener::local_addr` should not fail"); /// assert_eq!(addr.is_unnamed(), true); /// Ok(()) /// } @@ -226,7 +226,7 @@ impl SocketAddr { /// /// fn main() -> std::io::Result<()> { /// let socket = UnixListener::bind("/tmp/sock")?; - /// let addr = socket.local_addr().expect("Couldn't get local address"); + /// let addr = socket.local_addr().expect("`UnixListener::local_addr` should not fail"); /// assert_eq!(addr.as_pathname(), Some(Path::new("/tmp/sock"))); /// Ok(()) /// } @@ -240,7 +240,7 @@ impl SocketAddr { /// /// fn main() -> std::io::Result<()> { /// let socket = UnixDatagram::unbound()?; - /// let addr = socket.local_addr().expect("Couldn't get local address"); + /// let addr = socket.local_addr().expect("`UnixListener::local_addr` should not fail"); /// assert_eq!(addr.as_pathname(), None); /// Ok(()) /// } diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs index e03ecd7eed9ea..f80a3a887c54d 100644 --- a/library/std/src/os/unix/net/datagram.rs +++ b/library/std/src/os/unix/net/datagram.rs @@ -273,7 +273,7 @@ impl UnixDatagram { /// /// fn main() -> std::io::Result<()> { /// let sock = UnixDatagram::bind("/path/to/the/socket")?; - /// let sock_copy = sock.try_clone().expect("try_clone failed"); + /// let sock_copy = sock.try_clone().expect("`UnixDatagram::try_clone` should not fail"); /// Ok(()) /// } /// ``` @@ -292,7 +292,7 @@ impl UnixDatagram { /// /// fn main() -> std::io::Result<()> { /// let sock = UnixDatagram::bind("/path/to/the/socket")?; - /// let addr = sock.local_addr().expect("Couldn't get local address"); + /// let addr = sock.local_addr().expect("`UnixDatagram::local_addr` should not fail"); /// Ok(()) /// } /// ``` @@ -317,7 +317,7 @@ impl UnixDatagram { /// let sock = UnixDatagram::unbound()?; /// sock.connect("/path/to/the/socket")?; /// - /// let addr = sock.peer_addr().expect("Couldn't get peer address"); + /// let addr = sock.peer_addr().expect("`UnixDatagram::peer_addr` should not fail"); /// Ok(()) /// } /// ``` @@ -390,7 +390,7 @@ impl UnixDatagram { /// fn main() -> std::io::Result<()> { /// let sock = UnixDatagram::bind("/path/to/the/socket")?; /// let mut buf = vec![0; 10]; - /// sock.recv(buf.as_mut_slice()).expect("recv function failed"); + /// sock.recv(buf.as_mut_slice()).expect("`UnixDatagram::recv` should not fail"); /// Ok(()) /// } /// ``` @@ -523,7 +523,7 @@ impl UnixDatagram { /// /// fn main() -> std::io::Result<()> { /// let sock = UnixDatagram::unbound()?; - /// sock.send_to(b"omelette au fromage", "/some/sock").expect("send_to function failed"); + /// sock.send_to(b"omelette au fromage", "/some/sock").expect("`UnixDatagram::send_to` should not fail"); /// Ok(()) /// } /// ``` @@ -561,7 +561,7 @@ impl UnixDatagram { /// let addr = bound.local_addr()?; /// /// let sock = UnixDatagram::unbound()?; - /// sock.send_to_addr(b"bacon egg and cheese", &addr).expect("send_to_addr function failed"); + /// sock.send_to_addr(b"bacon egg and cheese", &addr).expect("`UnixDatagram::send_to_addr` should not fail"); /// Ok(()) /// } /// ``` @@ -595,8 +595,8 @@ impl UnixDatagram { /// /// fn main() -> std::io::Result<()> { /// let sock = UnixDatagram::unbound()?; - /// sock.connect("/some/sock").expect("Couldn't connect"); - /// sock.send(b"omelette au fromage").expect("send_to function failed"); + /// sock.connect("/some/sock").expect("`UnixDatagram::connect` should not fail"); + /// sock.send(b"omelette au fromage").expect("`UnixDatagram` is not connected"); /// Ok(()) /// } /// ``` @@ -638,7 +638,7 @@ impl UnixDatagram { /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]); /// ancillary.add_fds(&fds[..]); /// sock.send_vectored_with_ancillary_to(bufs, &mut ancillary, "/some/sock") - /// .expect("send_vectored_with_ancillary_to function failed"); + /// .expect("`UnixDatagram::send_vectored_with_ancillary_to` should not fail"); /// Ok(()) /// } /// ``` @@ -686,7 +686,7 @@ impl UnixDatagram { /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]); /// ancillary.add_fds(&fds[..]); /// sock.send_vectored_with_ancillary(bufs, &mut ancillary) - /// .expect("send_vectored_with_ancillary function failed"); + /// .expect("`UnixDatagram::send_vectored_with_ancillary` should not fail"); /// Ok(()) /// } /// ``` @@ -719,7 +719,7 @@ impl UnixDatagram { /// fn main() -> std::io::Result<()> { /// let sock = UnixDatagram::unbound()?; /// sock.set_read_timeout(Some(Duration::new(1, 0))) - /// .expect("set_read_timeout function failed"); + /// .expect("`UnixDatagram::set_read_timeout` should not fail"); /// Ok(()) /// } /// ``` @@ -765,7 +765,7 @@ impl UnixDatagram { /// fn main() -> std::io::Result<()> { /// let sock = UnixDatagram::unbound()?; /// sock.set_write_timeout(Some(Duration::new(1, 0))) - /// .expect("set_write_timeout function failed"); + /// .expect("`UnixDatagram::set_write_timeout` should not fail"); /// Ok(()) /// } /// ``` @@ -804,7 +804,7 @@ impl UnixDatagram { /// fn main() -> std::io::Result<()> { /// let sock = UnixDatagram::unbound()?; /// sock.set_read_timeout(Some(Duration::new(1, 0))) - /// .expect("set_read_timeout function failed"); + /// .expect("`UnixDatagram::set_read_timeout` should not fail"); /// assert_eq!(sock.read_timeout()?, Some(Duration::new(1, 0))); /// Ok(()) /// } @@ -826,7 +826,7 @@ impl UnixDatagram { /// fn main() -> std::io::Result<()> { /// let sock = UnixDatagram::unbound()?; /// sock.set_write_timeout(Some(Duration::new(1, 0))) - /// .expect("set_write_timeout function failed"); + /// .expect("`UnixDatagram::set_write_timeout` should not fail"); /// assert_eq!(sock.write_timeout()?, Some(Duration::new(1, 0))); /// Ok(()) /// } @@ -846,7 +846,7 @@ impl UnixDatagram { /// /// fn main() -> std::io::Result<()> { /// let sock = UnixDatagram::unbound()?; - /// sock.set_nonblocking(true).expect("set_nonblocking function failed"); + /// sock.set_nonblocking(true).expect("`UnixDatagram::set_nonblocking` should not fail"); /// Ok(()) /// } /// ``` @@ -914,7 +914,7 @@ impl UnixDatagram { /// /// fn main() -> std::io::Result<()> { /// let sock = UnixDatagram::unbound()?; - /// sock.shutdown(Shutdown::Both).expect("shutdown function failed"); + /// sock.shutdown(Shutdown::Both).expect("`UnixDatagram::shutdown` should not fail"); /// Ok(()) /// } /// ``` @@ -941,7 +941,7 @@ impl UnixDatagram { /// fn main() -> std::io::Result<()> { /// let socket = UnixDatagram::bind("/tmp/sock")?; /// let mut buf = [0; 10]; - /// let len = socket.peek(&mut buf).expect("peek failed"); + /// let len = socket.peek(&mut buf).expect("`UnixDatagram::peek` should not fail"); /// Ok(()) /// } /// ``` diff --git a/library/std/src/os/unix/net/listener.rs b/library/std/src/os/unix/net/listener.rs index b7f8d25a85ae5..793e2378e716d 100644 --- a/library/std/src/os/unix/net/listener.rs +++ b/library/std/src/os/unix/net/listener.rs @@ -200,7 +200,7 @@ impl UnixListener { /// /// fn main() -> std::io::Result<()> { /// let listener = UnixListener::bind("/path/to/the/socket")?; - /// let listener_copy = listener.try_clone().expect("try_clone failed"); + /// let listener_copy = listener.try_clone().expect("`UnixListener::try_clone` should not fail"); /// Ok(()) /// } /// ``` @@ -219,7 +219,7 @@ impl UnixListener { /// /// fn main() -> std::io::Result<()> { /// let listener = UnixListener::bind("/path/to/the/socket")?; - /// let addr = listener.local_addr().expect("Couldn't get local address"); + /// let addr = listener.local_addr().expect("`UnixListener::local_addr` should not fail"); /// Ok(()) /// } /// ``` @@ -244,7 +244,7 @@ impl UnixListener { /// /// fn main() -> std::io::Result<()> { /// let listener = UnixListener::bind("/path/to/the/socket")?; - /// listener.set_nonblocking(true).expect("Couldn't set non blocking"); + /// listener.set_nonblocking(true).expect("`UnixListener::set_nonblocking` should not fail"); /// Ok(()) /// } /// ``` diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index 31a908dfe187e..dba49d0406bf1 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -199,7 +199,7 @@ impl UnixStream { /// /// fn main() -> std::io::Result<()> { /// let socket = UnixStream::connect("/tmp/sock")?; - /// let sock_copy = socket.try_clone().expect("Couldn't clone socket"); + /// let sock_copy = socket.try_clone().expect("`UnixStream::try_clone` should not fail"); /// Ok(()) /// } /// ``` @@ -218,7 +218,7 @@ impl UnixStream { /// /// fn main() -> std::io::Result<()> { /// let socket = UnixStream::connect("/tmp/sock")?; - /// let addr = socket.local_addr().expect("Couldn't get local address"); + /// let addr = socket.local_addr().expect("`UnixStream::local_addr` should not fail"); /// Ok(()) /// } /// ``` @@ -237,7 +237,7 @@ impl UnixStream { /// /// fn main() -> std::io::Result<()> { /// let socket = UnixStream::connect("/tmp/sock")?; - /// let addr = socket.peer_addr().expect("Couldn't get peer address"); + /// let addr = socket.peer_addr().expect("`UnixStream::peer_addr` should not fail"); /// Ok(()) /// } /// ``` @@ -257,7 +257,7 @@ impl UnixStream { /// /// fn main() -> std::io::Result<()> { /// let socket = UnixStream::connect("/tmp/sock")?; - /// let peer_cred = socket.peer_cred().expect("Couldn't get peer credentials"); + /// let peer_cred = socket.peer_cred().expect("`UnixStream::peer_cred` should not fail"); /// Ok(()) /// } /// ``` @@ -295,7 +295,7 @@ impl UnixStream { /// /// fn main() -> std::io::Result<()> { /// let socket = UnixStream::connect("/tmp/sock")?; - /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout"); + /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("`UnixStream::set_read_timeout` should not fail"); /// Ok(()) /// } /// ``` @@ -340,7 +340,7 @@ impl UnixStream { /// fn main() -> std::io::Result<()> { /// let socket = UnixStream::connect("/tmp/sock")?; /// socket.set_write_timeout(Some(Duration::new(1, 0))) - /// .expect("Couldn't set write timeout"); + /// .expect("`UnixStream::connect` should not fail"); /// Ok(()) /// } /// ``` @@ -378,7 +378,7 @@ impl UnixStream { /// /// fn main() -> std::io::Result<()> { /// let socket = UnixStream::connect("/tmp/sock")?; - /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout"); + /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("`UnixStream::set_read_timeout` should not fail"); /// assert_eq!(socket.read_timeout()?, Some(Duration::new(1, 0))); /// Ok(()) /// } @@ -400,7 +400,7 @@ impl UnixStream { /// fn main() -> std::io::Result<()> { /// let socket = UnixStream::connect("/tmp/sock")?; /// socket.set_write_timeout(Some(Duration::new(1, 0))) - /// .expect("Couldn't set write timeout"); + /// .expect("`UnixStream::set_write_timeout` should not fail"); /// assert_eq!(socket.write_timeout()?, Some(Duration::new(1, 0))); /// Ok(()) /// } @@ -420,7 +420,7 @@ impl UnixStream { /// /// fn main() -> std::io::Result<()> { /// let socket = UnixStream::connect("/tmp/sock")?; - /// socket.set_nonblocking(true).expect("Couldn't set nonblocking"); + /// socket.set_nonblocking(true).expect("`UnixStream::set_nonblocking` should not fail"); /// Ok(()) /// } /// ``` @@ -493,7 +493,7 @@ impl UnixStream { /// /// fn main() -> std::io::Result<()> { /// let socket = UnixStream::connect("/tmp/sock")?; - /// socket.shutdown(Shutdown::Both).expect("shutdown function failed"); + /// socket.shutdown(Shutdown::Both).expect("`UnixStream::shutdown` should not fail"); /// Ok(()) /// } /// ``` @@ -520,7 +520,7 @@ impl UnixStream { /// fn main() -> std::io::Result<()> { /// let socket = UnixStream::connect("/tmp/sock")?; /// let mut buf = [0; 10]; - /// let len = socket.peek(&mut buf).expect("peek failed"); + /// let len = socket.peek(&mut buf).expect("`UnixStream::peek` should not fail"); /// Ok(()) /// } /// ``` diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index 3e1fe13ee6fc2..971d88c65ea75 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -188,7 +188,7 @@ pub impl(self) trait CommandExt { /// /// /// [1]: - #[stable(feature = "windows_process_extensions_show_window", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "windows_process_extensions_show_window", since = "1.100.0")] fn show_window(&mut self, cmd_show: u16) -> &mut process::Command; /// Forces all arguments to be wrapped in quote (`"`) characters. @@ -451,23 +451,14 @@ impl CommandExt for process::Command { } } -#[stable( - feature = "windows_process_extensions_main_thread_handle", - since = "CURRENT_RUSTC_VERSION" -)] +#[stable(feature = "windows_process_extensions_main_thread_handle", since = "1.100.0")] pub impl(self) trait ChildExt { /// Extracts the main thread raw handle, without taking ownership - #[stable( - feature = "windows_process_extensions_main_thread_handle", - since = "CURRENT_RUSTC_VERSION" - )] + #[stable(feature = "windows_process_extensions_main_thread_handle", since = "1.100.0")] fn main_thread_handle(&self) -> BorrowedHandle<'_>; } -#[stable( - feature = "windows_process_extensions_main_thread_handle", - since = "CURRENT_RUSTC_VERSION" -)] +#[stable(feature = "windows_process_extensions_main_thread_handle", since = "1.100.0")] impl ChildExt for process::Child { fn main_thread_handle(&self) -> BorrowedHandle<'_> { self.handle.main_thread_handle() diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 1f45423bd8285..4eb3796ac026d 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2770,7 +2770,7 @@ impl Path { /// assert_eq!(path.trim_prefix("/haha"), path); /// ``` #[must_use = "this returns the remaining path as a new path, without modifying the original"] - #[stable(feature = "trim_prefix_suffix", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "trim_prefix_suffix", since = "1.100.0")] pub fn trim_prefix

(&self, base: P) -> &Path where P: AsRef, diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs index 9b555c32df99d..9b7dd3b78eac7 100644 --- a/library/std/src/sync/once.rs +++ b/library/std/src/sync/once.rs @@ -348,7 +348,7 @@ impl fmt::Debug for Once { } } -#[stable(feature = "once_default", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "once_default", since = "1.100.0")] #[rustc_const_unstable(feature = "const_default", issue = "143894")] const impl Default for Once { /// Creates a new `Once` value, same as [`Once::new`]. diff --git a/library/std_detect/Cargo.toml b/library/std_detect/Cargo.toml index a6785bb20555d..c03fff827d5cd 100644 --- a/library/std_detect/Cargo.toml +++ b/library/std_detect/Cargo.toml @@ -24,3 +24,7 @@ libc = { version = "0.2.0", default-features = false } [features] std_detect_env_override = [] + +[lints.cargo] +# libc is definitely used in code but the lint doesn't realize that (unclear why) +unused_dependencies = "allow" diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml index 10562389d62d3..cef5532857b5e 100644 --- a/library/sysroot/Cargo.toml +++ b/library/sysroot/Cargo.toml @@ -32,3 +32,8 @@ optimize_for_size = ["std/optimize_for_size"] panic-unwind = ["std/panic-unwind"] profiler = ["dep:profiler_builtins"] windows_raw_dylib = ["std/windows_raw_dylib"] + +[lints.cargo] +# We expect some of these dependencies to not actually be used since this is +# just an aggregator crate. +unused_dependencies = "allow" diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 72895e1f2462f..c8d1cfd599909 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -423,33 +423,19 @@ pub(crate) fn run_tests( // `running 0 tests...`. if ran_edition_tests == 0 || !standalone_tests.is_empty() { standalone_tests.sort_by(|a, b| a.desc.name.as_slice().cmp(b.desc.name.as_slice())); - cfg_select! { - bootstrap => { - test::test_main_with_exit_callback(&test_args, standalone_tests, None, || { - let times = times.times_in_secs(); - // We ensure temp dir destructor is called. - std::mem::drop(temp_dir.take()); - if let Some((total_time, compilation_time)) = times { - test::print_merged_doctests_times(&test_args, total_time, compilation_time); - } - }); - } - _ => { - // We need a vector of `&TestDescAndFn`. - let standalone_test_refs = &standalone_tests.iter().collect::>(); - let exit = test::test_main(&test_args, standalone_test_refs); - let times = times.times_in_secs(); - // We ensure temp dir destructor is called. - std::mem::drop(standalone_tests); - std::mem::drop(temp_dir.take()); - if let Some((total_time, compilation_time)) = times { - test::print_merged_doctests_times(&test_args, total_time, compilation_time); - } - // Fall through on success, the caller may want to do more stuff. - if exit != std::process::ExitCode::SUCCESS { - exit.exit_process(); - } - } + // We need a vector of `&TestDescAndFn`. + let standalone_test_refs = &standalone_tests.iter().collect::>(); + let exit = test::test_main(&test_args, standalone_test_refs); + let times = times.times_in_secs(); + // We ensure temp dir destructor is called. + std::mem::drop(standalone_tests); + std::mem::drop(temp_dir.take()); + if let Some((total_time, compilation_time)) = times { + test::print_merged_doctests_times(&test_args, total_time, compilation_time); + } + // Fall through on success, the caller may want to do more stuff. + if exit != std::process::ExitCode::SUCCESS { + exit.exit_process(); } } else { // If the first condition branch exited successfully, it will @@ -1175,18 +1161,6 @@ fn generate_test_desc_and_fn( no_run: scraped_test.no_run(&rustdoc_options), test_type: test::TestType::DocTest, }, - #[cfg(bootstrap)] - testfn: test::DynTestFn(Box::new(move || { - doctest_run_fn( - &rustdoc_test_options, - &opts, - &test, - &scraped_test, - &rustdoc_options, - &unused_externs, - ) - })), - #[cfg(not(bootstrap))] testfn: test::DynTestFn(Arc::new(move || { doctest_run_fn( &rustdoc_test_options, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index b907c3ef2cb11..85bae04fcb2e8 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -1,6 +1,4 @@ // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(trim_prefix_suffix))] -#![cfg_attr(not(bootstrap), feature(exitcode_exit_method))] #![doc( html_root_url = "https://doc.rust-lang.org/nightly/", html_playground_url = "https://play.rust-lang.org/" @@ -8,6 +6,7 @@ #![feature(ascii_char)] #![feature(ascii_char_variants)] #![feature(deref_patterns)] +#![feature(exitcode_exit_method)] #![feature(file_buffered)] #![feature(formatting_options)] #![feature(iter_intersperse)] diff --git a/src/stage0 b/src/stage0 index 3426edfafbf16..65357a133fe09 100644 --- a/src/stage0 +++ b/src/stage0 @@ -13,605 +13,588 @@ nightly_branch=main # All changes below this comment will be overridden the next time the # tool is executed. -compiler_channel_manifest_hash=1612da194f5a1c699d7a20519341ed9aa62e29f28bf3f303ab6801e8e266b103 -compiler_git_commit_hash=cbae9b4cae2b108f6a3d18cfe6075714bb739463 -compiler_date=2026-08-30 +compiler_channel_manifest_hash=748739f565e7977153cc87b1bf606072e31088a751ed351c1a076cfc4ebd04ed +compiler_git_commit_hash=e3feeb59cd1bdd011a2bfcc0747b55125d9b8527 +compiler_date=2026-09-29 compiler_version=beta -rustfmt_channel_manifest_hash=d950b3b494cde6b8448964e1795a86530bff7ee5e729a48ed6341c6ec3ee5ad1 -rustfmt_git_commit_hash=fd7ed57dfd3bdebb745a1d8158638727b0e7047a -rustfmt_date=2026-08-30 +rustfmt_channel_manifest_hash=4ac7009a2d787fa804178e5a7a067b1f828f85623a160ef7cc417d378814ef3e +rustfmt_git_commit_hash=c1070d69382b8d2f2eb65119c738a77d9e324c9e +rustfmt_date=2026-09-29 rustfmt_version=nightly -dist/2026-08-30/rustc-beta-aarch64-apple-darwin.tar.gz=63da74142f0e917ccbc13cf182bae60d9ec3d545b712ac6150fe8b4e633a2c7a -dist/2026-08-30/rustc-beta-aarch64-apple-darwin.tar.xz=0c20c4730544923b2ba9ab4ccf98cd22db6759d1d6cc2e5b8c99662b953163ac -dist/2026-08-30/rustc-beta-aarch64-pc-windows-gnullvm.tar.gz=1d67701059998ff993a42c3781b2b735bf537d9db46bdb0b94e6cd9313f69b0c -dist/2026-08-30/rustc-beta-aarch64-pc-windows-gnullvm.tar.xz=093d13372b7bc06246e63a1e18aac59464e71939b951e14ae0ce500f467be92c -dist/2026-08-30/rustc-beta-aarch64-pc-windows-msvc.tar.gz=d1a51ad8e37b8f482c994527f7062a4b3ac9d1734be81b677a5e270ff121747e -dist/2026-08-30/rustc-beta-aarch64-pc-windows-msvc.tar.xz=f019195e5c72d6b6e699416d8851555965ccf5f108bddae999e9bf37fec19693 -dist/2026-08-30/rustc-beta-aarch64-unknown-freebsd.tar.gz=f9b8e19c81bb9cbb2c75d841f043b084aa9c3c239b359c761d02d255c16ec928 -dist/2026-08-30/rustc-beta-aarch64-unknown-freebsd.tar.xz=fd02f9f057e75b2f6e5c763dcad6dfd9ec39c8e03a40f2cffb82823edbb2da26 -dist/2026-08-30/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=1f44bbb85ebb6d4c218016661afa545a8e038f1b937e49f81bebd915ba10c608 -dist/2026-08-30/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=e2e2bf7f32709df924efe7b5f530781ea1428ce163e92270a3ee476b7b3a3d1a -dist/2026-08-30/rustc-beta-aarch64-unknown-linux-musl.tar.gz=5452dc6c27dab927dab0afb5be5f300f1cc9af3c7ccfb88dd605227851fd65d7 -dist/2026-08-30/rustc-beta-aarch64-unknown-linux-musl.tar.xz=1f7c588a39f096f7578fc6bca93f0c85ae40976cf26a51913070119a8b910e07 -dist/2026-08-30/rustc-beta-aarch64-unknown-linux-ohos.tar.gz=8aa1b28d25e4c7a21d3fcb85254d1e2c169ff55b3536a290edacecb6c051ab4b -dist/2026-08-30/rustc-beta-aarch64-unknown-linux-ohos.tar.xz=27208aaaebbcea8e819d7d9fbf20dd994cc24f727dbee339d34e6a995e2b9864 -dist/2026-08-30/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=73f04b6601665531d79900f59a8f92f3e7a90f196d62e1ea10e20a3e6ca6f8f4 -dist/2026-08-30/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=64b0fb006d621f6003527b41e9e31f9141f3df09a0dfe979ee68054d1346016e -dist/2026-08-30/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=19e1f450d4aa8d169898170c9bcd2ab7fba9d3453a631c57a5148236805f101e -dist/2026-08-30/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=f7715866e5e05360279365dc39eefc96436a53f429cd5b283662a81634f7371f -dist/2026-08-30/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=2e765b6a53cabb0077ad4f8f563862d115c9f152165dc92615a727bdf0d2998b -dist/2026-08-30/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=09a111ae1c8861099a39d495fcea86c65780bb2b7a6c7bc19fff56915b4f11a5 -dist/2026-08-30/rustc-beta-i686-pc-windows-gnu.tar.gz=02d8f06789c7f48a19e31ddc7c3f8dab995197f7857d410f6df60dad1067b8cf -dist/2026-08-30/rustc-beta-i686-pc-windows-gnu.tar.xz=91bf9711b7551cb3caf6660824ad5c04f27ed9a0fd086211b3aed56628311d45 -dist/2026-08-30/rustc-beta-i686-pc-windows-msvc.tar.gz=70525d3d60e2ebddb9e7b3341314caa0df4e34bdfcb47bae46927fa13a6ed327 -dist/2026-08-30/rustc-beta-i686-pc-windows-msvc.tar.xz=59d9ecfad856f135df42afd957024ede0a3eb263a7ec4ffbf517e16696054d83 -dist/2026-08-30/rustc-beta-i686-unknown-linux-gnu.tar.gz=317c5379344a6e473a29e432d4aab7399ff3dbe86a72dd279c0c82c495d98c65 -dist/2026-08-30/rustc-beta-i686-unknown-linux-gnu.tar.xz=af6b78184886cff946f408dcd27ce4332fe39b514c49a6c285aa12ee8a895194 -dist/2026-08-30/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=0894c6b942bad197888f596f7d518595f5db700cc21089b39d9b923c0bc2c902 -dist/2026-08-30/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=d10527ec270b021405f4c7c8853296837efa3d4f1804d7e9aaf22c7f76b3ac8d -dist/2026-08-30/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=82edc27720b2001ef4ccfaa8638c839bd76ca9294723516749544a794a963f76 -dist/2026-08-30/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=efa4d683554b36de9d19d1aa6a6bcd39223e4b8726d5108895071169f976abf6 -dist/2026-08-30/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=453f91a3f885305cdc98ae91bb06fe0cd3bc2f2cad2db05ffc51a9957c5d7dd5 -dist/2026-08-30/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=acb98b89f961c5b309f54e6dd647f68c105f0f95aabbddbe6363055ab842fb4f -dist/2026-08-30/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=791dc39fa441ecbd5e976da99d988796ad5382f62a85856722dba4fdc4f81491 -dist/2026-08-30/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=005c0e756b757b0d49b6ec9777a9997799d5328f826a4d168a67994591323037 -dist/2026-08-30/rustc-beta-powerpc64-unknown-linux-musl.tar.gz=d3b6748b0471837b8f2f7118e739f4870f2875fb061253c71dbeadcb5a88253d -dist/2026-08-30/rustc-beta-powerpc64-unknown-linux-musl.tar.xz=9c681f8f3efd7f8130ee8c2a40c39d83f6bd58858e134c8df8bba2b65fc3da1a -dist/2026-08-30/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=3924195349e7b1b31f6334f0d07d66ca4f3c423fb57b8bdded25fa1746b4d1b1 -dist/2026-08-30/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=3f0decdada02b892f63920829a4af3541f149d44b162b3a98d2aa006f2bf47cb -dist/2026-08-30/rustc-beta-powerpc64le-unknown-linux-musl.tar.gz=c8c0a5745dfcecc41a52876a9658badf7a35417173f143f50a6d304eb99c4dd6 -dist/2026-08-30/rustc-beta-powerpc64le-unknown-linux-musl.tar.xz=47992ff2ff6725eac8e6322c1d76df258a54fc928cbcc8d175acfe16b5a4058f -dist/2026-08-30/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=91747193505f48d0eba8653bf14855c81999afefb632207eac3d7d6f355fd2bd -dist/2026-08-30/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=95f5717569d3b07ed6808c82a5a3849284ce9b404792806fc06356a11ae54895 -dist/2026-08-30/rustc-beta-riscv64gc-unknown-linux-musl.tar.gz=ff705b94a62127be2bbbaf20a036fd4d9c3fcc23b852bf50b814120637eb28d9 -dist/2026-08-30/rustc-beta-riscv64gc-unknown-linux-musl.tar.xz=da5837ddd0b7ab0b10be836fcf757ce117bbe54e57d7ce696c38e8779be64328 -dist/2026-08-30/rustc-beta-s390x-unknown-linux-gnu.tar.gz=7282b673f837c2998f70a47e44c67d2d88d75f55be6c363a43706f37acde0676 -dist/2026-08-30/rustc-beta-s390x-unknown-linux-gnu.tar.xz=2890fbd6092fac747d44f525623e77c87d5924a878d20be664e20068f729f01c -dist/2026-08-30/rustc-beta-sparcv9-sun-solaris.tar.gz=b1526015253711f6b54e5e2081e5503461ca94e66edffa3226899c357350475d -dist/2026-08-30/rustc-beta-sparcv9-sun-solaris.tar.xz=dc7adedded9d7c4022057709f33de27a6ace3d08a264f17bee7c8e1a92e975b8 -dist/2026-08-30/rustc-beta-x86_64-apple-darwin.tar.gz=9f06cb6793158449b822f07b86a2a57c73d12ad05dee33d188027ae20559f197 -dist/2026-08-30/rustc-beta-x86_64-apple-darwin.tar.xz=d506f9e4bfe7d3d223a88392d5416ac0203924e31b6e3f68a32adc1578d74e0b -dist/2026-08-30/rustc-beta-x86_64-pc-solaris.tar.gz=60825508456e01c09e82986c2c3574dd954e2fbdb16f20db1751437eb2294414 -dist/2026-08-30/rustc-beta-x86_64-pc-solaris.tar.xz=7aa295d6f6ab2eca3d72e1703bc533ac01908dd5080a859c7ab01003d0634d9d -dist/2026-08-30/rustc-beta-x86_64-pc-windows-gnu.tar.gz=01bda7ca1de22ac2881f0da5bd1db0c31500eab3e4b5273d16b581193788e32c -dist/2026-08-30/rustc-beta-x86_64-pc-windows-gnu.tar.xz=65229fa0b642f511ecae17f456d5a67aac0338adcb07ad0746eaec97cd0b2d25 -dist/2026-08-30/rustc-beta-x86_64-pc-windows-gnullvm.tar.gz=90021d8fc771da2febbc00152c6dd7c3b58845a9a522f74573a2acab9f55a016 -dist/2026-08-30/rustc-beta-x86_64-pc-windows-gnullvm.tar.xz=cec531ec82cd3630818985aa6e2e2afdd553e195c87c26873b914c2a159929a2 -dist/2026-08-30/rustc-beta-x86_64-pc-windows-msvc.tar.gz=2d41c0c375f565315155c80e0d241bd8ea132e994b5d87ded8a21302f29d5ab4 -dist/2026-08-30/rustc-beta-x86_64-pc-windows-msvc.tar.xz=6d82171d5e4453c466313f6541fbb62dc74d0c7863651413c687b7f4c27b2a4e -dist/2026-08-30/rustc-beta-x86_64-unknown-freebsd.tar.gz=0509d78b60e4743b1953f12a70a91adc7ef48cf886826dcb16e87695999c7699 -dist/2026-08-30/rustc-beta-x86_64-unknown-freebsd.tar.xz=a5714f58f8651919a51c8ce28536ce83f86fd7ac72bf067dd97189c1d389c07b -dist/2026-08-30/rustc-beta-x86_64-unknown-illumos.tar.gz=883ab0b98ded267ff1b7a8fd0d9ffc7529ff6a5e6b1e73c2168faf1c90d92ef0 -dist/2026-08-30/rustc-beta-x86_64-unknown-illumos.tar.xz=58178ca6b6c9ced54a0f7991fbd94f6d92c32eacffbf774444429ea46b1f58d3 -dist/2026-08-30/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=2a164be1423d98988d4c3e9c7635af9150a961b5fb3d2052517987266978fc65 -dist/2026-08-30/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=66764b74fe55573ea5884ac7ac98fd7e5bff95f4ee0f389e3f5ee07eb75e1623 -dist/2026-08-30/rustc-beta-x86_64-unknown-linux-musl.tar.gz=4b7216393d167874d030e24efd637717f8451c89506c4964220632556522e881 -dist/2026-08-30/rustc-beta-x86_64-unknown-linux-musl.tar.xz=645c594846ac499aa29bef08dacf4402f2479413fb98ab255419bbcbaa39440b -dist/2026-08-30/rustc-beta-x86_64-unknown-netbsd.tar.gz=a1044a20bd4e0894f94d0d2a2f2601bd9e8315be561bb196360950fc959c9ab0 -dist/2026-08-30/rustc-beta-x86_64-unknown-netbsd.tar.xz=c90e60e75e4d2420bb58df22483f028c92eead983b2a5f73e1c87f66196a80d1 -dist/2026-08-30/rust-std-beta-aarch64-apple-darwin.tar.gz=9f02f6d297a31bb6a6bca2648f7e6e381d386365ec2548619f200fce3d1d7109 -dist/2026-08-30/rust-std-beta-aarch64-apple-darwin.tar.xz=d8f4620f3672cae11fdb841a86d44215aeba2e656244286056f7742e966797e3 -dist/2026-08-30/rust-std-beta-aarch64-apple-ios.tar.gz=547510c49fc9c4d993ca76d7d2a38e6e0fc791a8b838fb30e246df78c3480ce8 -dist/2026-08-30/rust-std-beta-aarch64-apple-ios.tar.xz=b54fc751131000c13c58b2863ed238a6d6f750fdb1b1a5e6e1110e05bedc5f7e -dist/2026-08-30/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=c2c93323193b2f6d796934916c002c0d98203745c98458678d70eaff2546566d -dist/2026-08-30/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=ab88ae96f66a15ce8fb00296e8f7f292d31f941e89455529ee7544220187cdec -dist/2026-08-30/rust-std-beta-aarch64-apple-ios-sim.tar.gz=dff0cf3e961505ada60f6fad68cc5f5881b725bb7ef0f0d23b6ae4fb8722f5a1 -dist/2026-08-30/rust-std-beta-aarch64-apple-ios-sim.tar.xz=b6c00ebacb1758e8f3b830a054df06d120e270c4b2a0ef88866b06be2bb95e53 -dist/2026-08-30/rust-std-beta-aarch64-apple-tvos.tar.gz=7f6c1cb3f8b5870449fdbfe1139f27c93b810b1f52da01a93abb8c8656ecc14d -dist/2026-08-30/rust-std-beta-aarch64-apple-tvos.tar.xz=e40b47e96b7ad06f7e13fa0272b4b8014eb4799bd4c7237f35df513eb7eed7cf -dist/2026-08-30/rust-std-beta-aarch64-apple-tvos-sim.tar.gz=158c8066d75a93d770ca620ffb64b92d39630b401a909f17e99765b9871ec25c -dist/2026-08-30/rust-std-beta-aarch64-apple-tvos-sim.tar.xz=635d4e479727b51957b0bbfa14ac5ce7b3282ae146aa04a92ff28963cbf9635f -dist/2026-08-30/rust-std-beta-aarch64-apple-visionos.tar.gz=28f4a6e679995ac6b4037f29c9cdc161183012edb39e484d31ce24ef044128d5 -dist/2026-08-30/rust-std-beta-aarch64-apple-visionos.tar.xz=b3d6255fb1e052747ddf5c3b3484040cbf03dbc882e92cde98c8656442f84cc5 -dist/2026-08-30/rust-std-beta-aarch64-apple-visionos-sim.tar.gz=09facc091183c715daf223d9bd158d6333c6e3f837627bf318f2c0e1be0851b9 -dist/2026-08-30/rust-std-beta-aarch64-apple-visionos-sim.tar.xz=4943e00b8e0496786ec9c2bfa526da1f44aa162f874f7084f51c95c3ec3a44b1 -dist/2026-08-30/rust-std-beta-aarch64-apple-watchos.tar.gz=ba3e478886aa3b34101334e3ab9a3543a0f5e3d44f44efa48bc7b56c14a3951a -dist/2026-08-30/rust-std-beta-aarch64-apple-watchos.tar.xz=2e4e7035ab8464d8ba3775b66433b1888044394bf18343bbbb16304ada735368 -dist/2026-08-30/rust-std-beta-aarch64-apple-watchos-sim.tar.gz=7f8ffe07832cc648c8be54b79bc6923594a34e254245e07fe706fccd52b28195 -dist/2026-08-30/rust-std-beta-aarch64-apple-watchos-sim.tar.xz=343aef2c9816bd2007837916a8ee5101c1b0b97692066c5cf844a7230a42a346 -dist/2026-08-30/rust-std-beta-aarch64-linux-android.tar.gz=94b3a90192944d2483e2c4e3bf02a03e43b00540c16873d869a75b6e6d7a675e -dist/2026-08-30/rust-std-beta-aarch64-linux-android.tar.xz=e26b35a45e9d2331b4ee37f6f9b70f927dc89cd4b956ec76c556577c7b0fa1e4 -dist/2026-08-30/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=24eef069090edc04f787002c971bccbc328775b54d98e3ab63b247a4c1e0e99c -dist/2026-08-30/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=88cf54b25e9a76e303413bb6d32e064d784e6b83dc282a42d45983d57842ca08 -dist/2026-08-30/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=726999c2b5dbec5ca64e56abbce4d246dcb265d709df96d48a4653e863531ac7 -dist/2026-08-30/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=22e04ac2cd44daff5e5873f8492a1a3345f83034021923ff223cb3905c81e16b -dist/2026-08-30/rust-std-beta-aarch64-unknown-freebsd.tar.gz=9593926d80f8b3adfa59b2073f48234001d70c08225d03e0f128f0188d2878c3 -dist/2026-08-30/rust-std-beta-aarch64-unknown-freebsd.tar.xz=f43da9dc7737f5881391e92013f773c6fc3888dece33eac141797617d590ecc1 -dist/2026-08-30/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=9d177fcaf3805830b0b0a1661d3306509f5620195877185b0630193220a95feb -dist/2026-08-30/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=b1c017c1cc05c334f74dbf747d29e692cbf4bdb9c08d5778067266d7816841f4 -dist/2026-08-30/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=b443b40dbe16c1c0805778d34a652b16dd891e5d641ece48f988be00d4ae8c25 -dist/2026-08-30/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=295de2ccd9c9ffaf6648e76a4bd358289fc78ed0ed162d38a69632a6bfae240a -dist/2026-08-30/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=8fdf744594d28f7425df836f3ad3289ea052e26aa98e0d9659c8f03a85d9713a -dist/2026-08-30/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=e87932897c88f458d35e53873b2c019f2cebbf11e634689f8e9b97c9320adcd3 -dist/2026-08-30/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=33e0b8fbe21128edbaa3c2da91fac703107964f818624dd87a03179c9a6b4a62 -dist/2026-08-30/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=8c79addb67a5c8b8181fa25df85516bdc4fa69003c2f8c9e8a6c6c60eaba6920 -dist/2026-08-30/rust-std-beta-aarch64-unknown-none.tar.gz=39cafc68fb5044aa42fa274fc7c49bc210472d5cd97ed82cd09c98b73042f66d -dist/2026-08-30/rust-std-beta-aarch64-unknown-none.tar.xz=78c289e2984f4b99bb9caa4d61833dc94b0588be7aac2309c4c9cf5d75b56703 -dist/2026-08-30/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=b6012253ae93c1a13ea4e8cab50873c206056fd9325d26de402e45669950994d -dist/2026-08-30/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=d9fb182de0cffbb3a74fe309ba65d79323901da154e9766a88a569247f260d2a -dist/2026-08-30/rust-std-beta-aarch64-unknown-uefi.tar.gz=f54892f078518f520b32bf76a932cce2c450289cd70c826542477401109eb3dc -dist/2026-08-30/rust-std-beta-aarch64-unknown-uefi.tar.xz=672c8e38330262341209232c73bb600f2949b3d5a1f5c93d0a95e18539fb94de -dist/2026-08-30/rust-std-beta-arm-linux-androideabi.tar.gz=887d61d7764ea35bcb2fdd608940a0d3b0d888cd2b8c94f33d242ae71d2269d7 -dist/2026-08-30/rust-std-beta-arm-linux-androideabi.tar.xz=29f1dea85c828ae819c5ebca3d76dd451cf72e9498f9f207f3272162cc159cd1 -dist/2026-08-30/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=b735d7f9cfac1d3a7ad22e0b79979f78aeded3c538dee686728ff9e8c64d6787 -dist/2026-08-30/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=878c84e83139426b209f0ae84a898e005f499d38700f5d8446a6aa4ad81feabf -dist/2026-08-30/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=bdaf3e6c1fba51bd37e7d23b547642885b97e3e66e3e5805f60ee03332e1548d -dist/2026-08-30/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=26446f3d1d9e235e11ebe6e21e3c8bb23efe5e8d31671bf2d573af5e39ae7ba3 -dist/2026-08-30/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=21a1317f24f27d3c567c08c8306f3c97a38dad185bde37229e7c279adb52875f -dist/2026-08-30/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=51ad360481ab758d3023dc615351afba30cf99a162e3f207f5275b5995258412 -dist/2026-08-30/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=57d7204c68646f489e1db251e69d5fbb329e71954100a9a58bc4eea5bd526c34 -dist/2026-08-30/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=01b476bcd78cfc757d9687ad65cad8c15f4bc5bd2e3149a04314e1604257169a -dist/2026-08-30/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=3b94aba1d51f5a6f039a555122d358bdd8e8f3a1a13e3622842a56acd9e48765 -dist/2026-08-30/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=c814c2d7b7de9f97457932139960d40d869ae6783528a6e0d7edf3af0d34da2d -dist/2026-08-30/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=2783998a08bf439cc4f6113a2d7f454791a8437bc9bf9b8d3a9d991bf830eddf -dist/2026-08-30/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=bf7bb1f7e676b0f70786ba671a687701879a7b34f3ebee99e6faab139444c0ca -dist/2026-08-30/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=0d39dc704bb80630048ca2b6b3706c4e9bbf8c16a1eb24c41e2c818e2c89222d -dist/2026-08-30/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=98058d9812f279e9797e6e2163d706dfa6676647d6abd64efae52d9602978bfb -dist/2026-08-30/rust-std-beta-armv7-linux-androideabi.tar.gz=906e3d6b21ca38b6358a9c381aba7aa8e2894a2abe649d12dcef91cc5ab83dca -dist/2026-08-30/rust-std-beta-armv7-linux-androideabi.tar.xz=bd9c5e2dc8542dd0ebcdb53b40422d364aec9399b93b731879c5cada4947583b -dist/2026-08-30/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=a4f1149965d18e306ae5fb29382daa6b0e17b1667d8eae08f0342267d7aa6857 -dist/2026-08-30/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=58121e6668b93a7bd853dff02ff26fe0c4f5e721f23acb7f092cbdac35835a87 -dist/2026-08-30/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=7e3ce83fea162bd4eab433bf35402ecc2099a46afeb66b86ea5e54f0b53a93d5 -dist/2026-08-30/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=4737ebecd9ded896ce25f72c7d2397759bd9243d7399bd6955b90e3fdb4c27d2 -dist/2026-08-30/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=26d2c719cb467295e3effaeae939241325d6fdfd6d32784e90b6c955cf294ffc -dist/2026-08-30/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=d2ec9ee496d74deafee30846ce577333154d4c4221943d53129f3a4c8365118e -dist/2026-08-30/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=60007d5b87b54b4f500ce686b1c6740ab7641dda28676a9c56df7b9a36c34141 -dist/2026-08-30/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=1befc6a2e3b6d7e23bc132ad6fcf4e59934d386e2e467dbbc5ec425d628db846 -dist/2026-08-30/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=6ee69a47a0ce552fb9b69edeca089004c84de1d380ea45554964be8dc5b854d7 -dist/2026-08-30/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=6a594a15e7a1962f4417997d1b1fcdfe72a3786f019242567a915237a8f12112 -dist/2026-08-30/rust-std-beta-armv7a-none-eabi.tar.gz=af06b8910b044e0c804802c316904d53d0a6072d601353927bf5d733cbb10664 -dist/2026-08-30/rust-std-beta-armv7a-none-eabi.tar.xz=dda99a3c47b6fdaa000172e3a9f52876d168499a24e33716a1277a2c1d3e303b -dist/2026-08-30/rust-std-beta-armv7a-none-eabihf.tar.gz=42799d4c5f6b596b6f4c565358adacd2982433cf26f16bde99047f63b07ab97a -dist/2026-08-30/rust-std-beta-armv7a-none-eabihf.tar.xz=0cb9cfeae9a30ec848ef007dd9144398c66be3a755ffe94d9898f2da9057170c -dist/2026-08-30/rust-std-beta-armv7r-none-eabi.tar.gz=b248ea8f35a5557e53882f362ab00211f15124688f56e57474c66bece0bc5c77 -dist/2026-08-30/rust-std-beta-armv7r-none-eabi.tar.xz=9427d716b04a5b178788fead61b3b41abb4acf482bc3def3c1f9b3513243b156 -dist/2026-08-30/rust-std-beta-armv7r-none-eabihf.tar.gz=b8f8e1359af035a33afde195fe4c3de23412c950e216d1ecf6a80fe471f5eadc -dist/2026-08-30/rust-std-beta-armv7r-none-eabihf.tar.xz=1a8aa055f437a8e6dc258d60697f10664b2e28e74ee450d256fd38243730a101 -dist/2026-08-30/rust-std-beta-armv8r-none-eabihf.tar.gz=3b512dfdc3365c1e7d19e42755506a2aca6efa880d754d7838e69b19f6a8d607 -dist/2026-08-30/rust-std-beta-armv8r-none-eabihf.tar.xz=f12bca87642b53c9ef4672ad070913a411de0b772a1f4437b9a258a989d8298c -dist/2026-08-30/rust-std-beta-i586-unknown-linux-gnu.tar.gz=af08b969901c84b02a2501a667bd5cb89454a0817ba66c9fd9a00b03503c922c -dist/2026-08-30/rust-std-beta-i586-unknown-linux-gnu.tar.xz=ec871b92b19cef0f63baea61298575f50ee568046470d0bc12bfc7bee830e846 -dist/2026-08-30/rust-std-beta-i586-unknown-linux-musl.tar.gz=b6805cd6642b6b1de3e637581313cb26241526112114adca8157179948f967e4 -dist/2026-08-30/rust-std-beta-i586-unknown-linux-musl.tar.xz=5c2827bdd87154ce42ad9939dae78a022d3c3045f9b8698f60292e5ba0a0ff14 -dist/2026-08-30/rust-std-beta-i686-linux-android.tar.gz=c568edbc22aba9c2e2360bcf821e9c60894ef3836fc7846cff4c178b2d746fc9 -dist/2026-08-30/rust-std-beta-i686-linux-android.tar.xz=0bd654f6591c99d139bb83ab7e2699327697feddb12edec50bf4f834c0edcffc -dist/2026-08-30/rust-std-beta-i686-pc-windows-gnu.tar.gz=701a3087c3810884d3a83345d2ae8b3de6b1514fbf97bbed99a0421abf2fa2b1 -dist/2026-08-30/rust-std-beta-i686-pc-windows-gnu.tar.xz=b8e8bb023d34012e82d708a0d6e4a558c32f0e489b3eb381b88919aa554578fb -dist/2026-08-30/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=a36eafa511ea809368df67889b2fc0b5a18ed7c2a1e9b21118b160f2b8a63a5b -dist/2026-08-30/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=f1b0c50faf927e5ba97cf0533287cd132f1e3a2b9cb0338f7a56e1ed4311b0bb -dist/2026-08-30/rust-std-beta-i686-pc-windows-msvc.tar.gz=847c2c7aed2ca9f03bc2a8a46ce9b2e48e968e8bb9d947349f83ecde27464631 -dist/2026-08-30/rust-std-beta-i686-pc-windows-msvc.tar.xz=e49a11c577a0e860cfac07eaf0fe1a0f502ada16ec7c05c02d0c60293c8aff8d -dist/2026-08-30/rust-std-beta-i686-unknown-freebsd.tar.gz=c2435372ce00925ed17120ba1586b5d3dac6b4ce979e02698d87a74ad71a7a7e -dist/2026-08-30/rust-std-beta-i686-unknown-freebsd.tar.xz=113874727b99b497e5b346e908407f41b7b2f85cae272cc555dd3699fe8de8fb -dist/2026-08-30/rust-std-beta-i686-unknown-linux-gnu.tar.gz=78385dde39126b0eb524a3681bb8607c016110985ef0b2f2da00c86a5961d64d -dist/2026-08-30/rust-std-beta-i686-unknown-linux-gnu.tar.xz=52480e55a90a54d3174232b4b76f6aaef9055da0ed49733b19ea6c3b8a6db1ea -dist/2026-08-30/rust-std-beta-i686-unknown-linux-musl.tar.gz=350e1a7c2925462c4c2a8b796874f17fd0e284680f2dc2e930017b585ed661c0 -dist/2026-08-30/rust-std-beta-i686-unknown-linux-musl.tar.xz=fd62e7c69e1d0388aaeba25a9a65c8e327e60dbbc3f57948b9f7000981eb4172 -dist/2026-08-30/rust-std-beta-i686-unknown-uefi.tar.gz=41dd818f059414729cd8978a4b79995b765493885dd89a0587be88b83f844aa0 -dist/2026-08-30/rust-std-beta-i686-unknown-uefi.tar.xz=6fb74e7c1b4b20c8b28966e2ee89ab9b1208fb43f57d8f9fe91e5c5bdfa9e046 -dist/2026-08-30/rust-std-beta-loongarch32-unknown-none.tar.gz=5cf23bf844fd1157b9360303459beed6fb1ca77a2bdefd7d394a1d50385670f8 -dist/2026-08-30/rust-std-beta-loongarch32-unknown-none.tar.xz=d952d3f950b776c68528bba94c76a06fb2d55d363fcedeecb1155d6de3a31d3b -dist/2026-08-30/rust-std-beta-loongarch32-unknown-none-softfloat.tar.gz=1967abcc458e9f5efc46f052733490cde533ea074a3ddc0d2fcbf002be4ddc79 -dist/2026-08-30/rust-std-beta-loongarch32-unknown-none-softfloat.tar.xz=bcc63e232b44d653196104d93629ead81c19c1facd03d97207da744c353167d7 -dist/2026-08-30/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=d8946832080fa2e13498bbe7e0cc5611f1c93da1a7b5e3b19c836d03fe784c15 -dist/2026-08-30/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=fda84558d60dae4383d6556545bfd0f292f4ca7226db012948c3c2c32b514c6f -dist/2026-08-30/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=63e4aaee66fdf0444becbab59ecbd7a1955d27e5e7420507bfe78e482558a4e7 -dist/2026-08-30/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=6bc088d81bf425614dea2f31fb0bcf229566cfd912078ba997e272492f5dfeb8 -dist/2026-08-30/rust-std-beta-loongarch64-unknown-none.tar.gz=aed26cd5efdefbc5b636d3a31566c816eda9dde7061efff48b327254b2fc9653 -dist/2026-08-30/rust-std-beta-loongarch64-unknown-none.tar.xz=dd470e7c8ed1a37cd140161988578a31297de2f3739a1d0a1994618f61c4c290 -dist/2026-08-30/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=be92ce71185bb0bf4d0b220806e6d0251c80eb70d6ef133c205e8121863d0f41 -dist/2026-08-30/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=1417b6cf3730f228ac07f045b8ee6506c2df0d8ae7b262e61ea7625c2ee866af -dist/2026-08-30/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=1b10411f90f9ceb94ba6e901ea347a7b14c784250b26c7ebf578ea0f0f774c34 -dist/2026-08-30/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=5998d419985fe62e015ff1d01f83907a7606c28364c0edbf540db598dd446ec6 -dist/2026-08-30/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=efba4705562534e2f6ef97857cef856c4d1c88281cb307c7f6696bac05eac943 -dist/2026-08-30/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=d716a06bf4bc9ad2f2d3ae17997cc3b377b8dbd1dfefaf93ae7d4f8c6a913af8 -dist/2026-08-30/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=7576dd106e174a21eaad65bf48351233ad8cdec1c5f172f6531efc1edeb40f59 -dist/2026-08-30/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=e187119c3fda1b444c340f4d123f95fb23274b624683c844676a15ca2457c209 -dist/2026-08-30/rust-std-beta-powerpc64-unknown-linux-musl.tar.gz=43e4647b626a5c8eb34ef930c70b89ae1efc4d7cb93ea35ea91ab82d52e20ae5 -dist/2026-08-30/rust-std-beta-powerpc64-unknown-linux-musl.tar.xz=ca4204801a3326475c726e3916d9a89c1b8f4f9eb8f2115dac4f005f080355de -dist/2026-08-30/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=a5d389199f5e64c7f25a97cbd80082a9b07481d79bdea6052ccac4d5e46ee390 -dist/2026-08-30/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=8979ec9fa392b43e9e0e166a68dfb4a0fdf23e28bb54abcd305b5e0e99811a72 -dist/2026-08-30/rust-std-beta-powerpc64le-unknown-linux-musl.tar.gz=39b9c96f6c01f8ad15e7b5e3cb1550258d9380ea43126c25745c38b7fdb57583 -dist/2026-08-30/rust-std-beta-powerpc64le-unknown-linux-musl.tar.xz=cf68b7783e218d0b5fac2bc6a431b3c8dedbf016c10c510558771cbdb8c473a0 -dist/2026-08-30/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=adac96c3877930f85c8a9ae7a3afce44bf9030c1bf389dc3e21e7ab0c83c9cf7 -dist/2026-08-30/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=138e96b975fd2bcf54525775a02ab05e1f9ad80095d01116f33693b4359bf0d6 -dist/2026-08-30/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=e7be47333fba57452ed7bf22bdb165a60ea243f9a593df5e8eac32796b0d5d7f -dist/2026-08-30/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=9b4ed1df7fc906cac3f1c9bbb5e546b58e9c6402b9573c4f69c160df8c5e00b8 -dist/2026-08-30/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=43898c8585bea709bcd682eeea33e914ab8be343ca27dfb82c3524e5ece2d37c -dist/2026-08-30/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=af236521d4556f90cc003dd17f692de787befc62e8c2df11242262f7c2afff22 -dist/2026-08-30/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=2f8125c2d07bb57d821662f06b7eaf00d8b98a7386be372cbd6cd517eb6c6e7b -dist/2026-08-30/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=1a86efb62f35f60d7b1860c37430e039cecfdad2053f6e449577200d715cbe58 -dist/2026-08-30/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=6f09dc0d0bb9775d0f4b52277913e5fe8795c3d77e178e1682af563f3ab3a030 -dist/2026-08-30/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=0de9f4b1fe08f33dba23effeefa4695a4201094cc587bfdebfb4408e9d58cc8b -dist/2026-08-30/rust-std-beta-riscv64a23-unknown-linux-gnu.tar.gz=dd2e782f2bda2c8f220727b85f8d702efb70977c2232c48bc5d9858264501de3 -dist/2026-08-30/rust-std-beta-riscv64a23-unknown-linux-gnu.tar.xz=d1ba75a8d572591380bba39dd6fed42025f481642993329dc7c20479ea92a6b8 -dist/2026-08-30/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=d01ef2e3a1ec1c69b3a80aad302d066ea4fe406ff752c9b65f7ef1beebba0c22 -dist/2026-08-30/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=fb919571c31f43ef03b35908bf9ca85ba6bcc053ca289380ba2552c4e64104ba -dist/2026-08-30/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=b187f1deba8ea1bb3d3e793c3cb2a6b7f309940e4edbe8b406a023bce82d8785 -dist/2026-08-30/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=741cbbf9d91e955303f253ecd885168737dc01369feb33f738290668be01b146 -dist/2026-08-30/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=ed5c5a046e9896c7d9ad35c76db1c0216ed31c0661d30e29f3f7b5c8211aeb48 -dist/2026-08-30/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=1ae3c3dd12bc5e669d953521862fff3cec12b6f9f71bb8e3e7b24290d05114cd -dist/2026-08-30/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=3d3bd0667e139054169ec2ece3d16219269c858ffef37c4e9615b5bcf1e3c83b -dist/2026-08-30/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=d350e91efad53a550ef8c825e7f7ce12e99bf250afd9a93ed9fd155b72287947 -dist/2026-08-30/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=eac3ec8b4eb9a3b9a127d2e6fffc4b4a752449eb7595950c9af0dc83ea969b72 -dist/2026-08-30/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=d081593cc03f52a6937fb3bef0a2103a02b43cb4705d1747b8b513e1f0983834 -dist/2026-08-30/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=17db3b6de8e015e9c572899bedea98996a47d725c59664e338053ed590e4e33b -dist/2026-08-30/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=2e79e7c3eb7515581a8bbee2d02dd8242d7d3d1529eb067a387338b2ae5a63e6 -dist/2026-08-30/rust-std-beta-sparcv9-sun-solaris.tar.gz=72474e747dbdc104c817c90e96e209cf4adc2a441aea37d9c6dc3f89ceaa1a5b -dist/2026-08-30/rust-std-beta-sparcv9-sun-solaris.tar.xz=65cb719203ec265623fffd66f905257c0eb284c0795e736adcc8dfd31750378d -dist/2026-08-30/rust-std-beta-thumbv6m-none-eabi.tar.gz=25f399a7944d8db8a44c49c0adfe7800fa4b12585c49fe2ed69a1b417571b786 -dist/2026-08-30/rust-std-beta-thumbv6m-none-eabi.tar.xz=02183d46df50acf3edbd6778eccf24e357f9d49d87ae0d8808ef47f98cfbfd51 -dist/2026-08-30/rust-std-beta-thumbv7a-none-eabi.tar.gz=839004d3d6ac180bec0e467a7bbd2ea1ddb47a0f29a92f8b2a074f628cfd0395 -dist/2026-08-30/rust-std-beta-thumbv7a-none-eabi.tar.xz=7b9b6c32078adb895fd07f3f72b2db25e9358bfa4a0470d7cfdc3cc7b5a827d4 -dist/2026-08-30/rust-std-beta-thumbv7a-none-eabihf.tar.gz=5e962fec3cc8661e9a62f15c688ac76bc83685e19c163d3b899ec423766429de -dist/2026-08-30/rust-std-beta-thumbv7a-none-eabihf.tar.xz=8db16b6186b89b3e9e0c5560a12bb09d08263e04aa0f9ee878d25dba9852447b -dist/2026-08-30/rust-std-beta-thumbv7em-none-eabi.tar.gz=0150636fdc64ec355916eec21d1dec8f5e73881dd21cb78907a2f06c14a896e8 -dist/2026-08-30/rust-std-beta-thumbv7em-none-eabi.tar.xz=9e4dc0a8492ea92703df7e00994c0e1728d2eb3152947e9b8550d6ae05a76d0d -dist/2026-08-30/rust-std-beta-thumbv7em-none-eabihf.tar.gz=fe3fd11562d4c428ae2757d42f17ee17bf9485c7e7fda2f6a54406ac6ae14444 -dist/2026-08-30/rust-std-beta-thumbv7em-none-eabihf.tar.xz=97735c5e6f77e59ca7540eb303eaa2432f632f867fc7567f1d25540504e889b6 -dist/2026-08-30/rust-std-beta-thumbv7m-none-eabi.tar.gz=e8afd6861c77eff9e8296e1846c01c06d6b83a858bf76099a79588f167999efb -dist/2026-08-30/rust-std-beta-thumbv7m-none-eabi.tar.xz=0421b81a17afc3af31e46a8bfe32a9b178a6a29ba58e25d71be991d1ab84babf -dist/2026-08-30/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=9612f99fa78f59fcaed30feb3c8660c3ff7e731011226d6114cc49e3f765bb2d -dist/2026-08-30/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=405ab112b26871dc310a7fe3c67d821544f48b4acace5d406c491529555cc890 -dist/2026-08-30/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=884b25035258fc7cfc7b2a0e95358553a3c7812954ec7a18dde82fd77cad24b4 -dist/2026-08-30/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=3648213c47d2e29931f4837914b3aa5d00575ffda7d75654c6d3cd1aece8474a -dist/2026-08-30/rust-std-beta-thumbv7r-none-eabi.tar.gz=680435027aab539feae6b3904717139e20640eb783c7da2ee31f3d06c1c6ac1d -dist/2026-08-30/rust-std-beta-thumbv7r-none-eabi.tar.xz=8fad51ba8f85f7762f40382c1a177c86f8b7ae1a23e41871f560449f34ac099a -dist/2026-08-30/rust-std-beta-thumbv7r-none-eabihf.tar.gz=0a187507505715a5a4497c0422adba69c03e496618e20023d46aa1a261a7e793 -dist/2026-08-30/rust-std-beta-thumbv7r-none-eabihf.tar.xz=b8bdb79d81f1fd5dbdc090b3306f4ec33673dcfe24350c44e1544d00bb8bbe42 -dist/2026-08-30/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=430646899a6bba8c9233eec0987224e2ed42b6cee3aa37ce12bd8aae66097a21 -dist/2026-08-30/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=36576d200890f00ba9e22cbdb337262ef12dc99271c8006832ebe0752c333ccb -dist/2026-08-30/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=2b3cdc315cfbb7bb1a55705cd30934ceb14b7b098ac9e9b86af2091acc1b46ed -dist/2026-08-30/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=ecbee4d541806d2f4559e53e4da549293f4bb881c2f5d99107043251a1f80790 -dist/2026-08-30/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=8f925d1d913c67ffd9d28c8d02b47aade2388472015f4917a0f3166a8a789bb7 -dist/2026-08-30/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=c9ba654ccafd0cf8e876770f3133ae143da10f37058978cb67a547f64aa5812f -dist/2026-08-30/rust-std-beta-thumbv8r-none-eabihf.tar.gz=615b2c19357545860fb64ec3b6715c004a4bf29299d8d2130b022acdc7c46ccc -dist/2026-08-30/rust-std-beta-thumbv8r-none-eabihf.tar.xz=27d47d56201190afbaf2e2339d3f56964ff59972a90c994ea551438ed4703eea -dist/2026-08-30/rust-std-beta-wasm32-unknown-emscripten.tar.gz=8ccf1bbfc69d4e8e452294a838adf848d32d57621350a7791d8ac8e1e72f8336 -dist/2026-08-30/rust-std-beta-wasm32-unknown-emscripten.tar.xz=5bd2be0368720436ace1cf02569ca50fa222f936bdda7761954108756151b3bb -dist/2026-08-30/rust-std-beta-wasm32-unknown-unknown.tar.gz=fbdcf8103c16966255aa5a1a65ed02fe6e39862ef2b6e6eade8af07d51654392 -dist/2026-08-30/rust-std-beta-wasm32-unknown-unknown.tar.xz=5c4f71b3be2808511727536c13b6af98fb61661c092031df3f24c568f8bd31d2 -dist/2026-08-30/rust-std-beta-wasm32-wasip1.tar.gz=254037cb663a97b20471a3c87f95d62d1be7b2810a35e53acb219a552e8b58fc -dist/2026-08-30/rust-std-beta-wasm32-wasip1.tar.xz=5f651662f78216db6d2db5a8ac7f8ed04349a82530c08aab2fe3b43b8ea8bf8a -dist/2026-08-30/rust-std-beta-wasm32-wasip1-threads.tar.gz=6093fe10ebfc96c45909e85ae72f98e4f8093cdf2ce9bd720ac1a1aabddbd60c -dist/2026-08-30/rust-std-beta-wasm32-wasip1-threads.tar.xz=175403a655dc2afa2f7b41bdaaac4cb371a6c5cd99a043178fa93f97ab02f604 -dist/2026-08-30/rust-std-beta-wasm32-wasip2.tar.gz=5248648157e3ec5c37d12a40caae0adac59aaae47438585e79a7fc91c294ddf3 -dist/2026-08-30/rust-std-beta-wasm32-wasip2.tar.xz=46705306104b7c5d25a15c0f3cc94f5e208d4da2b07eb516d63533194e901b5c -dist/2026-08-30/rust-std-beta-wasm32v1-none.tar.gz=746d7fa3e93d255a395baaf67d3d318e6419732698ab0089692bdbed5ec4a13b -dist/2026-08-30/rust-std-beta-wasm32v1-none.tar.xz=97d8daf857aa2da8f8daff5f7137c4cf442f3cf05a019b5608a20a4cf5e5d291 -dist/2026-08-30/rust-std-beta-x86_64-apple-darwin.tar.gz=8a5ca2b36f9f4b2ba1dfde1539e95c30a20173137b9822e7d0ec5b2c12aa89ec -dist/2026-08-30/rust-std-beta-x86_64-apple-darwin.tar.xz=2daa0aa9b738f036815b667c664e152750acbb9d14ab41e4ea994000867caae6 -dist/2026-08-30/rust-std-beta-x86_64-apple-ios.tar.gz=4eb04a86e00e50becf154d88eac41feeda32c76730297fd05178a1e941dce0ec -dist/2026-08-30/rust-std-beta-x86_64-apple-ios.tar.xz=80dd8be8e4c1a83b66a0cce6cb5bdea61640e471e755c314a549b56dad10d2d6 -dist/2026-08-30/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=5080a59c173281ec57ff14c32401cb769b1a577ae7710cc54c820120b35c5564 -dist/2026-08-30/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=fae0fb63364548777b9e644e83e3c6d7aeab37953efea5ac27cd2558c828a551 -dist/2026-08-30/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=fdc91ac8f59e98eac84f79059a486c2ada66890f22b7e66ef7e0b899f65b36e9 -dist/2026-08-30/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=9ead7033def70e9f455e4079d8a8b1c870f8871b80ae721a41f11e53106a6b64 -dist/2026-08-30/rust-std-beta-x86_64-linux-android.tar.gz=c143b388083353883d88d109db9131c1196d2874a0195b66aaa4427365bd4563 -dist/2026-08-30/rust-std-beta-x86_64-linux-android.tar.xz=f877fbc3b099bccfc531661cf4a5d67a69c0cf426b7d6d3269b4aefb85304f9e -dist/2026-08-30/rust-std-beta-x86_64-pc-solaris.tar.gz=719cb1ac855967c03120c7408d05d88ff101e34de40a65f2d37828f496a84eb6 -dist/2026-08-30/rust-std-beta-x86_64-pc-solaris.tar.xz=647430147f7b7903111ef24a90d2f326198ca70bfa0bb0ee5b1e76d297e9a81e -dist/2026-08-30/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=520d157e438e557e8f37792b9c59c913a732c77149b534a1c7d2769b52e932dd -dist/2026-08-30/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=830bf07e7f1b80e535ddfc2c269c8bd4ca3c63853faa6ba39c7360b0fad976d6 -dist/2026-08-30/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=74c1ea656656a624eb84650a833f6d4d3428230435c67ce0a92798a524c55124 -dist/2026-08-30/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=8866757f9e3508bd74c724c754511413697229daf50da755411ddc8f9de78fbc -dist/2026-08-30/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=8b3ed1fbdf18c25a2900568f9c974154750a187d5385e06537fc54c607e8e305 -dist/2026-08-30/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=f5250ac89f4ee3b68b86e125e64b2209360040189b39e34671aee03b9de3abad -dist/2026-08-30/rust-std-beta-x86_64-unknown-freebsd.tar.gz=711017150d461a85f3dcf28a37c7fa354ae08dbfa9ffa049576e71b224d7c189 -dist/2026-08-30/rust-std-beta-x86_64-unknown-freebsd.tar.xz=5f8a081aa1b6e7ab3bf88b6548ed55a0c1021b26060ee2655da38556b54a0e06 -dist/2026-08-30/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=40d0e66f5b6c1831684ec5c6946e2467e9c81c38d5a7ceffbdc9441397d6c214 -dist/2026-08-30/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=2632a2393f2f51884db1c07a3f193f19942bd20ab7a3bce6f654444028188aab -dist/2026-08-30/rust-std-beta-x86_64-unknown-illumos.tar.gz=bfe5417f3575d1fd0302e6caef380e33c71fc07ab1b9a98fc80d66cf8997006f -dist/2026-08-30/rust-std-beta-x86_64-unknown-illumos.tar.xz=bff9b2786581d340b0e801b085bdfb40d19309e07a99a97f92cf2016d77db81f -dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=76d75f97d7b0f3421029d078473529de626d1413d5ac8c0473325c15f2765573 -dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=1ec3eb585a38de48d12e05f78c82394493c9c640f8c6fdf487cc8c29ca88742d -dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnuasan.tar.gz=7d12531568c430c670d4933955b767985504a88c3da513b832b857f28e59fbf2 -dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnuasan.tar.xz=ade92cb3f5ca0088d93eeac74ec29b8532d285a730eb87350086e9cda4f7d60b -dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnumsan.tar.gz=6280a11a0e153f98dfbd4892a90ee60f086c812ded8177e21e6fa3fd9f733441 -dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnumsan.tar.xz=51792543085e26437577f4c3cabd226571c9f9d5b85d142a4d7ec19b992c4bf2 -dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnutsan.tar.gz=85bdd806ddf39fe35df389895b3c531df21b26dd60945f2b92a3f7f7627dfe77 -dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnutsan.tar.xz=076be1c27da9f50254ed8ae748c0ebe01a21af0c47920e035ee25121327cc607 -dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=e0c5acc46aac350663adc8b6b73e097299a94574785baf5487181b321979b34a -dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=f9470afacdce7db3d057bf13af6b6e45574b4c6cd8a1c75adbce2732ab61515e -dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=f207346769473385b1efd771abcc0e2a95d73dc93e5039a0ce4cc329daf1e83b -dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=25d752aed1d312ab614cd065826c688440aaca70cc7e67c4578ca82398f951f6 -dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=fc511b73ed5c0da3303efb8b5e01d6e4465cf028543a9ebcd5b1ba273e3e5104 -dist/2026-08-30/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=9ada977527a2fb632cfecd9414226664b47514adc988fbb0e3cb86cf1f81f81b -dist/2026-08-30/rust-std-beta-x86_64-unknown-netbsd.tar.gz=9268af9ae7ed919e0955a1162376ed84c65906304f3dcc64762a6f8dc764031c -dist/2026-08-30/rust-std-beta-x86_64-unknown-netbsd.tar.xz=49f7e2808660320fcde2f1ffe23d4e5d44f26c9d08124a97ffbd715d24c0d21e -dist/2026-08-30/rust-std-beta-x86_64-unknown-none.tar.gz=7f2dea659c4d5ff038118307cd2fc6286a95a6dc12a85686bd958806e3d49647 -dist/2026-08-30/rust-std-beta-x86_64-unknown-none.tar.xz=e96d78c8025876bdb25613fb81cf27b54803ab0a809d761909fc56e626153e1c -dist/2026-08-30/rust-std-beta-x86_64-unknown-redox.tar.gz=7874b37200d60c3986588f6178a623817acbcb66bbbfb9b81c9e4ae348cbc0bf -dist/2026-08-30/rust-std-beta-x86_64-unknown-redox.tar.xz=a6d454739b2fcd6728a7c19afc6e95e6ce2dfb02a569619a071b02b3fb7a6e33 -dist/2026-08-30/rust-std-beta-x86_64-unknown-uefi.tar.gz=6b4c4371089aa7d2be7dea927dfc623c9958998cf02952b8455dc4f05c466ba4 -dist/2026-08-30/rust-std-beta-x86_64-unknown-uefi.tar.xz=1dd395befcbdd4f379a2f78e498c15113e07934b46dfede8dc1075276d7c7cf2 -dist/2026-08-30/cargo-beta-aarch64-apple-darwin.tar.gz=9e761054280cc664f95355b3ff7c9828d6b98fcb63c6cc65b3ef07f78fa98a2c -dist/2026-08-30/cargo-beta-aarch64-apple-darwin.tar.xz=473eed6c6004b83a306c4fcf34002560c292050a6c25247a8c1cbe3ad05b93b4 -dist/2026-08-30/cargo-beta-aarch64-pc-windows-gnullvm.tar.gz=079698fcd5ee509d6b733e7119a8023d9b5e538ea526b64fb286cfdbb85fe16d -dist/2026-08-30/cargo-beta-aarch64-pc-windows-gnullvm.tar.xz=86018bbd5e4ce4a2ed6fe33c520fbdaa1e1cb93a86cc47f8fb8a84f139fbf77b -dist/2026-08-30/cargo-beta-aarch64-pc-windows-msvc.tar.gz=136513f5d9caa1d9a982c5731f07c52ed33ffcca18cf8c76f65b15193788f4df -dist/2026-08-30/cargo-beta-aarch64-pc-windows-msvc.tar.xz=faaa5028d993cfe8ad0c86b03e8ce2718bf20e8cee68d8185ecfa39cfa3870ad -dist/2026-08-30/cargo-beta-aarch64-unknown-freebsd.tar.gz=f9c7edc721b9e36377248325ec7944df39cf2ca005fb02a91a4994d717ad4783 -dist/2026-08-30/cargo-beta-aarch64-unknown-freebsd.tar.xz=581acbb17a497d6b76b99cc94833a33d72e104f2efff7d408d69550f912da462 -dist/2026-08-30/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=33647f90516de973cbfda8c553497ae5721e4412c4aecbdba1af4ff414093ca6 -dist/2026-08-30/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=9741da1d26464d27e5566220ac240ece0c94d95e0458e8e945c1d29cc198746b -dist/2026-08-30/cargo-beta-aarch64-unknown-linux-musl.tar.gz=92e567bb8a7eeee6e001bd47b39263473d69a6591a9e64f9f48736a3ee631669 -dist/2026-08-30/cargo-beta-aarch64-unknown-linux-musl.tar.xz=69bd4e038b62ca7a94d85b3673286fe9a2ff57d4fd750e35cc0f4edf2e74b701 -dist/2026-08-30/cargo-beta-aarch64-unknown-linux-ohos.tar.gz=58627d33a59fcd84a33e71e121f267e675d78a181fdabd8bfd645b0c21e36c33 -dist/2026-08-30/cargo-beta-aarch64-unknown-linux-ohos.tar.xz=4dd725fb1d9eb9f7f1434edf563642dd4357b4622b7990ca835c62db9b26bf55 -dist/2026-08-30/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=86ca22788c633215cdd0ca96986136504dc7525c1d6d12da5d2d37944986ea21 -dist/2026-08-30/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=99f26d926f354f3a72fb422bcd8a2f0b8379ac727d5c3f16b57b433fe9f5d656 -dist/2026-08-30/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=681839287ba9bcccbff125e21f9b1381915ebf1e2748d558cf4ff1dcace861fe -dist/2026-08-30/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=cf1e4cb9ebb5c86ad2090a9f08862fc85ee00f0c0a4dce50df4e688112e2b3d7 -dist/2026-08-30/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=9cd65395b781a22ec66e2e49e78d5a972360c93b5da7ed22b837635c68899a0f -dist/2026-08-30/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=b3c6b3a99f537303f2419cf7379cbdbacb899a956ad0653b0726d558f893f481 -dist/2026-08-30/cargo-beta-i686-pc-windows-gnu.tar.gz=055b916329d7848a521f63cbe6c373a4ad94a36e9c2cefe155283bb67b2c655a -dist/2026-08-30/cargo-beta-i686-pc-windows-gnu.tar.xz=728142c61e80ed2884a41446fb5ef9784ae66c6a5ae01d34548ad3722bf17547 -dist/2026-08-30/cargo-beta-i686-pc-windows-msvc.tar.gz=902d87163289b5f7c8876d79b4bcf6a524f445007afb41478c3d446c47e8efd9 -dist/2026-08-30/cargo-beta-i686-pc-windows-msvc.tar.xz=f8c2377f283109ba8db1d15925ebf549a0297d33245d67efc2f178fbbc13a766 -dist/2026-08-30/cargo-beta-i686-unknown-linux-gnu.tar.gz=acb2edc9a1e93476848d22725017ca6c80906875cb3c3cd5f23972a9a96c109d -dist/2026-08-30/cargo-beta-i686-unknown-linux-gnu.tar.xz=6600fd8770b01333c808210c5fe794cac10f302e4d256d1c76d1ad3b86b2c63c -dist/2026-08-30/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=98b4d2d3c9684c4477cbab01edad84970f9bbef0032249800f48cb4aa6259eae -dist/2026-08-30/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=3ab812af126bc73f9da76ed94436b856b3a5b778a0594773217ede933c136e89 -dist/2026-08-30/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=d5058dc322f0f947bd5b8ac8644df85ff760797283d4cd62a08c6137fb1b31b8 -dist/2026-08-30/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=34dfe36b152df195bf161ebf151e7166096b8cf9581b8972b49b17cd9be6f101 -dist/2026-08-30/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=7402338613366b038279a45a2390a403fd7479cca7e38fae1614e3356b1ed17b -dist/2026-08-30/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=6637409067ce9667b02142a3866bacac5b378a7d3f4c1198ad63b8dd44e13683 -dist/2026-08-30/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=bef6d62721d7cb4a5e8d16b4ce8dd0b64100991ff86e4228ccfd2baef6bc1d13 -dist/2026-08-30/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=ab6ebfc224a8b5732b009ea5fcd082f6765ba92c1912b4507ad6b7020d366f31 -dist/2026-08-30/cargo-beta-powerpc64-unknown-linux-musl.tar.gz=07db627041a31120cb4c416ba8d8cd9497e496830568f06770aaf3bd2388cf89 -dist/2026-08-30/cargo-beta-powerpc64-unknown-linux-musl.tar.xz=c5438cb0e1df9c6dbfcb31d9b578d8421dffea54ce84fbb16619b57eaac22fac -dist/2026-08-30/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=9ec047abc63b03ade31cad80b0e3c247855ebbdeb42081f0e7d1cd0fa2d6a591 -dist/2026-08-30/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=59850205528f58ec1df682519b33d149dacfd34c6820188344166be741b6496a -dist/2026-08-30/cargo-beta-powerpc64le-unknown-linux-musl.tar.gz=b51d3d280d5c7db88697f5cf62a16bdf87debc3a36e169e1613b19c787684460 -dist/2026-08-30/cargo-beta-powerpc64le-unknown-linux-musl.tar.xz=42fed8ea76cdef7ef55cea3f5afa7b65bbbd0f64a7dd91c5128b4d0a459a1d61 -dist/2026-08-30/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=674a081bb7e9264aadd9877cd56e354023bacbd3d7645f47b5e56fd929b2893c -dist/2026-08-30/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=cad87b60d098bdc83f26039d2a7b01cecd72b454414423786e69d7830fbc2f11 -dist/2026-08-30/cargo-beta-riscv64gc-unknown-linux-musl.tar.gz=0020a7c5575ac0aed412219257ac4ed7af155ce4696382ee4a5b20113331b8e5 -dist/2026-08-30/cargo-beta-riscv64gc-unknown-linux-musl.tar.xz=ceb3b28ee22ad4b7e893583774680f5be45be9376fb56d23d48ac6201bc972e8 -dist/2026-08-30/cargo-beta-s390x-unknown-linux-gnu.tar.gz=59836d761c03a77477236199be5b0bd06d2ba5ab1d0f39176e1d7c8434eb45e2 -dist/2026-08-30/cargo-beta-s390x-unknown-linux-gnu.tar.xz=38dd22d489aecdf755bb667b4e79d2cb2ec8b6c2710d01686d600f1273e8d59e -dist/2026-08-30/cargo-beta-sparcv9-sun-solaris.tar.gz=c9df6b1cf54638837c2ab060d81241b1cc9c0fe415927c3df281a6c27a46fa5b -dist/2026-08-30/cargo-beta-sparcv9-sun-solaris.tar.xz=e1da5f2fc4dfa042c2819cc20ec8a7fe223aec9a3632899d83965b69c0742048 -dist/2026-08-30/cargo-beta-x86_64-apple-darwin.tar.gz=466f22d638541dfd8a067ae8b01d1d5ba3fe53e77191da3f3f676d4a90d88cca -dist/2026-08-30/cargo-beta-x86_64-apple-darwin.tar.xz=239a1222ddc7c24648f902799dfd258ae334a37f3f58675e94a62879fa51d302 -dist/2026-08-30/cargo-beta-x86_64-pc-solaris.tar.gz=7623f134d775dc42c669f1f23dbd22415036927efe13b183edfc303003d714e1 -dist/2026-08-30/cargo-beta-x86_64-pc-solaris.tar.xz=126bd01ff0c9bb942e211a8fdf6712199979c35d1b6b2b19bbd2a21fbbea966d -dist/2026-08-30/cargo-beta-x86_64-pc-windows-gnu.tar.gz=bfb4fedc712bceeaf74cf23245fd3efdd68728d77db8e04a32ddc329995bdd97 -dist/2026-08-30/cargo-beta-x86_64-pc-windows-gnu.tar.xz=b703ae1050c9a7ebb6b6ddb0523c59b2e5b38466716346e85e7c63c26588927b -dist/2026-08-30/cargo-beta-x86_64-pc-windows-gnullvm.tar.gz=562f4d368d2d854ac580e07738411afb563373e247514e944bcd98f9967319ae -dist/2026-08-30/cargo-beta-x86_64-pc-windows-gnullvm.tar.xz=f165e4bfef2e6bafeb4825961c0fc41ac7ac23d7457feb444dfb8c1e1e0d012c -dist/2026-08-30/cargo-beta-x86_64-pc-windows-msvc.tar.gz=9a3c7ad87e5f3b98d02167c449437c0aba21d174a6ecfa2f0e4817b8c93ad91c -dist/2026-08-30/cargo-beta-x86_64-pc-windows-msvc.tar.xz=831c421d5c5d187047920ccf7ce76300f4d9e3a36960e347d179f31b08f9b49f -dist/2026-08-30/cargo-beta-x86_64-unknown-freebsd.tar.gz=3dd99be35b587a0334d71bc92dfe15e06ff0a052d66782a2425895684dcfe669 -dist/2026-08-30/cargo-beta-x86_64-unknown-freebsd.tar.xz=e4220bc3ccfb034fb1b40d506c9a9637153c943e0a0f9dea4bd56065df2698cd -dist/2026-08-30/cargo-beta-x86_64-unknown-illumos.tar.gz=98de23e890441294de89857063f2810f81df29c02cb9da755793f78eaa8ca8fd -dist/2026-08-30/cargo-beta-x86_64-unknown-illumos.tar.xz=9dbc424c16bed26b8d2ea662c41f156ef14636cbc2006c36af151ea68c932551 -dist/2026-08-30/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=2d2cdc1af3afe2816da895ed1ef0f27a31ee31f938a9385864c0c8e1385a2ec9 -dist/2026-08-30/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=62bcbf31738317455017be5dadb592ce9a6b937bf61303c30c56d4f6d8f1ac3c -dist/2026-08-30/cargo-beta-x86_64-unknown-linux-musl.tar.gz=32247e6fb942d39444cab2b35ce2b64a44c84b2fa934acb781ea9c682f60f14b -dist/2026-08-30/cargo-beta-x86_64-unknown-linux-musl.tar.xz=8c155d690af2600d9a4dcf00d62b6a5f52524e999d25d02eb873a6ab28f373e5 -dist/2026-08-30/cargo-beta-x86_64-unknown-netbsd.tar.gz=c588c5407c06a36da78587b6ee7baddc72b45ecb6fac9290e333fd0eadab1152 -dist/2026-08-30/cargo-beta-x86_64-unknown-netbsd.tar.xz=09c84a0118c5d533b442f39c33265a04abb72133c94f662654095f984f0e85e8 -dist/2026-08-30/clippy-beta-aarch64-apple-darwin.tar.gz=cc03b3970d8e2f5b055fab29f46e9120fdd520f6db45a6213a699a9a4367997e -dist/2026-08-30/clippy-beta-aarch64-apple-darwin.tar.xz=7c6c789f64225fdc45aad2c8eb596aa679e855abb5c4d79573a458f2da7309ac -dist/2026-08-30/clippy-beta-aarch64-pc-windows-gnullvm.tar.gz=b404caee9abf7e945985ccd5379f0e2f41c3b7dbe6e999d722b55fdf9d08c6ac -dist/2026-08-30/clippy-beta-aarch64-pc-windows-gnullvm.tar.xz=36c9f84de6b071aa5f1c0bae438ae3ef132c4add9d35ee5a69e8a754501b568e -dist/2026-08-30/clippy-beta-aarch64-pc-windows-msvc.tar.gz=bebf9f956d1974779ab06d7bdd25a7ea053811523ba2ff4ae18267bad7c80494 -dist/2026-08-30/clippy-beta-aarch64-pc-windows-msvc.tar.xz=fb4274e7618fe49031cb6f4021a0e7dc4bf1ee8900eb45cef118600c8137ad4f -dist/2026-08-30/clippy-beta-aarch64-unknown-freebsd.tar.gz=79e922d0c5bbd69c86d7a459552e47511481eb5faee8a7a2eb893ccc5f7b6788 -dist/2026-08-30/clippy-beta-aarch64-unknown-freebsd.tar.xz=ed65f1ac492dafebfae2ee367135e1f56f57af9b2d284739fa57b18793e7386a -dist/2026-08-30/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=d4aa6c22318d181ff4ef17f0ef2b8aea6641efac232f8a074cf4948e76c68802 -dist/2026-08-30/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=1d679549e6cb70f5acac81d255aabfbb6afef0c94973747e791f27e1097dfb8a -dist/2026-08-30/clippy-beta-aarch64-unknown-linux-musl.tar.gz=0fecf358ff0e7725ec6df42b194a1912b91b358aad683fc48d36b1768c88042f -dist/2026-08-30/clippy-beta-aarch64-unknown-linux-musl.tar.xz=443cb8a078231aa3bba0b8082cd5f20ce36caee120d1060e8f3cf73fd05d8907 -dist/2026-08-30/clippy-beta-aarch64-unknown-linux-ohos.tar.gz=f8b624585864c6bd679db4d505b8c84d46682b8cccb29fcd5bc5fcc74c7a79e7 -dist/2026-08-30/clippy-beta-aarch64-unknown-linux-ohos.tar.xz=8e09d294c73ff186be62d2db49a06240b6d66c674c81c2471646222a5d607e01 -dist/2026-08-30/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=106efc64c2e21abc149264e3a98c4b836c1430d0240f3489d5605a2cc17760fb -dist/2026-08-30/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=b45eaa6f6586aca7e622c5ad60ae9ec92ddd935dff5d6c94ba3a78e0dc6dc304 -dist/2026-08-30/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=8bb3d211d9d17c5acb2867cd154f3dcecdbfb36d723c05f35d91f2e33ea00067 -dist/2026-08-30/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=08c78ecc4b5489c5480fe6d3832298686f782f9e45bb265946b9bb1176733f54 -dist/2026-08-30/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=1875b1f3c267c634cd48933c98891a53b350f7142462cb56bfc6513326024c89 -dist/2026-08-30/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=a647ca6600707b40a1e97f7fd0e39bf43c863ea60224eb28beee0622f74253e3 -dist/2026-08-30/clippy-beta-i686-pc-windows-gnu.tar.gz=772d98712f108d6d7eb7730e26ec04e66a972daf3ac5352c30160e20c1861ba6 -dist/2026-08-30/clippy-beta-i686-pc-windows-gnu.tar.xz=d75cdb626c3104552b122e79d2ed07bad9ec04f084f58bde332d029feb3ae90d -dist/2026-08-30/clippy-beta-i686-pc-windows-msvc.tar.gz=e7ecdd93739741d769a1fb4ea33b9dd3c935008d7ad5e773d3673d5ea7dbd6d6 -dist/2026-08-30/clippy-beta-i686-pc-windows-msvc.tar.xz=8b1223c943d378e201e83d61298527e2d7307f96ce609c6e1a5483f086490bec -dist/2026-08-30/clippy-beta-i686-unknown-linux-gnu.tar.gz=f326afa8e228964581df0c4a0096eb33fc132df0254b2648f43f6589466e72bd -dist/2026-08-30/clippy-beta-i686-unknown-linux-gnu.tar.xz=7e868c12873c5e451ebdfe67e4474538a9d3f46d5dde8ad4139c8f5056a44685 -dist/2026-08-30/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=e185f345c34e54bc100b1df955c047b53db30b9b3b054a2cf5a264f0e3ae2405 -dist/2026-08-30/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=270c4f7d7763180bfb8a7dea1d97259398c9b7c6560fdd3b58192748ffb40cf2 -dist/2026-08-30/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=22d484c3ae2ade651e12ce943780b51da3b0dd6bf04c6f8403540cc7f382ced0 -dist/2026-08-30/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=a669d05d6efc4e77f05b417d00272f2a0221e05b37f921b9e0f9769a8b48830e -dist/2026-08-30/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=3d782e904a64856dcae5de5d2be509f2ccc3109e9067ddd540bc8e1049ea3ceb -dist/2026-08-30/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=dd867a9fca45df5ee0d3ef602802f8accaf9fcc1ab1fe52b74ea72e03b91d67f -dist/2026-08-30/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=a890aa398977d62b10513350e2c918fb41ffa76a2733b2f08ec829f15b8dfd0d -dist/2026-08-30/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=c8ae48e109ae2f4daf3c878056641acacc457618afe42c9af53eaa4bf9a4faff -dist/2026-08-30/clippy-beta-powerpc64-unknown-linux-musl.tar.gz=010d6114089273e267645340437d74b962c7f16ad21914b689100241e1e5879d -dist/2026-08-30/clippy-beta-powerpc64-unknown-linux-musl.tar.xz=1ff705f8d502081d85e8f85a177b4d00a3f102475c6148f7609040efe8f95cf0 -dist/2026-08-30/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=226cdb2a14e6f7ac8962326d6f0a4459a99d5f43ed6516f296da74a4c96504e5 -dist/2026-08-30/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=6f0d5341554b0b12be7138962ad1f02cf534b197923f791e8489e09c2ec0fa31 -dist/2026-08-30/clippy-beta-powerpc64le-unknown-linux-musl.tar.gz=aa41e1b12199dbe2597c1614908911bc936b77e4697d6f47a73e99b3fc6d3cbb -dist/2026-08-30/clippy-beta-powerpc64le-unknown-linux-musl.tar.xz=f0084a572996014050b886ea7defe6c6f3dbb8055c840c9f3e0f09474f1cd87e -dist/2026-08-30/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=35d0c03ff88bbc60059f1014c65f8803a5e649fcef0ffecf90c73db0b5e29d04 -dist/2026-08-30/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=f2233e50c2c976941b30f41859494c3b47a4a92022b50f924eb3aafbb10ad1c6 -dist/2026-08-30/clippy-beta-riscv64gc-unknown-linux-musl.tar.gz=8f34275dea87439be7c820cf5c239168c5641711e439afe873615ebc26e92f20 -dist/2026-08-30/clippy-beta-riscv64gc-unknown-linux-musl.tar.xz=7346c56c1ff8cadbb633d0890dfea12918344f035075a5ade3fb44869da7ce26 -dist/2026-08-30/clippy-beta-s390x-unknown-linux-gnu.tar.gz=064c99e94f0dd2da50e8445cba0f6bd3b6de9a78f860fde838097f26f93c0a86 -dist/2026-08-30/clippy-beta-s390x-unknown-linux-gnu.tar.xz=b5237ae854270214b81270f1a6dcd26fab19470b98450b8503a1647d83f19d66 -dist/2026-08-30/clippy-beta-sparcv9-sun-solaris.tar.gz=e8cb900135fcaecc87565e6279f3b50db957370b73f7bdaee39401bb2236ec93 -dist/2026-08-30/clippy-beta-sparcv9-sun-solaris.tar.xz=a1315c1d6b3ab19a6351527f07d62bc375d937571af49f1130b030440f96ad74 -dist/2026-08-30/clippy-beta-x86_64-apple-darwin.tar.gz=4adb22b7d502339fa505fe7ecf18167fd7a054e15211d28f78d7f27c05fcfb4c -dist/2026-08-30/clippy-beta-x86_64-apple-darwin.tar.xz=0e9c5bd310a8c6d797cc741a3368c4e18ebdd138fb0035bcec94ca3563fee966 -dist/2026-08-30/clippy-beta-x86_64-pc-solaris.tar.gz=ec8ea5558cd47e0324ab46fc8d7f06b55e3a5b015e1b06f7d8372ef63846e2e5 -dist/2026-08-30/clippy-beta-x86_64-pc-solaris.tar.xz=2ce6978bb89c20fd4d92d9a513c60ed8a4ecf243d68e9ed5e76a06f46374725c -dist/2026-08-30/clippy-beta-x86_64-pc-windows-gnu.tar.gz=269d4722bf8604755727de19c3e92932976797ee07a382a4241d598e11f1dcc3 -dist/2026-08-30/clippy-beta-x86_64-pc-windows-gnu.tar.xz=bd37185b9ea6c75df3fa873bb7bb961ea48cd7eb2e1e537df78fa23560a4e542 -dist/2026-08-30/clippy-beta-x86_64-pc-windows-gnullvm.tar.gz=7a84636be94207fe6bad2a162bb9f412944f07d87e65aaea8defa01500be420d -dist/2026-08-30/clippy-beta-x86_64-pc-windows-gnullvm.tar.xz=6f3cd9590fde49d3d32473d7363b8bd9e1298adb87dbef2fc8ba2aa6565cf7f8 -dist/2026-08-30/clippy-beta-x86_64-pc-windows-msvc.tar.gz=9d33b21d67155a006f8ba2de17892812519ce9ddbb6531656b314c710363f7d1 -dist/2026-08-30/clippy-beta-x86_64-pc-windows-msvc.tar.xz=a6805eaf9f9d0d5d9f98d6fafb4b4e96accfb2676acca907ee704f84745c5768 -dist/2026-08-30/clippy-beta-x86_64-unknown-freebsd.tar.gz=b8e66bc833089b1b23cd0e73c2e1b3409864d2b00c7ba533378b45eba07a8dc9 -dist/2026-08-30/clippy-beta-x86_64-unknown-freebsd.tar.xz=593633c48f833329e86613601cbb4db25071eb19b33a4561f7104c0cba86f03a -dist/2026-08-30/clippy-beta-x86_64-unknown-illumos.tar.gz=dbfa333d2cf958b0d39983bdf3fd2d55623903d82f34d70d06ad31561f51cf97 -dist/2026-08-30/clippy-beta-x86_64-unknown-illumos.tar.xz=53a0ec434ba0664dcd967d02a13daab11c23eb294b3e80befb80667f8983c586 -dist/2026-08-30/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=17a88086e382454d70bf08e33149b8e0ba97a34500b9f56dbbfd9ff4c3fc535d -dist/2026-08-30/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=b0237d0782a9b8938769e85dbbcf1a6eec91554f665b90acf00a60f4dd0714bf -dist/2026-08-30/clippy-beta-x86_64-unknown-linux-musl.tar.gz=2d7ff9aa37dbcfdec585dea69555c973430b7e6f4f6b55e450cb34c05b59baef -dist/2026-08-30/clippy-beta-x86_64-unknown-linux-musl.tar.xz=9ae39943b49d89ef53153b2921fe7dd6ed244acd5e39297ba7cf108c38ec644b -dist/2026-08-30/clippy-beta-x86_64-unknown-netbsd.tar.gz=7c8c9387e3f75a917dd721cf96a118cd8924baae1b476e9da545aa6c4cf06609 -dist/2026-08-30/clippy-beta-x86_64-unknown-netbsd.tar.xz=0d85f1338a69ad620c923bec29c3fcad6225f957578f0a41a11568c154e091aa -dist/2026-08-30/rust-beta-aarch64-pc-windows-gnullvm.msi=99a2ea82e19f436cdf4dec0f0aaf315c16a3229fb6d9b103ee9d1a2c06b74090 -dist/2026-08-30/rust-beta-aarch64-pc-windows-msvc.msi=c0a27c16075e29239e68b31d76946a41a452acce1140c1e509a189c2e3f56eff -dist/2026-08-30/rust-beta-i686-pc-windows-gnu.msi=8f742fd4920a3fcf5d41dc113f885e441f8681d83a745a5b12195c2782a4c93b -dist/2026-08-30/rust-beta-i686-pc-windows-msvc.msi=513fb7fe5d4289ddbb58260863ba3821d2cb2a3baabc0bea1a65ef2885c413ec -dist/2026-08-30/rust-beta-x86_64-pc-windows-gnu.msi=2d9f279983d1a50913e7777de880899143190413292801266b95ac2ed69a4e4e -dist/2026-08-30/rust-beta-x86_64-pc-windows-gnullvm.msi=5bf8e7568a27395a4b879dd6534c141a92cdf12536d1201a175d84453963699b -dist/2026-08-30/rust-beta-x86_64-pc-windows-msvc.msi=23463fbf570caf314427b3ff8e666a2d9b3cfdf7947aced459187eb59c645e48 -dist/2026-08-30/rust-beta-aarch64-apple-darwin.pkg=e933472ceac42d94982728bedda2976bc77da11805a236cd93cab0c159dafe5e -dist/2026-08-30/rust-beta-x86_64-apple-darwin.pkg=bb9d97c74eb28bae220ed548e46b91c478d66301801c51d4d170d45989d24cc1 -dist/2026-08-30/rustc-beta-src.tar.gz=baa6964c75882e0393efbed2f19e8303b46101336adfdf44bede282dae15ef0d -dist/2026-08-30/rustc-beta-src.tar.xz=f835b92620f3802afdaa41fa49de6e253c9db0de0234070833011ce65c14d0e2 -dist/2026-08-30/rustfmt-nightly-aarch64-apple-darwin.tar.gz=22d6733e4325fe6fa25399b651e77cd5ed1a7f370f7558aaa08e8b6447f55264 -dist/2026-08-30/rustfmt-nightly-aarch64-apple-darwin.tar.xz=fcc49f0698c09f8ff89ca044d0426dad2399da253d287c3aaabebf103b4a2820 -dist/2026-08-30/rustfmt-nightly-aarch64-pc-windows-gnullvm.tar.gz=34a0e1f6d068d30cca9099c44736657de307ea3041970fde751aeda3781d02f7 -dist/2026-08-30/rustfmt-nightly-aarch64-pc-windows-gnullvm.tar.xz=8f7955c05e2a5324fba961df617ca2d70d473565cd3389fcd52814e9cd5c4f65 -dist/2026-08-30/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=7df7e3f128e4d4f88a5777e9e736fce117f5f47ef8cb505713aba9db09b8cecc -dist/2026-08-30/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=094323c8a19c6840d13d9e3a1668c94dc249ff0c720634da1fef8cf844cded71 -dist/2026-08-30/rustfmt-nightly-aarch64-unknown-freebsd.tar.gz=bd932f456a46de862f1aa3fc5b936a5e364a714a6cb8b71c7cf3920f180177a0 -dist/2026-08-30/rustfmt-nightly-aarch64-unknown-freebsd.tar.xz=4c14e353f8f5982ba3b3828578e412f433ca3f16e94c9aa0f6efdf2949b53215 -dist/2026-08-30/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=efb14d13c092a4dfd1d2229aaf850cb2e6c56bac9c31ec322e22f515050567da -dist/2026-08-30/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=7df63718528c050a0e306ab08979ca787b6f0522a442d34355cf683f3bb259f0 -dist/2026-08-30/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=b0a231d0eb6bb006bfc144a954be07ed9886202967843b0e8475b19429902884 -dist/2026-08-30/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=b98a8ba107231b4d8832d6f1cb679661e9ee0faf13c81dc3eaa576853580582c -dist/2026-08-30/rustfmt-nightly-aarch64-unknown-linux-ohos.tar.gz=dec01a69341b8d512eb17ec28687b4ee43174de63e31a90b91e99b9eaf17e345 -dist/2026-08-30/rustfmt-nightly-aarch64-unknown-linux-ohos.tar.xz=e598a9559c169794bec2443e7842e62728e09fcaa6614b1a3f5ebd6803f0ef6a -dist/2026-08-30/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=18a5a8ca79e449f7daf52f534cd2ab137e33204280ac7da35e0bd31f6ba2674e -dist/2026-08-30/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=00e6e3d4d555ee786545b5f0a542d7b5bb9260781a80e4598d50bdf856457a4a -dist/2026-08-30/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=421735da37fcf7a85c2bccb27b13c15105f98a95333734c1d383e18b7a01842c -dist/2026-08-30/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=a3936b0c6a67da7180c10554dbe6427beaf05480c40b3a57cc07082085987cc1 -dist/2026-08-30/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=817768d8aae4d3d09b952631982051eba84b889e87367c2d740a14e35261fb4f -dist/2026-08-30/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=5d905fdbcc0d3d2f5949c0e32980172fa8216a51974945248e293f8c81b58203 -dist/2026-08-30/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=e2cae9d3e6b6c6cf72bf0e12510358984adb5f5279f49af8f4a29869614f0a84 -dist/2026-08-30/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=bfb5472037dd5d1031384c70d58bf841ff4a9e33716b55d8384c47d27a31ac04 -dist/2026-08-30/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=b18fa3d4a5469b7736655c842af84ad44a07fbd6146669c6f2b5f5c3f26a4e33 -dist/2026-08-30/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=c7978ac60291efc21bc77c2aed4d14c0bbfd6dbccb461f0499202fe8b8dd0818 -dist/2026-08-30/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=e1e69785fadaa294f92d7f5e42b046a47c4b508a806804048c3c2b1cfcda25d1 -dist/2026-08-30/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=c6371931d1bbc56f94f17d55ef0e8a756388606599a6f8828b1269504b57f0ac -dist/2026-08-30/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=e2763a910eb0305fbad6200fdb70e21c80f6ce61a29c9ef6cfdd134e54fa149e -dist/2026-08-30/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=b8ff26519a2b6087969497e02e1a958b283b2dbd5741c5f9a531bfadb7f55b4e -dist/2026-08-30/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=f83eba99f2c4ca3c8e72debd3abfc81c4e8e12b78f33030a2ec0bca467ff1026 -dist/2026-08-30/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=9da6df6e5b98e59dad134fa7eb6fc74cdd7590799e5d77b885675d3301cb5ae5 -dist/2026-08-30/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=ab48c3b5e6a1c920d2776ada7f2c7a262c6456c70c4051c55f24067768f36011 -dist/2026-08-30/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=d6a6ff842d3004c14a39349c62453b5279085bcf44f2c3f101bba074249b6393 -dist/2026-08-30/rustfmt-nightly-powerpc64-unknown-linux-musl.tar.gz=7790a116d7598a29c083e8defa140b3c69dff2fa8632abe16c0814e3fdceb771 -dist/2026-08-30/rustfmt-nightly-powerpc64-unknown-linux-musl.tar.xz=090ff92dbd36a9d051e48545672099c40917f5cc781fad0075d1db73bacc9b6b -dist/2026-08-30/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=6a448b720e8b8904a7f6b160891dc711165b043aa2f2700f1001220841da7383 -dist/2026-08-30/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=47850b2456b8f28493268987e10ee2197f6bc49517b9338c469346e42c4ea524 -dist/2026-08-30/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.gz=51fa8c6d2e9144b5086ebcd91580a7b2338e42294a0db614c2a5b40c2817f074 -dist/2026-08-30/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.xz=09af68ab10528ac45be29d2d7671a5cbbd0c508d842c811448d1b1a0818e4ebe -dist/2026-08-30/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=4ba0481a7d6111f1197c44f9475ccfe814a32cd13ff218b7a6f96fa6b188dc07 -dist/2026-08-30/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=cb078f0a92905a6ce410866e2c0f93ecdc12fc2b17716e8ab503531b72cd2f41 -dist/2026-08-30/rustfmt-nightly-riscv64gc-unknown-linux-musl.tar.gz=5c8f989fc890a8d40b88d03002819dba392def655ff4a297eae83e24635599be -dist/2026-08-30/rustfmt-nightly-riscv64gc-unknown-linux-musl.tar.xz=ac6a2d15f43100e71a401f334eadc59d76e554fc7e2e4c67870c24f05c7ac682 -dist/2026-08-30/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=78f43dc32a140e6b84c5b50e319b5d779d8d3a6a63172df5b0a7df984cda2919 -dist/2026-08-30/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=cdc738d4e7db3489ec4be89db19fb6beeefedc09f0f99bfc3f4177e5a0e29e39 -dist/2026-08-30/rustfmt-nightly-sparcv9-sun-solaris.tar.gz=8b04309e8d8ed92f52ee9656b0c3b694681c9c867bbadb781c14df8d2f25a189 -dist/2026-08-30/rustfmt-nightly-sparcv9-sun-solaris.tar.xz=fa880983d380d71b52468551aeea00502c04a1c84c1976b82ad137031b63e61e -dist/2026-08-30/rustfmt-nightly-x86_64-apple-darwin.tar.gz=0faa8f222a300d58a8d815a49625202da2c93b89d655de9f8105fac8fa3b49c2 -dist/2026-08-30/rustfmt-nightly-x86_64-apple-darwin.tar.xz=860418646c51c8a4309b5f64700e9cddbaad55edd33776bce10341d069a4842b -dist/2026-08-30/rustfmt-nightly-x86_64-pc-solaris.tar.gz=70dd11166440c56c5d39ad393f22904b0d043c4e128ceed9b35276b1f7c88814 -dist/2026-08-30/rustfmt-nightly-x86_64-pc-solaris.tar.xz=0c0224c46c41018eee3fd6373a3a50869faca604acf5985627a43d381bd023bc -dist/2026-08-30/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=e3ae658cd8daf76fba66422c5b63d335a73c6d1abd0b0f6b88c385467779f876 -dist/2026-08-30/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=372750b8dca20904cc7716f6c999a581ecbf67537bbc1a340226cc4d1cf5f01f -dist/2026-08-30/rustfmt-nightly-x86_64-pc-windows-gnullvm.tar.gz=3edebbe5ca7cc0e9cdac3dbd715caea022c890f2e16dc0798f8517c324dccc8b -dist/2026-08-30/rustfmt-nightly-x86_64-pc-windows-gnullvm.tar.xz=bb6cb837ef4e0355b946a9e8af2d8a4e9a89e06f68f6a0f92adfdf56eef1d583 -dist/2026-08-30/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=7b5a4c70a3223e4987e216f9853833c87d347c5e4daf6328eda4f2e434e3dcc8 -dist/2026-08-30/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=4040814b80224dd9ee4ad051a491c5c7cb345ed41c2bce1070c13faf785cffb9 -dist/2026-08-30/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=529dcbadb35869dd2dd39e4b81929dcd5fc74d983e5544b61e66a663dfc40fda -dist/2026-08-30/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=20c86d4a327b5b227dddd1d9a900f5314f25728b5f1cbbf970d7a8bf2c8b039c -dist/2026-08-30/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=b6951008db1f2b95e35dd207bdf95040bb0bc6875a710a744d81a9769e24f91d -dist/2026-08-30/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=c502feb9fb19f971450201f5d396d9e622169884ab2fa42b14ca4685e2ec485e -dist/2026-08-30/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=76acd957f09291ee38b993aea1511d7ed4247fedeed07b90368efdd4cd216e3a -dist/2026-08-30/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=5a9b8925bfbe5c244e6f1c84ca821bad2227ec374db11f0d593830f2419742c8 -dist/2026-08-30/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=da93547e78b5b8d587e35d15df2eb789ad4f075bb82d4605b5f4abe49b7fe49d -dist/2026-08-30/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=688e31843695905b5e67b2a186fa4e509c860befc70ee533195710f784787b64 -dist/2026-08-30/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=229cd762e308882adbfaee3c50e1a32bf88a3e1c488ab9998558a90716340a45 -dist/2026-08-30/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=47e7a7cf0eebb9c62185e5506ff1aef012709b36c7433181d774b8cd1a75567c -dist/2026-08-30/rustc-nightly-aarch64-apple-darwin.tar.gz=25ffe92502f44e574a72b9493ee0b1a4e0e873c1c931f1a07aa0e478ceb170e1 -dist/2026-08-30/rustc-nightly-aarch64-apple-darwin.tar.xz=9d494a6b72761dee6ec3c0ec085d5b29838565ef45bbb67b097caf0aa4750304 -dist/2026-08-30/rustc-nightly-aarch64-pc-windows-gnullvm.tar.gz=576b8ba2a8aab889df0e673d434402c38d22efcaa4a8cd2f005c01063cd80601 -dist/2026-08-30/rustc-nightly-aarch64-pc-windows-gnullvm.tar.xz=dbd428ee786b17c9a91039a2274e01d1adf14d6af747f78c32d68a62a5752e35 -dist/2026-08-30/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=395f1fd4b0286f70d4d48d5b1aae4a8f7ceb0e0a916fdfb69cbe2c00a1cd31c6 -dist/2026-08-30/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=33fbd7251609d17dcedff1de1d6b34e5aa257411229e9e7c0066d51b3b22d23c -dist/2026-08-30/rustc-nightly-aarch64-unknown-freebsd.tar.gz=954f471480070c222a6316e1646770b6472c007b89f68ea61a713b153210b960 -dist/2026-08-30/rustc-nightly-aarch64-unknown-freebsd.tar.xz=9f19a67717d4710b3e445fbe84591da5fc5be7b6c6f07e5e5bbcf978243c4070 -dist/2026-08-30/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=d1cdfc3cbcb3f131b4307b83389da6c0385f733ef6c68e569f280c1d10bc6a18 -dist/2026-08-30/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=c967d3a8cf286f5197759160f90f823eb82c0dcfbdae4e43580c4e4336fee294 -dist/2026-08-30/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=667e1683c157443a221f00467c927651756a593f5bec5f438b55aaadd740dd27 -dist/2026-08-30/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=e4680cff6ef155809ede44b4c4a5f23ade8f920fd54e877ed93b6166010930cb -dist/2026-08-30/rustc-nightly-aarch64-unknown-linux-ohos.tar.gz=fd6c0c4450fe0b8f586452046c80b424935c1fa83181358c70c19b25ddb0dbed -dist/2026-08-30/rustc-nightly-aarch64-unknown-linux-ohos.tar.xz=b2c7e0cf7f1b71e141b248e62b7d10f0999f48fffcd6dc07318c3205c79ca505 -dist/2026-08-30/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=df20767bfd43a0fd4c5665ab4c0d0f0511b3356918f54b7c3074f6a1b7298aad -dist/2026-08-30/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=c43366c230813ae776aa094e3422a445b4a3d513f98ba6d7b78cb5ad2d0a2a8e -dist/2026-08-30/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=0c0c872b14aa8dc461989326b53c2692b46bc24bb8125d4f90e5b977f5db3bcc -dist/2026-08-30/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=82e0eceb946f0a69f2d766c3fe2a5467852caddff960a66c5fcf9d14fa6daf92 -dist/2026-08-30/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=4783a2cc2a99596fd187bad7f486f97018ffce918c34b4b022fd88f27053c967 -dist/2026-08-30/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=c078badef6ab76e69f0fcbe6ca76f1037cb64d67e5a1feecee898ef6aca91521 -dist/2026-08-30/rustc-nightly-i686-pc-windows-msvc.tar.gz=340b68ba0802676c99da1784b0f03eb9e3cd7f78cf40fa579f97601c07dacb24 -dist/2026-08-30/rustc-nightly-i686-pc-windows-msvc.tar.xz=ac4c0562021b4f3076b39856eb16ab288f3d16d25c557cf954ce66f389449f9e -dist/2026-08-30/rustc-nightly-i686-unknown-linux-gnu.tar.gz=5ac857921af0b1b8d290a059eeb1d510ad4cc5f450b513b26a11be67885558ee -dist/2026-08-30/rustc-nightly-i686-unknown-linux-gnu.tar.xz=a01fb1c1721998e3bffe377a15663e911bcaaf497fc2a7f1dbef06125466febd -dist/2026-08-30/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=46d1aa393ee0f736bf46cb6d8e975e66774a797a78918fc106cb1baf2115c1ee -dist/2026-08-30/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=66ea19498d78291393f20ad6313fdb2359b7a685bb358d28c498042f957b7ce9 -dist/2026-08-30/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=27e138e7e0ecff208f09780f6cb51d4447fb75b5891c2e961c3b380670bf43e2 -dist/2026-08-30/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=16bade7c4f0644f4474622591f1ae83be1c7d6ad86aa23f1cd0bc29959e41555 -dist/2026-08-30/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=44207e156b7d05f8ffd05394cd0a5f2c4cf290e8a7d4be07a95e6242be738f85 -dist/2026-08-30/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=98c9309ccd0bc473ab1c373232c0ad483ce959a9b7b31cfc0b948c0dcff4ae55 -dist/2026-08-30/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=bcaf935990ad326f9469b18514330bb219fac62773b1ca44cfd9f2639e22442e -dist/2026-08-30/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=68242588d61346c4001c4bade2daec0611f3f079fe1d1e5debf08746d8ca2217 -dist/2026-08-30/rustc-nightly-powerpc64-unknown-linux-musl.tar.gz=34e4d626d1e484c3d8bbe2be39a6324b0a02cfc60b7bf13c561e6c41eb6b3917 -dist/2026-08-30/rustc-nightly-powerpc64-unknown-linux-musl.tar.xz=8b35dd518df6b7225dc7b8da30ef9fce97181bf3781e69fbd5fca67833c54457 -dist/2026-08-30/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=66aca4805b3450a90bde12ddf6f2b9139fcab333bf4a33825d9bedf3842fccaa -dist/2026-08-30/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=6861be8d2ca2fe398e461ec1d68eb4b6e5a589b5eb39b60ca4083579a54ccc07 -dist/2026-08-30/rustc-nightly-powerpc64le-unknown-linux-musl.tar.gz=7644e739c1afbe9a7be15878444e56340dbadea64f06799066e8d14c1e736ebf -dist/2026-08-30/rustc-nightly-powerpc64le-unknown-linux-musl.tar.xz=fe4e05894da7fb3bff0d4cc725e0e80dc78fa55d97bbb0588ce5383fdec72407 -dist/2026-08-30/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=e59bb87d54ca41779b984fad84ad20144e4bb224ca187ca6a51ee1d15ec5bff4 -dist/2026-08-30/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=d997aa633692996dac26f68a246b3dff4a597595a08808dd965e01f05bc502b6 -dist/2026-08-30/rustc-nightly-riscv64gc-unknown-linux-musl.tar.gz=3d5692e095f9b23a05aa57b1de83fee4a6ab9ba1ba85f0d6a7a59997814f762c -dist/2026-08-30/rustc-nightly-riscv64gc-unknown-linux-musl.tar.xz=85b6a0d7e0405537ef929819b957a37723010e8cefa82c558a7d0c42e645fa59 -dist/2026-08-30/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=668c203cfeed5b0286a5928d9b98e289f0ec32fbaf21fe61534ac9bb5c9236fb -dist/2026-08-30/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=8fd2005a2f7233db1399af86d9c8b48b959b3627faa5c8a3dde1d6db67f72562 -dist/2026-08-30/rustc-nightly-sparcv9-sun-solaris.tar.gz=d8767b7abc10f45dcc53258adf4ca2c062d3f063f830791b6c475537a7009704 -dist/2026-08-30/rustc-nightly-sparcv9-sun-solaris.tar.xz=58ed2a29ed983d6dc632ea7dd68532fef902dbc44a68e2cd668323fa9676438d -dist/2026-08-30/rustc-nightly-x86_64-apple-darwin.tar.gz=27bd68fc60a35b8f56b538cfe9d3cafe156dba2b8cb25bc04d488505882157b6 -dist/2026-08-30/rustc-nightly-x86_64-apple-darwin.tar.xz=a452c953f1641c6d2ffaf59d129f38b7fa2c6f8c29882c3d82408b50e4c4c95e -dist/2026-08-30/rustc-nightly-x86_64-pc-solaris.tar.gz=c12868cc994812742945591b906f761f9a5ca0d09a809da69f3b0f7de731a707 -dist/2026-08-30/rustc-nightly-x86_64-pc-solaris.tar.xz=9974a6f3bf2b784771114ae846f7fb54746525e5dd921f4832410e40a00502b3 -dist/2026-08-30/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=6ce5a31fd706d532679c5db6bfca375fb21f34df077bd7e182f6e38cfb852561 -dist/2026-08-30/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=72cb129e77c6c8f48e82a82d894a5fdced57d74c8a7ade88589c3baf1385ef26 -dist/2026-08-30/rustc-nightly-x86_64-pc-windows-gnullvm.tar.gz=e896320dd35b2b43943a29491bacfc696d5e68c3c9a7c0a4fbab6cc57ca5afe7 -dist/2026-08-30/rustc-nightly-x86_64-pc-windows-gnullvm.tar.xz=93b8fcf4ed8aaa3a9ad1ed14086ed4bf44cc38db920f86eef0c1f42da37c9665 -dist/2026-08-30/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=5368d930648a6f04b20967d6183e53925bb930d047271b3683cf3d663d893f23 -dist/2026-08-30/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=e696551fc4f4b0573c60750826ee93113a95a4ee7361af3752e49c5a386abf69 -dist/2026-08-30/rustc-nightly-x86_64-unknown-freebsd.tar.gz=c2ef207e1ebd2c408c91a63cffd5986ae01cf265e535947d12bc43a2015eae5f -dist/2026-08-30/rustc-nightly-x86_64-unknown-freebsd.tar.xz=5025d42e80e6d377a9dba466ef3e81ab817ff6e098c2bbde4923afedf0fd7893 -dist/2026-08-30/rustc-nightly-x86_64-unknown-illumos.tar.gz=876fbafdf17e645e870d4b6afcd5465ee155e910309cc91bad10dc885d178b0a -dist/2026-08-30/rustc-nightly-x86_64-unknown-illumos.tar.xz=f380f5b0a7ec8c537b8bd53528b3a407cd69449baf0d6c513f03c2de047ba3fd -dist/2026-08-30/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=4e010b6ff2f3923b31c44cfcd74d33389dd2de01521e4f22b90c58294fa490fa -dist/2026-08-30/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=d87f9b9bc000e028ce81b49d64352c59eccc99cbf282c9c3bc834a72d9aeaff1 -dist/2026-08-30/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=2332302e83712fa814b119bea274fdb1f70494fc7e8ea6a23c88f20bac3ac6fe -dist/2026-08-30/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=2a43c8666489856bf8ce91729c2eeceb88a3d38bc6cacccc8c598373afad1247 -dist/2026-08-30/rustc-nightly-x86_64-unknown-netbsd.tar.gz=094c2005eef2f8ca0e466da77af70f7b1cc6c837e8b2e933c26d66b8bee3e06d -dist/2026-08-30/rustc-nightly-x86_64-unknown-netbsd.tar.xz=a68f04797c3ae9db0e31d9670fa9ce17efd5ca3054bdc4de06ca97b143cb59f3 -dist/2026-08-30/rust-nightly-aarch64-pc-windows-gnullvm.msi=4334c750cc57337150cf11dad2b10c5d65f1866e7f672093550322fa696d888f -dist/2026-08-30/rust-nightly-aarch64-pc-windows-msvc.msi=b2c56f022de67eb6045b1137709a5055c139d88e9fae8175b932a7da1f2fc1d7 -dist/2026-08-30/rust-nightly-i686-pc-windows-msvc.msi=bb18feb2dfdd9495289b70a6bb41584489dfe14de19961fe32fe6d249ff60c7a -dist/2026-08-30/rust-nightly-x86_64-pc-windows-gnu.msi=18d50140987657604cbf1a980b2249243afc6a734f725475a25a3f96c0edf72c -dist/2026-08-30/rust-nightly-x86_64-pc-windows-gnullvm.msi=83cb268a0ee1c120357082f9711d2a5eb05e58d433bd52dabfabfcbb31df6200 -dist/2026-08-30/rust-nightly-x86_64-pc-windows-msvc.msi=b19b6e4ef4b022f183c45ebba60ea8b6bcbcb06c60345231fc602dc1aae0ba5a -dist/2026-08-30/rust-nightly-aarch64-apple-darwin.pkg=2fa1f66fd223a57405047c498614d71fd3bf087a98063e2f652c9899d2a5960a -dist/2026-08-30/rust-nightly-x86_64-apple-darwin.pkg=20a2d983a8ef414f2c61773f056bed1d300c24e5f65252c1a0b01fc230030e28 -dist/2026-08-30/rustc-nightly-src.tar.gz=a1768b2d3627caf5f7fbdf5918fc1586180a7a2f2076403d1cb4ab11ea3eaec6 -dist/2026-08-30/rustc-nightly-src.tar.xz=b03a014a5a4f8bb1d0fb14d9f01e3a5cb9df64c4d4208463f4a6b977d2287d9e +dist/2026-09-29/rustc-beta-aarch64-apple-darwin.tar.gz=08cb5170859d6ebf335c279df46cd8421e6478a0199d0cd2709c0afbe8a92dc2 +dist/2026-09-29/rustc-beta-aarch64-apple-darwin.tar.xz=5ec30352066404071c4c9a077e19b211e1e2865babec422c1b5305882fccb2f8 +dist/2026-09-29/rustc-beta-aarch64-pc-windows-gnullvm.tar.gz=24630c62a81890608c84b0c5d1ccba809c7414c9cfa6737b092bdcb3defb6797 +dist/2026-09-29/rustc-beta-aarch64-pc-windows-gnullvm.tar.xz=b9db7c497276274a7e5af4ae6666d4d77bb9ebe8a389513c1628488f4f86b950 +dist/2026-09-29/rustc-beta-aarch64-pc-windows-msvc.tar.gz=75b429e1d1f34317877ce3838e4e5c79ea579a051314fce9755ecd92782031e4 +dist/2026-09-29/rustc-beta-aarch64-pc-windows-msvc.tar.xz=04fb7d879ff7b00ed5cc3a054bfd8f4dfcbcc039c1000334db34284b6b7d0d27 +dist/2026-09-29/rustc-beta-aarch64-unknown-freebsd.tar.gz=4a4ece6cb6b686d844d3d93c6b5cc50dcc6fd1a2aac17d7ff7606cc3fe103980 +dist/2026-09-29/rustc-beta-aarch64-unknown-freebsd.tar.xz=2bfd413768c42feade1655007488e4cb913fc5b295763dd7835224e5a57ab198 +dist/2026-09-29/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=c60b31aec10e123a0c461b6f86b0f7d18dd22e706abe76ed4d9ea010c76e1fc1 +dist/2026-09-29/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=ecc23a873a11fcbe2b81e47763204f93a1f91e551c0fa8766262ffa2cc3d0538 +dist/2026-09-29/rustc-beta-aarch64-unknown-linux-musl.tar.gz=1634c9acebc04a266987633062e0db4d4b5a92a568ae55cb146cffba8108038d +dist/2026-09-29/rustc-beta-aarch64-unknown-linux-musl.tar.xz=4361c19fcc2cf8e26bb52489e7dd3e96500c6e6d54bbeaa1493d0b8c8d6a066e +dist/2026-09-29/rustc-beta-aarch64-unknown-linux-ohos.tar.gz=318e6fae90b8da5cad5eea22d358b848746a8f4fcf60d164a2d630f03d12facf +dist/2026-09-29/rustc-beta-aarch64-unknown-linux-ohos.tar.xz=7d80d8a51de0f9a8f0af2ac170e5156a14dba2f3952946a845917f772e9c7dbb +dist/2026-09-29/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=7dc6dcfa998512791269d52f9ee0097bfea867c3a02a54c676c88a69a40f8a23 +dist/2026-09-29/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=b791b3ed832746088ed4ec8378f9b226a7900c4fd4cbe6436f7425191ef1013f +dist/2026-09-29/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=0a1bab07aafcc98cbb130b81b3ad9eceff1194037110fc8ed7fa6650a572ab07 +dist/2026-09-29/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=677ee4e95a57d1e498ac4bd9ac05084675c03c58de6e85320d7d6d0c725e6ebc +dist/2026-09-29/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=e7de0b8ec0715ee54866b533f22ffe23b560e58884228f145e0458a3dfb0450b +dist/2026-09-29/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=6316b4bc4931c2811c90d7dff9df5bf7875531c6cf985c065f78b8a0577e370f +dist/2026-09-29/rustc-beta-i686-unknown-linux-gnu.tar.gz=8229d9b5bb6497abdedf15731c15c2ae85c8050bf0995a576685716e9d929ac8 +dist/2026-09-29/rustc-beta-i686-unknown-linux-gnu.tar.xz=428ba34f2281ddbb794a2062e446ca6e5b0cd90a84829186f769bb8d2190a28c +dist/2026-09-29/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=04ab37c4e7e9dde5a2332975b6f7cfe6c02319e89f9bab2128945656ec81110a +dist/2026-09-29/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=50d6c00c82dfb7f10bd2c49057822e082c3bc1f6cb7a08e06ac2a5a350e1d1eb +dist/2026-09-29/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=9fc8d551462b4a845c18f163c2787e256d00d4edcaca0721da63ab57002f418c +dist/2026-09-29/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=ce74c12908e44b8b87fdb371533b6a81b5cbc8967e04209b833c87940f4a1420 +dist/2026-09-29/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=e7417324e10e59b5768daa4b5cd01fe92a624739a9b450693fbd5902227a3561 +dist/2026-09-29/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=68dbbc9c7f6c1f2725140c0edd58e3607cd31d4406e7514cb32b9a894f3af39e +dist/2026-09-29/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=93b02c260b6ace5ea43fd716a100abfb2ed3de24a53e3032794c35858fb0f618 +dist/2026-09-29/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=e78037526d62c567cb2aa1336c0ed2bfde01e2948833c10a3585040dcf26f343 +dist/2026-09-29/rustc-beta-powerpc64-unknown-linux-musl.tar.gz=3ee5c15579228dc36bef6b254fc235ff57426be8dba7bb358beaed0f1791afc0 +dist/2026-09-29/rustc-beta-powerpc64-unknown-linux-musl.tar.xz=053fbdbfdce20029dedadf7218daabee5b181a69c20b46c2849970f9fa91a7a2 +dist/2026-09-29/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=a0d9ad02f3f031d54080f3a64f97d099f38de9b324e3906ecd9f873f8353167f +dist/2026-09-29/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=8a81d01e78892fbfadfb22b59c6264bcaf4343e36afa806d94b2c6f51eedde43 +dist/2026-09-29/rustc-beta-powerpc64le-unknown-linux-musl.tar.gz=5780592d8b617c2a2b3c1a0c142e71ba589ce5a6ca8d05840668ed9b0217e807 +dist/2026-09-29/rustc-beta-powerpc64le-unknown-linux-musl.tar.xz=e71f58d7383c5ce823ede7d7d032349a3616ec3c3fcae212786b24ec4e427fcd +dist/2026-09-29/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=3f113901c2996c2bc39891cc6146fa4c2d8800029258186805b20a34dac0ab13 +dist/2026-09-29/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=2b7bfe0f71378a76c4b5bc04224f728c02b0cf21d66999d86a33b754ff80b52a +dist/2026-09-29/rustc-beta-riscv64gc-unknown-linux-musl.tar.gz=b4e6d98741d7293f16ab9218e5492664765f43cbc7f8537b45ef6815ca83b0bb +dist/2026-09-29/rustc-beta-riscv64gc-unknown-linux-musl.tar.xz=98141ecd5a1426d8b168e5f181bacf083150895e446840d2243747159bdc3773 +dist/2026-09-29/rustc-beta-s390x-unknown-linux-gnu.tar.gz=5b821594334d8f9b1d07264df899f22fe7a041d7417618b8e7809973fd45ae22 +dist/2026-09-29/rustc-beta-s390x-unknown-linux-gnu.tar.xz=5c52006d530dbd13711e01402dc533c1d664f77e4f1c997179b900ce29ccc617 +dist/2026-09-29/rustc-beta-sparcv9-sun-solaris.tar.gz=7db0a06f0450e2f47ebae3912fff144d416cfe58877ff8996d1335af634bc7db +dist/2026-09-29/rustc-beta-sparcv9-sun-solaris.tar.xz=3d8c85b04fa3d1947840867c5ffb750ae341ad17982aca302abc754e43e1ff42 +dist/2026-09-29/rustc-beta-x86_64-apple-darwin.tar.gz=2bf2b522df594f578642b9c1670b265a02b937b48b5b47ace32a53ad7b569200 +dist/2026-09-29/rustc-beta-x86_64-apple-darwin.tar.xz=ed18e8348eba7bbc6adfd6b95292d802834022a243bd9739cfdbc5d69d8e7e2f +dist/2026-09-29/rustc-beta-x86_64-pc-solaris.tar.gz=cce6ce17920028ed75d83134bae4e02704bf497002b654ff629dedd8294a8335 +dist/2026-09-29/rustc-beta-x86_64-pc-solaris.tar.xz=6d5cb6a91f23044f79c73954bf392989d031412e4d6b43e18d4256d7a3c1fb0c +dist/2026-09-29/rustc-beta-x86_64-pc-windows-gnu.tar.gz=efea45514b6313626db60fa3e922fbd812454004c34c79e3770050826da93022 +dist/2026-09-29/rustc-beta-x86_64-pc-windows-gnu.tar.xz=5a32405ad9ffe040516efd73d961ca53f89c1cd8b4bd8eadb900caef8303e0c3 +dist/2026-09-29/rustc-beta-x86_64-pc-windows-gnullvm.tar.gz=6e911af2547846c6baa414b7d85288d954293df34b5cc87805aa6bb06570dc48 +dist/2026-09-29/rustc-beta-x86_64-pc-windows-gnullvm.tar.xz=e1ad982eccf000e89da01d6910cf918d2231e3cdcc3738f6696d3d57dfa5f353 +dist/2026-09-29/rustc-beta-x86_64-pc-windows-msvc.tar.gz=fd2d7a0809aa431f3f2365f6a98901f359514d47967067c936ba68bc47437d5c +dist/2026-09-29/rustc-beta-x86_64-pc-windows-msvc.tar.xz=ea968def39864e80a462e6be752a7fab2a8c9da7f14799b138ddf0e9bc1f534d +dist/2026-09-29/rustc-beta-x86_64-unknown-freebsd.tar.gz=87deb753d7a5af1afc02cc988d23ea0d42a9573b5e9abbed23ff8f345a91056e +dist/2026-09-29/rustc-beta-x86_64-unknown-freebsd.tar.xz=2dbaa50d6542748cd31dc9f13d4fb82874825634f027317b830121937b583d76 +dist/2026-09-29/rustc-beta-x86_64-unknown-illumos.tar.gz=f682c3ad10ae60d43e2a54a3f624782c9ef0ae61fb0e9ed95a867794e0bff256 +dist/2026-09-29/rustc-beta-x86_64-unknown-illumos.tar.xz=0ad43335ebc8b0d1dbdaa34aa53fbc0cba9a8186b5edac080f5a7bf7ed7cde7d +dist/2026-09-29/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=c567617a07be89de49b009162604ef9bfe4bc542419d405c444e39714591f4de +dist/2026-09-29/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=e562beb9a7ccda3e99c79b2f37149fe5dacdb1f3bb7bdb77ec94b1a947daf009 +dist/2026-09-29/rustc-beta-x86_64-unknown-linux-musl.tar.gz=cea2a33fbacd6b80a7e19592a2ca8f58eb1613589dbd8c906ae78b5723cebe6e +dist/2026-09-29/rustc-beta-x86_64-unknown-linux-musl.tar.xz=e0a1889de08bc4c91006e1d335ed7215257de80bbf6bae375906021ada6dd95b +dist/2026-09-29/rustc-beta-x86_64-unknown-netbsd.tar.gz=262db7c3e54259876fa7f03775b73a5f190cd4812060feac04c13a03db1c5343 +dist/2026-09-29/rustc-beta-x86_64-unknown-netbsd.tar.xz=547adcdda9c63d0f63f8351dee197ca843628bfb1f965e8305f947ca128a2f69 +dist/2026-09-29/rust-std-beta-aarch64-apple-darwin.tar.gz=12a712c301ab944900438c0da63b45ec133efea74b398e708faed172e2960042 +dist/2026-09-29/rust-std-beta-aarch64-apple-darwin.tar.xz=d9705141deb514ad2d721ae34174c33ab5b64ab7181294886cbbfdc3f9b999ae +dist/2026-09-29/rust-std-beta-aarch64-apple-ios.tar.gz=3a65781d05da1559788ea8bc2df4d84f12fdc4194cfcece0863ce786ead5ec13 +dist/2026-09-29/rust-std-beta-aarch64-apple-ios.tar.xz=728a2be2bbbacf3866e007d92b9f0857a9b7da0d0c47c16e296fba25839afbf4 +dist/2026-09-29/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=b445edeeddab84fac96c089d73f3a87e485415583ddbff217092058c14c79c9b +dist/2026-09-29/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=db73dd68d6a0458b7ab9e49f2e331a460f14eb4598af19f2a6f642b85db3c947 +dist/2026-09-29/rust-std-beta-aarch64-apple-ios-sim.tar.gz=09d2bbd7f44f6245ff9e7ffdccec0a491e9195075232cfca2f247329b0371aa8 +dist/2026-09-29/rust-std-beta-aarch64-apple-ios-sim.tar.xz=1faee83ec196e8a2876c06dd5377a542aac1aa32c7d3b00ecf31a3713b50555c +dist/2026-09-29/rust-std-beta-aarch64-apple-tvos.tar.gz=e8d1cd23d78eacb8a4be5cb465b94902b5351573b4c0a47073205ec4c8028397 +dist/2026-09-29/rust-std-beta-aarch64-apple-tvos.tar.xz=42f013a0c3ad79263d651b194dab7b08734f6a96dd5943535706f4a8990ca819 +dist/2026-09-29/rust-std-beta-aarch64-apple-tvos-sim.tar.gz=a5381d8ed927c6e1c720833462898ca6c4bdae6702e308352f0dc5698e3fb93f +dist/2026-09-29/rust-std-beta-aarch64-apple-tvos-sim.tar.xz=6ffd6d6d7bc230e28a78f7230b0b91fc71dda6af018feae186b0eb48910234c6 +dist/2026-09-29/rust-std-beta-aarch64-apple-visionos.tar.gz=90a82a478d671ed7269f7cfb5eeaa70cb914d9424dd741c7a2ad2b4a26840b6b +dist/2026-09-29/rust-std-beta-aarch64-apple-visionos.tar.xz=1c700b45a80f7304fe00977cb2fe46975ce16ac31494f2e5afc825465b475d02 +dist/2026-09-29/rust-std-beta-aarch64-apple-visionos-sim.tar.gz=50113f0e4b4cbd8c528978a6ead8fc3fcf15dc6b1c4bf97488a61da8d9245dfe +dist/2026-09-29/rust-std-beta-aarch64-apple-visionos-sim.tar.xz=fbd9564bbdd9d0d43fb00fe67a83fad16a58d4545982344bdbacad93dd53b110 +dist/2026-09-29/rust-std-beta-aarch64-apple-watchos.tar.gz=6ba080aa355f112b74c180ee6ef1ed182bad260f35e4816bf22f758af1782286 +dist/2026-09-29/rust-std-beta-aarch64-apple-watchos.tar.xz=979686c0acca1dfe4bbc1906bbb7dd268b90b9aac3dd97a06f105fbc3260f78d +dist/2026-09-29/rust-std-beta-aarch64-apple-watchos-sim.tar.gz=4d3459fa110abab0d95e1748f5426f162d746635529839d88360dd7c186a9a0b +dist/2026-09-29/rust-std-beta-aarch64-apple-watchos-sim.tar.xz=303623e7c027952c164dae9e8662c1141914a35c7af148de8e7b0cd813594384 +dist/2026-09-29/rust-std-beta-aarch64-linux-android.tar.gz=cf7c1de2dbdfd3ac05131e63cc6285c5d76e8ae85c186350a164ce1017a6a1c9 +dist/2026-09-29/rust-std-beta-aarch64-linux-android.tar.xz=790d34c2a756240cad1da2662132eb11ffa2b3e844ba639c3561aa5ba0d3ae97 +dist/2026-09-29/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=dde06b88182f2f6bad4d7b2cfd40a99ecccac1fdc2dee3ef5e65f425e706484f +dist/2026-09-29/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=f901b2689461d3b38b5f2eec0a6f5c6795ee3638da97a433c1fa84ecff11a082 +dist/2026-09-29/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=943394d1133a8c82da94d97ae738472666a9ae4f2d04c504171d8bae34a13f21 +dist/2026-09-29/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=6777866c103e45b453d7ad36d3addc3bfa09684b6e6e4abe18ea5ef782ade595 +dist/2026-09-29/rust-std-beta-aarch64-unknown-freebsd.tar.gz=5b2e8bf0dfa7a5be26a3d969c708e5181149982877a3d571d75ad2c118b56ef8 +dist/2026-09-29/rust-std-beta-aarch64-unknown-freebsd.tar.xz=b5146618aee2bdeea3f3da4c6afe4b07d6b8af0440f6d954985973d12dc7ec9e +dist/2026-09-29/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=e92c49005a09ba23a21cc74364f30769997f7b6b81c2205ee7e9d9413fb38fb7 +dist/2026-09-29/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=fca1e29e1856abe923cccef58d560074d2d5adac5211007c00e0657677ea7f57 +dist/2026-09-29/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=9d02af2c761d752a1371e301753a432031984cfaf53d9812c8ce540bfbf6d716 +dist/2026-09-29/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=e991bfc2818af00b53cfac0535d094135712339b8f1289186a6d0f8d209ff351 +dist/2026-09-29/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=405f757b12a00629b2f2dfd0ebf3c372d257047fd8ddf348088ed78235fc0e7b +dist/2026-09-29/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=c8dd6d868b2f6b316433bb1849a809450bae0fab9305c60b2123816066e69d71 +dist/2026-09-29/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=4fb73dd34675a6f27b6426f58ad7be879ff49ab8e98c3ce003e49651bbacee4a +dist/2026-09-29/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=a89e58073a28be60905bb7647f0e60b4520639f5460cfc3c6f1e25c581939864 +dist/2026-09-29/rust-std-beta-aarch64-unknown-none.tar.gz=b7bb5e2d07dfb49786bc1f9de858c3a41a6c4723df4e48152905616867389617 +dist/2026-09-29/rust-std-beta-aarch64-unknown-none.tar.xz=0c0fc594ad1d67be737ec709d3e10ed319d3e5a4263d1951a9bfe664bd2504b3 +dist/2026-09-29/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=25ac7161cf32dad13f4bcefc64cedb25963f4f61995e9531650c8a2636536263 +dist/2026-09-29/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=440165cb33ab38c651e798c0ddca0195f36f7ab6de981c37b4f41c98c2cd6f38 +dist/2026-09-29/rust-std-beta-aarch64-unknown-uefi.tar.gz=b5ba39fce8b242d9f77fff252e0da2b4a8d455929d247ffeb522d063eccc3253 +dist/2026-09-29/rust-std-beta-aarch64-unknown-uefi.tar.xz=16915d999525cd8e1488d6378ded9c11f58b0390e2a03f0dfb89d32b3d2339c6 +dist/2026-09-29/rust-std-beta-arm-linux-androideabi.tar.gz=e1d3999e6ba68470df99c7836ce8c51232fb62785ea7c96c6b2a456d468655f2 +dist/2026-09-29/rust-std-beta-arm-linux-androideabi.tar.xz=c23e03c5eea7fc437413e6d539ffdf43bfaf2f00d9f13db2e4d789e3edb31527 +dist/2026-09-29/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=db082f4b98dd53be4f32b618d5494ec2fc2af75ac571d7aa1e93edba18ecf30c +dist/2026-09-29/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=cdd51373266d628735f876c8acab3d658f1ec54fca4ef76511c45d7d555d598e +dist/2026-09-29/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=62de66b7ac14a2d8b725be25b5f6af6246973ec5557ac631cff594177b1db726 +dist/2026-09-29/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=fb86b6e2e3b556a63144c0cef982c200e2bca8d2d0a1db4b1374d0c7724107bd +dist/2026-09-29/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=0f64d408c08361269324e8cea25053c5f542bda8b7afc5393a497808993254ea +dist/2026-09-29/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=b05ec5e82bd8c93ceabbe2578dda16076e4b87daf315dc5baa54c8abd4e52ebf +dist/2026-09-29/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=2effbb32422491890eb626dcf181cfb30499ba26c4f64d4a96c9e304c22dcde4 +dist/2026-09-29/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=24bb014666bfadb3256c390b36c2369a324077036eb2cc1c6e2be825d6e8d278 +dist/2026-09-29/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=932df0b6c8289fb46a9f056b70921a4b1b9400c136dd45c0561f190802d10c1b +dist/2026-09-29/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=fcf67570a855d2e396f0019492767c8fabf00b20ba614c8e00ee9c987fb06b31 +dist/2026-09-29/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=4805f236f0122d3a67e736031b2b530e9c1c4d7a1cf65039d7118d50985fe033 +dist/2026-09-29/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=3ae97148bbabfee58ecd7db754eef720a084685d6df918713ee9103126f8b96b +dist/2026-09-29/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=d5bc909741d6dabf577c4d26e9570e66a4fe0f7a253c61364f57bd3adf11c4d8 +dist/2026-09-29/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=6bb41498459ce565e0c91228c41c23ba326cd4d964bb5554866cc350d30d2381 +dist/2026-09-29/rust-std-beta-armv7-linux-androideabi.tar.gz=04be64de9a88dc5fad743c7c9e3ece7ffa88fc8f6741bc7097011dafc3af867c +dist/2026-09-29/rust-std-beta-armv7-linux-androideabi.tar.xz=87450f7a9e275eb7dfd67e78eca210d867ce06e338b8a53eda0e5eebb2930b85 +dist/2026-09-29/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=9d2c987cf665bd8490e43e66611cfae292c5bb74aacf7d36129cd71cadfe06dc +dist/2026-09-29/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=0533fdb36d2e8ee0b1bf5274e000f7876ade0f6c6a289a4014b97bc41eb4b88d +dist/2026-09-29/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=f6d92ec41459b974d5a1058b079560737261d263f218fa74982fb3d143117e02 +dist/2026-09-29/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=b7ea4246a4a35d36596edba6f808b351abf99e0c861abfc5623d7a7cf2a125e9 +dist/2026-09-29/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=004e933e4e1cf4c3bde0cb189b22c71bb58e84e9f9d0cab9288d46744c529b7d +dist/2026-09-29/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=ceed6092180912b2e6bfa95cd7345d2a0da20aced84ef1626ee9945fa109b950 +dist/2026-09-29/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=4acecafc1bec8a97b67206557e340d6de7fa3f6a39baef49e704e203798f12b0 +dist/2026-09-29/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=b79c57d00374db2f33708752d0c0c1ded34c9282c1a14b7a155f5c8ef49b96fd +dist/2026-09-29/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=2fd30887db6155ef25f02781322e79b6b69113f282e89b68e119677a3cf6c526 +dist/2026-09-29/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=9d65af3b8227e2096f3f78cfa2207241d226ceacd6c5559d2ad682ab156c6842 +dist/2026-09-29/rust-std-beta-armv7a-none-eabi.tar.gz=141612e58714918c93ba2769723712e577c99e19b6d858e77d8677850e2dcf85 +dist/2026-09-29/rust-std-beta-armv7a-none-eabi.tar.xz=2bfe5040c6c62fec4e863428288baa735fc581ac2d7ff4a180b51e169db0f291 +dist/2026-09-29/rust-std-beta-armv7a-none-eabihf.tar.gz=5014575869a7ecf9c6a6c91cb69b97f6fb798d3836f0c1851a5a9128d380fc42 +dist/2026-09-29/rust-std-beta-armv7a-none-eabihf.tar.xz=84dd449ba61513a783e10ccdc4b40ebf02db42a435f306690f945b59a9b38274 +dist/2026-09-29/rust-std-beta-armv7r-none-eabi.tar.gz=bcb61efdf77fc8a3ac756a2989cb29e57519cbba6cd86eac5eed42799e6dab98 +dist/2026-09-29/rust-std-beta-armv7r-none-eabi.tar.xz=0cbdb7ea8c7c9505a3b8a9d055704d736ea9be344862ef3f335d4abc27bf9d21 +dist/2026-09-29/rust-std-beta-armv7r-none-eabihf.tar.gz=422ff4501a710a25cdc6569428320beff61c2840872af2d63dde98543cd795f6 +dist/2026-09-29/rust-std-beta-armv7r-none-eabihf.tar.xz=c26f216ca75b5ab3c9e837a55c6a0faa7ffc3a348125e6dc545def1ad92582b3 +dist/2026-09-29/rust-std-beta-armv8r-none-eabihf.tar.gz=44b08082e62a1469c30956d9b3c82053bf341cd15b36a9ad634d0b9061cb2702 +dist/2026-09-29/rust-std-beta-armv8r-none-eabihf.tar.xz=57eccc6e20abd4d9a95bbe0095401d8b64fca6829e11a0f4f0b4977bd5466b8e +dist/2026-09-29/rust-std-beta-i586-unknown-linux-gnu.tar.gz=c98675485760784593bfcc1c1239ace93b05a90649a37cf40c78ec76f54c9b6c +dist/2026-09-29/rust-std-beta-i586-unknown-linux-gnu.tar.xz=25c25743a6bcbdcf35b6a055b5bb4a7c3af73074bca1923d3b97dfb5b87d51a4 +dist/2026-09-29/rust-std-beta-i586-unknown-linux-musl.tar.gz=5f0a8c43f055eaffe5efe71b62f0ba276bed1afc158efd29f10b5ea064fcd881 +dist/2026-09-29/rust-std-beta-i586-unknown-linux-musl.tar.xz=5d73bfd5f7115ec5e67b07c0e978f4aab9e8f79adee879e917b29e01fb78ca76 +dist/2026-09-29/rust-std-beta-i686-linux-android.tar.gz=7cdb05e049ea8e32fad2cea069fa98181d5289dcb2d6322e5dc80d151ef31b66 +dist/2026-09-29/rust-std-beta-i686-linux-android.tar.xz=e127f07fd97a7fada184bdee50aa83002c7764d6a0b320aa10d6b2bd400b2786 +dist/2026-09-29/rust-std-beta-i686-pc-windows-gnu.tar.gz=3f9713c9e37aafd3ce7c825ccd9a145dd9c975841da6de6f0ce340ae2381ad24 +dist/2026-09-29/rust-std-beta-i686-pc-windows-gnu.tar.xz=ec6e784cd6d3dc3e76857654621a4072193945668287b9d7665eb5105878bf0b +dist/2026-09-29/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=c174dc7ec2ef614eb6323f06e655eb86266c0b81e1d644e5e093d58af7806f5d +dist/2026-09-29/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=ac9f8789b013c8ece9ba57a56bd05047b8b7134c7f3f13e616bca2b592ca5ab8 +dist/2026-09-29/rust-std-beta-i686-pc-windows-msvc.tar.gz=a4b5db143623d75352bab8f5154583b0ee8f3a4886062e9bd79675e956e528d7 +dist/2026-09-29/rust-std-beta-i686-pc-windows-msvc.tar.xz=cfde62235d503f2906d0aeb21a07b479d3765a4d6bff10c1e54fbd557937e089 +dist/2026-09-29/rust-std-beta-i686-unknown-freebsd.tar.gz=d7bbff8b33fd5d247a8bae9a3c83f879777c65651babd1cc7515c52668b0f43a +dist/2026-09-29/rust-std-beta-i686-unknown-freebsd.tar.xz=a22f726246f417641f5feda6ed2622749e375d03d11bb1be57072d74e286ff68 +dist/2026-09-29/rust-std-beta-i686-unknown-linux-gnu.tar.gz=0d90d3e128d0f378c4b8d948fa65e6d3f42c9eda9da023e9218b6d62cb3442d6 +dist/2026-09-29/rust-std-beta-i686-unknown-linux-gnu.tar.xz=5e78729655a70c60fe5c49a32a7f09418a720f7623d512dd260d04ad52645b8f +dist/2026-09-29/rust-std-beta-i686-unknown-linux-musl.tar.gz=1e10e1e648b38e1e5d102ba87c374937ee1eca7abf53d4abf4421c74e2583283 +dist/2026-09-29/rust-std-beta-i686-unknown-linux-musl.tar.xz=a716466a78991384a45d0f27c73a3268e4f1f709d27ea32474100a8cc9ac5736 +dist/2026-09-29/rust-std-beta-i686-unknown-uefi.tar.gz=f5168879aa790d8a823d98865b2abed8683ad998bc46cab8f92b3cb046c0b442 +dist/2026-09-29/rust-std-beta-i686-unknown-uefi.tar.xz=414e0fc0ff74ba42765954390114a14cdfb261dbcf82ffee03509421ac8b13f3 +dist/2026-09-29/rust-std-beta-loongarch32-unknown-none.tar.gz=f651fea2e64f49fb75f74e7b4a350fde8391808ddad903dea20f8af4e4f848b4 +dist/2026-09-29/rust-std-beta-loongarch32-unknown-none.tar.xz=cef214987ba5cff11f8a5c75b11a2bc4fd3be236e23ca98308addbdf83529232 +dist/2026-09-29/rust-std-beta-loongarch32-unknown-none-softfloat.tar.gz=1a2f03ff61944e81dfe485129f96084a8f0843da76ce62287bf6a70500f5644b +dist/2026-09-29/rust-std-beta-loongarch32-unknown-none-softfloat.tar.xz=39f6bd3be80e0ead123e2ac706d5da15e2c76a7fa1994de40817692d82bb7714 +dist/2026-09-29/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=5012a90d4f9fcacbdf003f151cd6f3316defcd2283514526102834bbd74a8c8d +dist/2026-09-29/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=b8d1bfd9c839ebc6b7c90b98b0be907f6246e69fc92eb48e85db4ed6c7dcbe0b +dist/2026-09-29/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=6569ec56c5f6fa26aff9883603cb9453504854fee82878b25b1b0d2cc9935e6b +dist/2026-09-29/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=2b087399ddcface9b4466a915bf99077adbd8849846498016d57a61c48236d5e +dist/2026-09-29/rust-std-beta-loongarch64-unknown-none.tar.gz=064352424fbc4bfb9637b2a5e45c7ac39d4c2acf937a48f5c8b71cc3b24cb615 +dist/2026-09-29/rust-std-beta-loongarch64-unknown-none.tar.xz=1f3bd23cb2fd4444efdbc15637a05ca8adeb18b2dfecdc5281ca92fdab40f6a1 +dist/2026-09-29/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=cacb51b0256f0f30722f8b69c4cafaf79dc2e9d561ca4990e00ea450a49626d1 +dist/2026-09-29/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=a6c1b71975918d172cf47017a2636a29814297ae79f80d223a83ac0cf17770d7 +dist/2026-09-29/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=e8f0efcb638b971d12ff73cc32422ce944cb2816022dca9d875f1eae938319ca +dist/2026-09-29/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=b40bcea95f0c915cf154ffdcbd1388156c2d3c1734b4b00e192869422dbe170c +dist/2026-09-29/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=efffecff9289cb117cdf4e3fed6126b45a3a82040e0d5f44101ed52f0b38f274 +dist/2026-09-29/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=e12f25ed25788772becf9f44bca4e88eda5a1f21cf17f08b09cdfa728f90a764 +dist/2026-09-29/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=e032b20d3f989cc8c74478871e6dceed4ce3fe3d0a7d232c15b8976e679f870c +dist/2026-09-29/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=82e13804fce4dc6a36832873db80d5a4a43d9d8aee44c40c33c30a88227d5d44 +dist/2026-09-29/rust-std-beta-powerpc64-unknown-linux-musl.tar.gz=20a1312d8c162e7cb26ffe9ba89fa50cc92f4ca4bfa862e3bf2a540d3718a3d6 +dist/2026-09-29/rust-std-beta-powerpc64-unknown-linux-musl.tar.xz=6c2b3f2b17804994388a18f443470049bb63a785852456b27eac2a3320c03b31 +dist/2026-09-29/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=b02de7909bdcfb397a6714fee31031f7039c129fcbf831816d12957217fc9c7a +dist/2026-09-29/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=a8d21a1e9f410be453757ca441d1872cec6a4c92aef1ea2111b4ee4a126a3db3 +dist/2026-09-29/rust-std-beta-powerpc64le-unknown-linux-musl.tar.gz=44be1a79c527831221deedfcfb0e0afd0d8c772102b90286dd9180c6f102dff9 +dist/2026-09-29/rust-std-beta-powerpc64le-unknown-linux-musl.tar.xz=d2305657826fd51a2c6480d8aa3d5fdf92d0f665770a83ee4c0f7f9ed0f0de65 +dist/2026-09-29/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=f1c9e1c8dc22a6f1d784aec5b24922976972c1eeb56e7d587650e22d4eb0d601 +dist/2026-09-29/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=7aaa2bde1cd84c38b13d24dafa47ab9083339795cac996437f41c7510426a562 +dist/2026-09-29/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=f04d393d79727af08de12ca7d13fd41ec78120e3bcc30008f684508edff0f2af +dist/2026-09-29/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=04c8d324b52253354cd7907693bce663b300c075f10a9a0668c29956a8cf8a24 +dist/2026-09-29/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=2a8d5ffd86d7cf52d942933725653c6147ececd7f19a5d1ffee654a2cd1b8bdc +dist/2026-09-29/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=5399870b58683f7d4d35b80c7079e959a092ced21e6b56969a9e9c67e82acfde +dist/2026-09-29/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=6693b6d5032b92eb844e4c7dfbd7f251dae9a13c8af74aaff015c9258367c292 +dist/2026-09-29/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=cd1f07d5a147eb17ff4b6d77a9a9fc567d46a47ec00a1ae15d8ca0d48f12e5bb +dist/2026-09-29/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=e783e12d4436d0976053f3c559096b4baf6f5a02d222c45f3cb40f59fbb91f53 +dist/2026-09-29/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=00564a08fd47392352f40d4b375a7ca565c8fee14f553bd526dbd88f049ad9a3 +dist/2026-09-29/rust-std-beta-riscv64a23-unknown-linux-gnu.tar.gz=731b85413ebe28cad585e028bc77b78869e80ee0714f01b5e6a913d452ab6cb9 +dist/2026-09-29/rust-std-beta-riscv64a23-unknown-linux-gnu.tar.xz=25902d5d514f10984a67301e6281b7e7fae38af2d95879c1ae730485068e3d67 +dist/2026-09-29/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=a776dd47f9381e67c9fee75db18df84cc2faf51d8691d23c393ea1514f257bbf +dist/2026-09-29/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=9acd29f728562348bc380cc112cf56709ffd62e499d52e5ac9c0446a8c1731d2 +dist/2026-09-29/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=549702f03471fa57abd4b2d990b716fbc87274c8d0386afdc4ccadc7bc4dceff +dist/2026-09-29/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=574bd2d37d0c13be91082d9633af161ee3eb7572fd72c8959cc744672723cd1b +dist/2026-09-29/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=1c52932e910cada292e4561fb2d469d75e48369292475a67221a49e80b06e0f4 +dist/2026-09-29/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=18c6df09267c26b5f5c3d55b0ca108aeb1c6cc4e286461baef7ad126f5ca208e +dist/2026-09-29/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=3f42e1e761b319b3e348396c87c3b79f67783081b2ee0acbfcf72c29a5409fc1 +dist/2026-09-29/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=f5fe44aeb22ad3c00eef4f4a1bac56436ba59bc9336b901d88c0f781032dc954 +dist/2026-09-29/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=88b170bcd8d3e26d422bc8ae7a525d8969878434acdb60c4d8f75ad4a6f5fb10 +dist/2026-09-29/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=5cbcf61ee88f021d7570f360971a4781a48ace118b6c2047a6d71b6928ec874d +dist/2026-09-29/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=5772cb9750380f03ef47f1502e82ac790237967d7dd2e3de2eaf6fb0fb723df8 +dist/2026-09-29/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=5f2fcaf8b81c370443b53989dd12f3885c299fd8009aaeefeafb63ffa8c2dc40 +dist/2026-09-29/rust-std-beta-sparcv9-sun-solaris.tar.gz=4bcae41b9149b8d7d3a968b7924fa60ca15ff014c997dffddf1073e3c756a48e +dist/2026-09-29/rust-std-beta-sparcv9-sun-solaris.tar.xz=1bcaae45605a3b9bc05265d48e4bf46bdae9d3a45c6e4cbab4de7df0ec76b73d +dist/2026-09-29/rust-std-beta-thumbv6m-none-eabi.tar.gz=c8668ef20b4a6bdf393082067ec753b9e7e7fdcb4215bfa159a8394e70ac62bf +dist/2026-09-29/rust-std-beta-thumbv6m-none-eabi.tar.xz=6aa054160722c4f887cd335f5e5549afe289f04e7abc5d6df95769a83be453d4 +dist/2026-09-29/rust-std-beta-thumbv7a-none-eabi.tar.gz=b28bd0f5ffebe62f944a3c5f17a9a73eab5c990201ea6961d530b769a69f8d3c +dist/2026-09-29/rust-std-beta-thumbv7a-none-eabi.tar.xz=ce529ebc58e8a757bdab3aee87d34a0c06dd59feca3b708aa97a97b79ca176b4 +dist/2026-09-29/rust-std-beta-thumbv7a-none-eabihf.tar.gz=bc94dbbfe23cf6adf1d34a8a6421480854eab76009a0d327d597f84c83c597d6 +dist/2026-09-29/rust-std-beta-thumbv7a-none-eabihf.tar.xz=96bb2b46a7b11d85ef347e2561730fabd1f56cbb334b5b4ebe8fd0a60fc980ec +dist/2026-09-29/rust-std-beta-thumbv7em-none-eabi.tar.gz=988b9a2c797874a96a155b152d2704624eea46e3ff76c9ee31081708661ee390 +dist/2026-09-29/rust-std-beta-thumbv7em-none-eabi.tar.xz=8c64f7dc6ac9d4b35a5683f6324cff0e1bf136b63dc7b0341f5b15570cd6ff37 +dist/2026-09-29/rust-std-beta-thumbv7em-none-eabihf.tar.gz=35fe10b86edb438efac8d9bb37992dc42758f84b82945fc5c115294c1645e997 +dist/2026-09-29/rust-std-beta-thumbv7em-none-eabihf.tar.xz=9ce5331218676dfe1cee5e975a7e9c56c30e051e4999cf4d7bcc89664aefbb60 +dist/2026-09-29/rust-std-beta-thumbv7m-none-eabi.tar.gz=d268977a2462bc3f8ee3a113965417313c8ce91de44700701bf89a1f485c1261 +dist/2026-09-29/rust-std-beta-thumbv7m-none-eabi.tar.xz=02cc4d5a04d190245b154769f6bf691ad82b2a37d5b6dcff98d25218f4da6508 +dist/2026-09-29/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=6b5025117edb1c0f6e2a519d7a827c257371bcbfe8c1cd2cf194fd8e808fab18 +dist/2026-09-29/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=f6ee4b5ee7439a71c1ac02c428ccafd739fb59e4d7743c73218472c99d54747e +dist/2026-09-29/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=a1a6e10b069cc010dc0d25d33e39bf09d2e902ba824951571b1ff6272c406a30 +dist/2026-09-29/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=1e5f603944d9a1565d7ec648298e126a8d039ca8112bc9f5f8c4e6b2bfbe6f40 +dist/2026-09-29/rust-std-beta-thumbv7r-none-eabi.tar.gz=36c4b0a0bfe975883763666d3cc6562ca9f98e1b8623dc6fb1d341390669b511 +dist/2026-09-29/rust-std-beta-thumbv7r-none-eabi.tar.xz=d087749ff3a16e4577ae93afac8635ce614cfd56c68d2f01e939a33ee07ee5c8 +dist/2026-09-29/rust-std-beta-thumbv7r-none-eabihf.tar.gz=fff03b17250ffc7c328b68b542d293da4d81ae16fda76b53ca87d2dbe03a9fd4 +dist/2026-09-29/rust-std-beta-thumbv7r-none-eabihf.tar.xz=e47e298a4f5583c447056566b2c559af073387024d74822d4f7d657396cbb842 +dist/2026-09-29/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=6245b71146c9bf6892f87d36505f8f8b019f925a93e9e7382fb4c11ed7b92921 +dist/2026-09-29/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=1190208ca7e613923db504b2f452c87f631934a9ff69c212824ec15e03a45a58 +dist/2026-09-29/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=e2ae5641572df4bb08906d2b6e7f739eea79278333eb0c5547c49b0727c56dcb +dist/2026-09-29/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=fe005ce3e6d13722a8a20e3ab668d44848ec97a3d7e275b74d60a84d8e421ee9 +dist/2026-09-29/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=a53f0858a9105a0e1c675d7662838fa849266d19ce5e0f6a35f72e1d3c6d4294 +dist/2026-09-29/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=f229db4fd00f6995049a9e6e3cec6763dee8ce10daac63bc522013b121bc4973 +dist/2026-09-29/rust-std-beta-thumbv8r-none-eabihf.tar.gz=341a7f6420319fb33970a0904144734539e605a2323dfbf2b91169e53aafdcc8 +dist/2026-09-29/rust-std-beta-thumbv8r-none-eabihf.tar.xz=2f3cebd916bff44147582514eeabe207c693cdd5e058febe7d86e8c5c87ec598 +dist/2026-09-29/rust-std-beta-wasm32-unknown-emscripten.tar.gz=e8b45a1e9bc3b54f1047a1cdaf9f6b8af3a6750413e4da81d69f0590a6137348 +dist/2026-09-29/rust-std-beta-wasm32-unknown-emscripten.tar.xz=5c20fdc9b9429f2cf72b11e31fc401d81a5deed37f7bd15627d81db5f834b57b +dist/2026-09-29/rust-std-beta-wasm32-unknown-unknown.tar.gz=0796808b38d7517a28cfe7ba3eba5ecb037242a9abcc26390e1f1825467c7977 +dist/2026-09-29/rust-std-beta-wasm32-unknown-unknown.tar.xz=44dbce1c52229c875f22d98de17a78260892e4759b996e989d96ca58f22ea89c +dist/2026-09-29/rust-std-beta-wasm32-wasip1.tar.gz=79a9003e337d684054d8c6859c2118da6992f4ac7eeb8bebb790b763294902c0 +dist/2026-09-29/rust-std-beta-wasm32-wasip1.tar.xz=7d0bdf81bdfea1bb40a17055aa3077b0b7afb214a6826a92a462ac9006b6aafa +dist/2026-09-29/rust-std-beta-wasm32-wasip1-threads.tar.gz=1721f8d930563486f9f90572797b910643b4b0d62f1d89f90114568401d3da68 +dist/2026-09-29/rust-std-beta-wasm32-wasip1-threads.tar.xz=dc0968859fba0cf6ac6e2b50cb53b7790529e23e008a8407aeeb72b9939fa2e6 +dist/2026-09-29/rust-std-beta-wasm32-wasip2.tar.gz=f57b56c42f272d0daa2a8dfe5e0dc16d2ec696a820037bffece1cacdb664232a +dist/2026-09-29/rust-std-beta-wasm32-wasip2.tar.xz=e82fa595d0ee89331a1f862efd487beac1d29895f8eb061ad6b6d04049ebdb9c +dist/2026-09-29/rust-std-beta-wasm32-wasip3.tar.gz=6abca32199fc1bd072ef19d69c9884efe3dcb07c81d0260faa0ebb17e94617cf +dist/2026-09-29/rust-std-beta-wasm32-wasip3.tar.xz=f019b8b140d81aa18a01dff20170f07a381908196828870d3b4dfcbe915f9d34 +dist/2026-09-29/rust-std-beta-wasm32v1-none.tar.gz=777b38934c1f0e70e39e2fb55f3424f8dd77c54ad49c72340ba20cd4307d49c4 +dist/2026-09-29/rust-std-beta-wasm32v1-none.tar.xz=4c78b7da12168bb42a4df10aa269b7a5218eb086ad203e093a87c84f64b2756f +dist/2026-09-29/rust-std-beta-x86_64-apple-darwin.tar.gz=232d6824004015f32bbbb285c872030bdaf8bbf36cd259494f24f2802cac399a +dist/2026-09-29/rust-std-beta-x86_64-apple-darwin.tar.xz=63bf0f85ed80e97cac13f2edc54826829867b62b1758565c580a0680bf370bff +dist/2026-09-29/rust-std-beta-x86_64-apple-ios.tar.gz=23e8e77b11c0870bb486fcd76cee15db11587d3f47df20f220d69a46640ddd8f +dist/2026-09-29/rust-std-beta-x86_64-apple-ios.tar.xz=9f556cc01cd4abf0949c23f1ddc4209d7b92cdc1d521cb22403a4258eac0fdb0 +dist/2026-09-29/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=d5e6bd07a5aa5346c1294d851466579d567ce1d1db16f6b9a40c20619958c8d5 +dist/2026-09-29/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=c3d8808f3b17c81d6de7a8ee2486b5a837f67069e51ad29b0a3c2fa4ebaf4f0d +dist/2026-09-29/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=72d8b973a20da182acb65479a067be9b4e8fc4e7f7eed41deeac27f8e2401737 +dist/2026-09-29/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=ec661a7156e6baab75839b55377d270a1151e6c432420683ad5a082571f37a77 +dist/2026-09-29/rust-std-beta-x86_64-linux-android.tar.gz=06c09a6a5e54e4da413cedcf0a178107f2d6cfc8082903b262a5db6c807b4a44 +dist/2026-09-29/rust-std-beta-x86_64-linux-android.tar.xz=d36c4d48fa72b2313ba29fc757c505e8a11c712cc779eda7ffa5062b2646907e +dist/2026-09-29/rust-std-beta-x86_64-pc-solaris.tar.gz=ca8ce15a7ae374cc46fde55808a54f94c197bcc9bb40448df06e09cef1257dae +dist/2026-09-29/rust-std-beta-x86_64-pc-solaris.tar.xz=f7c2208dec2c25805546258a81d361f250672ea51e0891254bee9f3c3f4e95ff +dist/2026-09-29/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=b8632646f82535baf39460a3a6ed6a6a92e33f31787efaaf4e6d655225c4f5a8 +dist/2026-09-29/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=ab6729530be4e5fbfa51e76f53f4dcf9c974e0ce6ed11556e8aeb831b1aecdc6 +dist/2026-09-29/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=c76571599f894548491d95639bd75f551a3c614e8dfcf34dc6b38e1d3bf28474 +dist/2026-09-29/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=52dcb526a8ddeaa6081809401ff94a733128a5e4adf9feb1671744ca1134d817 +dist/2026-09-29/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=84c55c99e3a783136cd334db0fcd6cb6e6cc6d3fa997fedc87dd7620e094ca5d +dist/2026-09-29/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=d7c46a39c354ca67f2197be455db7f3817cf35f476b8fac5c85e16c911cd291c +dist/2026-09-29/rust-std-beta-x86_64-unknown-freebsd.tar.gz=46331daca0d7bc83edd687190817d7b7b62f14fa037d9dd56c32314d10e1df29 +dist/2026-09-29/rust-std-beta-x86_64-unknown-freebsd.tar.xz=ac315cd71f957e6b555f98e7744bedf32ae06cecf8a688594d16dc11b0409e14 +dist/2026-09-29/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=5ac6db26e1298837d5d660ca24be108c9fe569784ddb2061dd8b7afca06c4a1a +dist/2026-09-29/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=0ccc6aa8a3746d143515882a33254fa67cead1e58fc3dbce191769f59fccb635 +dist/2026-09-29/rust-std-beta-x86_64-unknown-illumos.tar.gz=9547382b596806f8460bffd1fba4b21c87a809744b678d1379c821288256bfb7 +dist/2026-09-29/rust-std-beta-x86_64-unknown-illumos.tar.xz=a52fa0165572f08d7c0807b618b8841c9220065ff188095bdbf4bd4e9bb11771 +dist/2026-09-29/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=b8eaac057b7b4197941904f539ef4e01eb93daeaedd8b158b5a0a2d8e370ea26 +dist/2026-09-29/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=9095fa52e354f1441568af9e3a9839b16268f7ae7707fd4bc48b2a2bcd1d547f +dist/2026-09-29/rust-std-beta-x86_64-unknown-linux-gnuasan.tar.gz=956b82298d2f2c7e34e28d157ba41945d39865a23b9bbe20678d7ae31aa825b2 +dist/2026-09-29/rust-std-beta-x86_64-unknown-linux-gnuasan.tar.xz=3ecf190a1c53ee9aea39f643ac62923835379f08f6503f4134459ebc5f610a08 +dist/2026-09-29/rust-std-beta-x86_64-unknown-linux-gnumsan.tar.gz=10576f120a98f153c7a68e62a565a92424917a36fe3cb017f4a657e236b3ff88 +dist/2026-09-29/rust-std-beta-x86_64-unknown-linux-gnumsan.tar.xz=a009b119cc0d811e070dc329cf241b8b509d9a297faa68c5d2216b4e21f5ac50 +dist/2026-09-29/rust-std-beta-x86_64-unknown-linux-gnutsan.tar.gz=8d9aab19bea2b6b07f11e9a2bdc0058441e6f80f4d6e778c03cb5b52854c7aca +dist/2026-09-29/rust-std-beta-x86_64-unknown-linux-gnutsan.tar.xz=3507d9b8563db110eaae0253c5c041b62d42508696f1526b94b92fd28e200b14 +dist/2026-09-29/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=7dc3b370335b15345dc9f508c4f132d00a69fdf0feacbaaaaa2f93bd7cbf9ce7 +dist/2026-09-29/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=b8b24db68ff29f15c52fc70ee12cc6d10bcd65259c521876fb08892c8f67b980 +dist/2026-09-29/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=13da2b408f85665b37c6ba519cc4fbf8eeacae1dd6835f22edd800fa229d6f56 +dist/2026-09-29/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=61f986574cf89a091fc6563c0cef458e1c5618444364eb36751194b2da7f8da9 +dist/2026-09-29/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=48d5e6ffa8dc7319809a13ed109a8c5e43e9b17d5e6c9e88a57ec160068caae5 +dist/2026-09-29/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=962cc03687830996b02c8419b4f948b94b7f9b6c40a918212bfa9ba8a3186aea +dist/2026-09-29/rust-std-beta-x86_64-unknown-netbsd.tar.gz=93c518fd23ffc00d69f37e38b90033d76091b3946ee7ec82d906b78a4f7130e9 +dist/2026-09-29/rust-std-beta-x86_64-unknown-netbsd.tar.xz=a8922fe96c323e6ccf587a70841651143065e25d2ce465dea5e2d9ffb52fd42c +dist/2026-09-29/rust-std-beta-x86_64-unknown-none.tar.gz=4df5d869a75e754e1952b73fa78a4722fca53038325dd0e541887e8d0c8a7620 +dist/2026-09-29/rust-std-beta-x86_64-unknown-none.tar.xz=c37467acf1d25eaba261edff55a410a0104dd31b90f8158b10b6f2e369a6d9eb +dist/2026-09-29/rust-std-beta-x86_64-unknown-redox.tar.gz=8d245bade3f0fd036e16314190cf3a0ca535c75a4c97277e24135a9e76815156 +dist/2026-09-29/rust-std-beta-x86_64-unknown-redox.tar.xz=76392bc2afdd60a591b3114fb191deacf59388c21fb1d7ec1733f2f561778648 +dist/2026-09-29/rust-std-beta-x86_64-unknown-uefi.tar.gz=b17e48ee19a86057a7ebaeadd697a4dc86853cf9e66c4981e5043de9e3ce1c00 +dist/2026-09-29/rust-std-beta-x86_64-unknown-uefi.tar.xz=1cd2a4b32284ffb4d11bcd3fb561578f3d00c763c704a177e113af6899c22d0d +dist/2026-09-29/cargo-beta-aarch64-apple-darwin.tar.gz=f3066c859807c0ab69429ea69362654e18c21d26b2c482be436280bfad4b49e2 +dist/2026-09-29/cargo-beta-aarch64-apple-darwin.tar.xz=0bdc913f85f762ca2af5c9bd2d72a31865c102bc66bcc43250a7eae06208de49 +dist/2026-09-29/cargo-beta-aarch64-pc-windows-gnullvm.tar.gz=e2bde3311142eee8c4d822ff838778cbd2ef7d7f496f4dd4a0237756fd16964e +dist/2026-09-29/cargo-beta-aarch64-pc-windows-gnullvm.tar.xz=1c26e80d1529c17cf4ef6025ceb63490cd862ca9eb7c21fa043fa89d2ee1f0ff +dist/2026-09-29/cargo-beta-aarch64-pc-windows-msvc.tar.gz=2b71fb86fb57894c2fa83ae53522783fd9b5b654332ae7623eca3b153f4136e8 +dist/2026-09-29/cargo-beta-aarch64-pc-windows-msvc.tar.xz=5a8b4e3db041cafd58e59333f872cb1020f385d54269ea02ca7ca8a4ce45796a +dist/2026-09-29/cargo-beta-aarch64-unknown-freebsd.tar.gz=12d98333d9d48a97a6cf0bbb9b01cd4a215a51feaf81c5ddb4ac54ce3644814b +dist/2026-09-29/cargo-beta-aarch64-unknown-freebsd.tar.xz=89fc6ebdf93d553fc957a1adac94f9d83feabd5c84c364aa875f36a4d274e31d +dist/2026-09-29/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=173043d8b96bbd8149de521da3271123895af497379a278a87039cef644f5245 +dist/2026-09-29/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=69eae56c755c9d90a1e35d38e22d43b46e204913d237c5c2ea9001906a273db5 +dist/2026-09-29/cargo-beta-aarch64-unknown-linux-musl.tar.gz=2590e51b526f771cc486a2ca15f89c7ccdf878bce18c7e03cf32b6116ab5483c +dist/2026-09-29/cargo-beta-aarch64-unknown-linux-musl.tar.xz=8d1325965495214ac2894aa9062255e519397eded66a32e71b871eeea81dd930 +dist/2026-09-29/cargo-beta-aarch64-unknown-linux-ohos.tar.gz=e18bfa187c668f15f48aa36fcb29d71791577132e829334dd3ac05d5b7cdd7f4 +dist/2026-09-29/cargo-beta-aarch64-unknown-linux-ohos.tar.xz=fc3d7339b87792efe262f8f0685bc97c42bda4ee21541d4d0719e1ba1fdba4a5 +dist/2026-09-29/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=25a23eaf8af21d465d2b0ca6461281702c10339d968ff226e0c63dc6bf9950ae +dist/2026-09-29/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=7544dd758d44668e985e93eb777bccead5f63bf98326ed7e003d2a68a59d4c4f +dist/2026-09-29/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=016d2a04723930c835f7564bbf460978ec2ba9f497c5b94c6665ece36989aefd +dist/2026-09-29/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=4a40079a253cb349e41148b919b7e460e5eb6c659089dc4366c32cb343dab5c8 +dist/2026-09-29/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=36b8677ec6fc857af1777e2f4a68c2cbe90a72b21f9afe2b4221593a76cd3748 +dist/2026-09-29/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=816e1c6b3bdaf08b24514331b972d864a6b7bd8d63479fd154dd1608ac66f26e +dist/2026-09-29/cargo-beta-i686-unknown-linux-gnu.tar.gz=f374e9858d5d4294e9007986d4df7af0d15a57bef5862c289b818c3bf7bc8299 +dist/2026-09-29/cargo-beta-i686-unknown-linux-gnu.tar.xz=ebaa11b6203e20cb0a612c53aaa9a0ae5c275795c1737c4bebebb679cdabb485 +dist/2026-09-29/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=e6816ee73290cf376b402ad6470eb2b68004a883b1b4294393a8966d7bdf1aa0 +dist/2026-09-29/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=b476bcd327cd838606b8482381c6fabf0ce97f518e3ab11b35a50827f2b18b51 +dist/2026-09-29/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=b83080fee58cb9e72db9c8ac994724ff3a5bd2b7039eabbfa0cd9bc77d2d4532 +dist/2026-09-29/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=889717547ec4cbb80d7f2d2e35b1b2b512c3e450ffa56a1bc27289fe285898d6 +dist/2026-09-29/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=340d7ff13760dbb32148c8616dd7c7246870a7f091bda102902589a20dc8c2f0 +dist/2026-09-29/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=29c10897c335e4bd2dde7848bf67bcc93b96e5911888524d0abb8704fb88a629 +dist/2026-09-29/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=62fe339183294cdd58c5c90a6a1dff3a388dc2b054f2ef46babc127cb1dcaf11 +dist/2026-09-29/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=18ce8044103b232c245c8ad3ab92073a473740a897506c69f79c406b611263d1 +dist/2026-09-29/cargo-beta-powerpc64-unknown-linux-musl.tar.gz=fa3e4a74e3bcb12816049d51dcbd9103fd2136679c509b47b4a64f38686c46d9 +dist/2026-09-29/cargo-beta-powerpc64-unknown-linux-musl.tar.xz=d5efafc560f206af8e32d6a720c923e74443af1e5e30e8e9a5a06a38b2955534 +dist/2026-09-29/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=07a1eb729d565b322c3f65d925cb98f125d8c031ea390e5537208fc831cdb627 +dist/2026-09-29/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=fae744722b6f92d00dcf4325d1f5c7a59dbf3563f53318e772ac48ec330c7d2c +dist/2026-09-29/cargo-beta-powerpc64le-unknown-linux-musl.tar.gz=95e91adc5af521f58650ab88707c870952be0492e913c96df8dd3a816449f242 +dist/2026-09-29/cargo-beta-powerpc64le-unknown-linux-musl.tar.xz=d46a64931a0ff96ba7c80f3fb3edceee803d86458c72255b5037857e0ff86de5 +dist/2026-09-29/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=05a6b30d13367ee0f13295ebad1ab19c41d6ef7e0658971b4857e2b423d04ac2 +dist/2026-09-29/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=d64db7e154194aab5d689236a545e3a2f657a67339c0eff77581be6f1808e6f1 +dist/2026-09-29/cargo-beta-riscv64gc-unknown-linux-musl.tar.gz=88adb1c494bc36bc577bb13bae1efa5051481cfce96249c4d340ab7eca017c17 +dist/2026-09-29/cargo-beta-riscv64gc-unknown-linux-musl.tar.xz=8347b2a940db92e3af2c11208ad77c337f5dc856960656c179e19c2b17a161b5 +dist/2026-09-29/cargo-beta-s390x-unknown-linux-gnu.tar.gz=79070ab2fd6d93d37a1cdd11d24a1de15a887d5503086f1e64766a99796decb3 +dist/2026-09-29/cargo-beta-s390x-unknown-linux-gnu.tar.xz=b64e4cca016d3ffce2b1e6944cd249d4e93eab689c0d9cced01a798bc7e183e9 +dist/2026-09-29/cargo-beta-sparcv9-sun-solaris.tar.gz=fc1bfe106843c3b7f0affa77de936dfdb8b9f5a438176d9037aa0533e9b9c8ee +dist/2026-09-29/cargo-beta-sparcv9-sun-solaris.tar.xz=9e12971574167eff3830526f10db3e21cb817f4b28acdb10c42c7689cc2f9656 +dist/2026-09-29/cargo-beta-x86_64-apple-darwin.tar.gz=97072e5a8006d0a8932983a44b1dc0a7b56d46efc76fac6378315f43cfb2c556 +dist/2026-09-29/cargo-beta-x86_64-apple-darwin.tar.xz=d296336efa8cee66a03655cbd66e64709866fe98bc2aeabfdff88039b74eb800 +dist/2026-09-29/cargo-beta-x86_64-pc-solaris.tar.gz=96832f53757943d1c752dadb11fc122af8085317017d7263b73d413029ce9b1f +dist/2026-09-29/cargo-beta-x86_64-pc-solaris.tar.xz=091cd84168e3c9dd860bc0df58d07def0318e470c3459cd431fed713c0ab2616 +dist/2026-09-29/cargo-beta-x86_64-pc-windows-gnu.tar.gz=f99a145aa7938be5baae99302858b680e2c2ae3dd84e8434cc38de374967deaf +dist/2026-09-29/cargo-beta-x86_64-pc-windows-gnu.tar.xz=5bd7758064d9500c68fcfdd5a3a851d4dda40d3c870a83b9a70c93b46a8c8823 +dist/2026-09-29/cargo-beta-x86_64-pc-windows-gnullvm.tar.gz=06494aceb50c8bf0131639c52c62746b07ff2143b04d383be6f137277397a0ae +dist/2026-09-29/cargo-beta-x86_64-pc-windows-gnullvm.tar.xz=5923b97ac130c29f6f0ba96fdbf4b034a452a9d03ae78d8bd812e9d3eb304a80 +dist/2026-09-29/cargo-beta-x86_64-pc-windows-msvc.tar.gz=26736efdd0b4e09dd8e7ed421881fcd39e588b31c45129c011bd78d83e42c153 +dist/2026-09-29/cargo-beta-x86_64-pc-windows-msvc.tar.xz=9e72a3172d9638143bbb51c9cecfce7dfbe463644ca3e90cfbfb04a30561ed93 +dist/2026-09-29/cargo-beta-x86_64-unknown-freebsd.tar.gz=e9b9ecfda5fa944168f81c12ebbe2c127ab245f867d61d47197ae23ca8eb9c86 +dist/2026-09-29/cargo-beta-x86_64-unknown-freebsd.tar.xz=e7359e4d2a6e0ff4ac99fa49346f1e2ee4c64487bb2f35ef0b75fc497bb676bf +dist/2026-09-29/cargo-beta-x86_64-unknown-illumos.tar.gz=bc5382bc1853388dc1573f464bfc3393f41293b159826488b0096ce1dd87582a +dist/2026-09-29/cargo-beta-x86_64-unknown-illumos.tar.xz=46867f0df7b6b95f13598267c5e17a96aff1de929ea2b23fbedb30e7b24324da +dist/2026-09-29/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=dc8dcdee80d7034b0ceadb64fb15608c7617022f4c0be595bffed3326f1bc7a8 +dist/2026-09-29/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=6ed534d029be58d7c0fcebaba581166fee81167de58806540d9d6ffb0f68836d +dist/2026-09-29/cargo-beta-x86_64-unknown-linux-musl.tar.gz=ccace12c5ac38d428e107faf94c7945eeff7f72058910fe93f6514234feb0aef +dist/2026-09-29/cargo-beta-x86_64-unknown-linux-musl.tar.xz=03501cfc18b5dd937612ee76fbd57ded962da245f87aefe3bfa4f332afd9812f +dist/2026-09-29/cargo-beta-x86_64-unknown-netbsd.tar.gz=384f90d70932ba9babe4f9baae008cdf52ef7815a0052b7b6c73bece3f024aa6 +dist/2026-09-29/cargo-beta-x86_64-unknown-netbsd.tar.xz=3c4e43e90a741f1e10409b3cbe426ebe3d3506ad7196eb291c55c4ee060d9e19 +dist/2026-09-29/clippy-beta-aarch64-apple-darwin.tar.gz=aa278ec430f7939b2eb5da177a7e3229b92105ee9e7ad71d8ba7f04cf6f41a4a +dist/2026-09-29/clippy-beta-aarch64-apple-darwin.tar.xz=3929ed842657b6792f95b987e0deb630d96aeb98db9700493be148999390c5e7 +dist/2026-09-29/clippy-beta-aarch64-pc-windows-gnullvm.tar.gz=1272823dc9eeb737f03ec09313c09953d75fea3a848e695c8bc434c2ab53e062 +dist/2026-09-29/clippy-beta-aarch64-pc-windows-gnullvm.tar.xz=76155e48b475fc40bb31ad136725f00875385db2bf179fdb3979065c7a65282f +dist/2026-09-29/clippy-beta-aarch64-pc-windows-msvc.tar.gz=f79d2073573010aa0f1ee4a8579b17f3a1997dc96fc6652a8c8c19a566231eb0 +dist/2026-09-29/clippy-beta-aarch64-pc-windows-msvc.tar.xz=4b8303804318d731b61159959c93782f205a95d8a3aa14e1643b319b6fe9558e +dist/2026-09-29/clippy-beta-aarch64-unknown-freebsd.tar.gz=1028922c743c9170603eb76731be0d3d994873a2b5a47f6a46480eb339a14554 +dist/2026-09-29/clippy-beta-aarch64-unknown-freebsd.tar.xz=ac262e022b7b09669051a325e02eef2cb83087c25ffdee6f059e2069ef430e3f +dist/2026-09-29/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=bb1376c0de000c1e0efdaf8ecb9fa11b14a64a6fe99000ac391f828376ce2c12 +dist/2026-09-29/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=90d1d3895d777b2a473f8035d3264f374c9ca91fdeec32d78899ae0a5f33f0ad +dist/2026-09-29/clippy-beta-aarch64-unknown-linux-musl.tar.gz=5a4cd4fa995f9ba8ef4f87001a87595c4a144f1af62b6a61ff2c5d4e2d90f7aa +dist/2026-09-29/clippy-beta-aarch64-unknown-linux-musl.tar.xz=3775b95f01258fb108f323d031ba8920993d23746f62a6fe5b14add176833b05 +dist/2026-09-29/clippy-beta-aarch64-unknown-linux-ohos.tar.gz=7759e690dcf0984c274dadb14d5601f64cecd21c833b44c93b24c509234bd697 +dist/2026-09-29/clippy-beta-aarch64-unknown-linux-ohos.tar.xz=21598de0d56cb2c0a259cec74bf4b45b1ae350a9d62296289e85f6648fff0427 +dist/2026-09-29/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=a8db1b3308fd0764012d3e76bdf92a076749a04af6f3f139288a1b5f7aea6d3a +dist/2026-09-29/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=746e5b548d3c57a9c42da80a02a5c2df0c2e025b2a8becf17ca1aab937d0bf27 +dist/2026-09-29/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=6100df771233dbe2d31b9ca7ac202ecdefddb964687b9ea2b97799c58f2df8b1 +dist/2026-09-29/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=601693ede0315db0d92c6bc9c53f1f4d829d1a506001cd291fcb61c12c91ca09 +dist/2026-09-29/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=a7cf7145fc885a7d0359e6f32f8d9a46bf2adbdf268823f1202647bc2a131fdc +dist/2026-09-29/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=4b26189ee6eb3d78cce60be7a54d0d64f1a5bfb18dbabf30e829296ee09065a6 +dist/2026-09-29/clippy-beta-i686-unknown-linux-gnu.tar.gz=b73fe9b224653599b38a0a68cada53106276e749f5350871a1d549be5c147487 +dist/2026-09-29/clippy-beta-i686-unknown-linux-gnu.tar.xz=60fa35754a88f0f97e538b639c24237d651c11e1edb16c653536111e1a7f123b +dist/2026-09-29/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=8a59dd0ce10cde5e714d3f8989fb1ebde1ac51d746e96a72d6239feae81d1568 +dist/2026-09-29/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=3e7d0761021dc58612054a575e202224645665f90fec0bf805998694a71c8fb9 +dist/2026-09-29/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=f220e05c95906dfe8247ab7a3fb732a5444cba27facad044f50db4c04b62bff4 +dist/2026-09-29/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=d9a7343dd0ee670a086a565a1013f647b3fd8061d4594d42cd2724d3cd52bb78 +dist/2026-09-29/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=e025c6f5c822b45ddf5387dc9a42dcdca9f69be2546a020b2d4de2c07590b8c4 +dist/2026-09-29/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=90d7b50a45274903c43d4d1c57c9ed5b4213c07563feed70caec38723df02bbf +dist/2026-09-29/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=31aa57d681a3215023de663aafeea01e476be4e2a1f89345602e89eb3b1b5c03 +dist/2026-09-29/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=fc5dd5800afb155af741770c6111262e9a2b5817bbd8bc2ba06ba2daeb72c822 +dist/2026-09-29/clippy-beta-powerpc64-unknown-linux-musl.tar.gz=ab5edc689617c105a00941d3870b6490c62209d235d09b7f2d48b8ca460b62a5 +dist/2026-09-29/clippy-beta-powerpc64-unknown-linux-musl.tar.xz=77b9759b82d634222650a2ccf9160b654fc636be0b7fd4fac822728eaf1f7317 +dist/2026-09-29/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=04f40458440c4222e49df829159f51fc667c10b0762181a535ff61cf120352be +dist/2026-09-29/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=ebc8495543e025b2c6db795f665725ad62a2ddd17094f6725bf4e00cbbf25331 +dist/2026-09-29/clippy-beta-powerpc64le-unknown-linux-musl.tar.gz=ba6653802d14bd1586819ae5f9510b9a97e0ba6ebc062942264b52fc297fcff8 +dist/2026-09-29/clippy-beta-powerpc64le-unknown-linux-musl.tar.xz=7c3f65a1938dea882cfee18992a10cb23b58de801a191d0cbbf8c6cc6f9cd900 +dist/2026-09-29/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=ad43d2a294308b1509151379c5a9bb40b064e13a841c2d34ed31537bd9eda3a0 +dist/2026-09-29/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=d7f118d124d772ebe763780f8ab1cd0295562eccae944c5507500971eebc5352 +dist/2026-09-29/clippy-beta-riscv64gc-unknown-linux-musl.tar.gz=9bb458f695227868c03d21e15177210b067c7fea223c1ba877f3908cff85e673 +dist/2026-09-29/clippy-beta-riscv64gc-unknown-linux-musl.tar.xz=80de4f209ad908cb28921bedd07cbb1444cd7f25179a851c6a2285bfcb13e13e +dist/2026-09-29/clippy-beta-s390x-unknown-linux-gnu.tar.gz=1f3e61cac84317586d80f816465800299920d032548dc82ac6fdd554503d9f86 +dist/2026-09-29/clippy-beta-s390x-unknown-linux-gnu.tar.xz=98f16b6b0a8a6a4542a07d0ec06ae1a05cefdeacfe7398363c61af5b5ea0e3dd +dist/2026-09-29/clippy-beta-sparcv9-sun-solaris.tar.gz=d5876205c3b704883a464354e287ad485dd0677261d36c7adb3beb97509bf907 +dist/2026-09-29/clippy-beta-sparcv9-sun-solaris.tar.xz=b036fc21fa47b8bce0113a1ef74ff869a54ea06d8f3bc0058f4551c3daa1f089 +dist/2026-09-29/clippy-beta-x86_64-apple-darwin.tar.gz=d9f9860fa397ae78d9e6612240a05eedb917cf536ebdef03bfd4bee110feff58 +dist/2026-09-29/clippy-beta-x86_64-apple-darwin.tar.xz=b054e2bba8ea8b3994e48aa1ef9b121eb1760f1c9468da3dcd9ca8cbe05728b9 +dist/2026-09-29/clippy-beta-x86_64-pc-solaris.tar.gz=ab47ad303b93eae7fd933333a94e7b4f65f0119735b83b8eca83691e24f982bf +dist/2026-09-29/clippy-beta-x86_64-pc-solaris.tar.xz=2187367acea68f7bf09932f0cdb237e30e57a57aadcc388219f60aaf28ec4ea1 +dist/2026-09-29/clippy-beta-x86_64-pc-windows-gnu.tar.gz=97af8a6c3356b4d65d1f96f893e57100969ecfbb2e6c364a2380b07d154677ec +dist/2026-09-29/clippy-beta-x86_64-pc-windows-gnu.tar.xz=af7f0a59d0ae24d0dc8ab6424a781a65d5d0cb8b3253786daa908e1d43efa7eb +dist/2026-09-29/clippy-beta-x86_64-pc-windows-gnullvm.tar.gz=683647b7e096c4085162b0936c614e7151bd6e9e6c5da902a80e68b91d54f47a +dist/2026-09-29/clippy-beta-x86_64-pc-windows-gnullvm.tar.xz=9a3b7efc7dd8c84f8351f117bcad61423c2f2cae6c1782fd28361a6865d31abf +dist/2026-09-29/clippy-beta-x86_64-pc-windows-msvc.tar.gz=b487c66b5091b4a7446f70d9fe138b62a253aac4a8a7745151f8a2e0f0af2c77 +dist/2026-09-29/clippy-beta-x86_64-pc-windows-msvc.tar.xz=53c63e23c797c931401bfc23053b336ebb0e0e26d603cd817770daff8aa8fb8e +dist/2026-09-29/clippy-beta-x86_64-unknown-freebsd.tar.gz=1174a56bb2aab0c5f88b963a8d2d26fbb5d29ff3f3dab449c6848711641060c8 +dist/2026-09-29/clippy-beta-x86_64-unknown-freebsd.tar.xz=adbb076f2efe0532c7e6997ceab6c08e8e5c228774b0e9f844bc238c14663f90 +dist/2026-09-29/clippy-beta-x86_64-unknown-illumos.tar.gz=07047d9cf9e20e6cdf12f1a24706eaf6791d921df97430aea8a1fe37f6cfd6f1 +dist/2026-09-29/clippy-beta-x86_64-unknown-illumos.tar.xz=7720a8410c6c1814a60c9c1432190179aff2bcdba720cc1fe7863cfe9c4ef7e2 +dist/2026-09-29/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=9a47312d7f06050e2a35f884a0fadb63994d9ce4c988db7055df9c3a18826db5 +dist/2026-09-29/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=dc6cafdb56fa4c08d69fabb0fe55c2bfbd13f5452676b7ca7ea80b0feb0636b7 +dist/2026-09-29/clippy-beta-x86_64-unknown-linux-musl.tar.gz=681bc45997f340b2767e1fcdb98d77cd6331b435c0b9b94d3dae0d68d2afe628 +dist/2026-09-29/clippy-beta-x86_64-unknown-linux-musl.tar.xz=09933240e021562422512f9a01364a681fa5fbdc0518d53b2c84159cc160f64b +dist/2026-09-29/clippy-beta-x86_64-unknown-netbsd.tar.gz=7f09a6e7d2a3ca645d600f7b2836854240927b9b22ed5b90c2e19b18602f1bf9 +dist/2026-09-29/clippy-beta-x86_64-unknown-netbsd.tar.xz=6f55faa86ce658f28036f4828d00d9f3554a16bc4c08d338f90e46cc0b8290a8 +dist/2026-09-29/rust-beta-aarch64-pc-windows-gnullvm.msi=110b7787e72503c3d8f00bb83b4844ee5d86282006535978fabaeccd570b9446 +dist/2026-09-29/rust-beta-aarch64-pc-windows-msvc.msi=52095c3b2bb30c4444514adb315c441ae99a908fcd6dabf84df86e9fa547fdf2 +dist/2026-09-29/rust-beta-x86_64-pc-windows-gnu.msi=0dbeb0a4874799e29f61078c2ee7b52aa09f3892da449949562f7b834213d2af +dist/2026-09-29/rust-beta-x86_64-pc-windows-gnullvm.msi=67bb2a3bdf0efa223c1ec3961ca8bb3becd0dfec3dbba6c1664f3800c13f96c9 +dist/2026-09-29/rust-beta-x86_64-pc-windows-msvc.msi=f3832ded2d7dc6b8e344a8a05a58145753b7206409ab7989e4e175b000891bb5 +dist/2026-09-29/rust-beta-aarch64-apple-darwin.pkg=ba8205d70d4e7d9dac9fcbbb50e26a1c48d95f6d53115cd4f31b4894fb770f86 +dist/2026-09-29/rust-beta-x86_64-apple-darwin.pkg=821a0c24ed40c517f6b3cadc591a41e12f3dc17ee177d304d91adcc4d00d1557 +dist/2026-09-29/rustc-beta-src.tar.gz=1e970d860c77112674c08a4f6fe27c7f5f3eabdbaaabae7924872f37b0a6bc9f +dist/2026-09-29/rustc-beta-src.tar.xz=8c8dd7643b15e160e0ee62ce2ea2804c1c463954a983527335c9ad05e2d7a282 +dist/2026-09-29/rustfmt-nightly-aarch64-apple-darwin.tar.gz=3bd82067ee57ab38a80d21b212397e600b1cdfac4ffe67e064a0d4fc72696579 +dist/2026-09-29/rustfmt-nightly-aarch64-apple-darwin.tar.xz=105657de7a7e2989d0e1aa27655bad89689dfa702e6208072c04a5dc1f116dca +dist/2026-09-29/rustfmt-nightly-aarch64-pc-windows-gnullvm.tar.gz=e9ac24651a2dcd1b92c85ce3ca537ca4004d077d13d81a76c30543a2ff537ce8 +dist/2026-09-29/rustfmt-nightly-aarch64-pc-windows-gnullvm.tar.xz=12d0fed0b8caaea2fb0b63590a4dc2f96af71a54eb3ca113e09601a5e603fa7e +dist/2026-09-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=2e4a7ba18c433714efdcce7b1b858a3128b10918f0b6c081225b5699ce095b4c +dist/2026-09-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=da5ef1e3577b7c7817509115086de5f3b32d943b76ee3e5d3d555f88bc02b28e +dist/2026-09-29/rustfmt-nightly-aarch64-unknown-freebsd.tar.gz=44446b6fae2d871a1b6af2100f4c0783b3f000b348a1536c5c4f23b82c8107ec +dist/2026-09-29/rustfmt-nightly-aarch64-unknown-freebsd.tar.xz=7d37bb9b45eac9c1e2bbcc623da6dde1d653527d408292e913b4347f3622accb +dist/2026-09-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=997a0e463191defc94ffa9405ba11a4a2bba1b220b40cef415a1a8d21e2e88f1 +dist/2026-09-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=2050f09bd2dffd324c3b949626c35830d16f2e92a680a8c7001a19287d3d1b54 +dist/2026-09-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=479090aac278503503b41acf936c774c645343a33193e5c149f9db28a301edc9 +dist/2026-09-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=87b3f386c5372dca8676065403c0123935c7a47c5e69579beecc040a0b67ba15 +dist/2026-09-29/rustfmt-nightly-aarch64-unknown-linux-ohos.tar.gz=10da9a954bd0b76aab56c09ba01262eb87069ba18d67c36b982f3a5ca0ca3555 +dist/2026-09-29/rustfmt-nightly-aarch64-unknown-linux-ohos.tar.xz=f3db934402e31236c41188b5f85eab229e4cc8d108c9c33375e03bdd3b72bde3 +dist/2026-09-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=9891c54c4cc027cb0e0edbf6c7b2d85a80287ff486074d8334cc0eea662fce48 +dist/2026-09-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=8ef63b3fbace26c9ae4045bf08d8bc2c60fc6fcac095bab34f0743f82729a15b +dist/2026-09-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=fabf81e854b1e1220756f2cc04cb911bff886af1a84f306bd38eaf3d7bf6e0bf +dist/2026-09-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=f47aac3590c165cd800be1526278bc06538fddfbadc2f2ea0288a16274a3b04f +dist/2026-09-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=fe5a0792b5f3f34e4854e257f3edf27e30c90938568e4ff576d374e5a4800cfd +dist/2026-09-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=3ed3e957bbb5aeb4895cb5ddfcb93abd32a5c10982adb0724a3b91a578c9d5a5 +dist/2026-09-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=d1e17fb001c32efa0455ce814ba35276e02de4fa41f858a1573f407ebfb79b21 +dist/2026-09-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=d673931f677d95884fcbdb9dd1d971588ad8209b12b9ec10338f2c9e1516479e +dist/2026-09-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=96cf73ca815b8b5c912cb82e2ee2d75d1d60a11bda9fe242173b8a74335441b1 +dist/2026-09-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=a1af935bc9d319a962f388cb9d52981ccc1adae9e79ad561c520f92994b5b4de +dist/2026-09-29/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=a614c7570d2f7370761938d62a93cf231d6673f4cf51be1ec13a86d7857d8a26 +dist/2026-09-29/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=c7033f3846f19329e2d0c177cdc328387e9fd1d6738f44f3134fd73993e810e7 +dist/2026-09-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=5a5c754617ff1d20b76c4f6a651bfbeb3446d133e2d7d1d151195d9c9709ba37 +dist/2026-09-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=efba88f943670d427859c411c71090e3c9c503400c527432bf0f4e45aa9a640d +dist/2026-09-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=bdfd3bd37453fd6c8cf965b2ccc56d0db4131dcb232843ff8ccb744126d07581 +dist/2026-09-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=36fb9e8d537d9439391b2eac5357bc93d422be396fe226c4e7ada987ae1cd0fd +dist/2026-09-29/rustfmt-nightly-powerpc64-unknown-linux-musl.tar.gz=613aaa4c896802ad5065a846a0412e708ba4ec8d4cbb8c4cc268924edf50866d +dist/2026-09-29/rustfmt-nightly-powerpc64-unknown-linux-musl.tar.xz=d11268b84e0ad465d055208171268a63340724909916c9c4c8f2db7f77930406 +dist/2026-09-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=3635e8a286ebf903e86b13e71a0c9da91b1cf08acd15fb529990e1bb01938994 +dist/2026-09-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=7ba06366c9cb6641d177d1fea1efc74b4a70145f4947aea57dc3161d21e3b53b +dist/2026-09-29/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.gz=64fa9295cd882e817a913046856e11e3980740efedbc9dce3c9154e38c9a1088 +dist/2026-09-29/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.xz=190e0db21d5bfb1e47a6448566b42429a386e8ced68eccf29c575e8a17774aa2 +dist/2026-09-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=780db7ef6ffc4d4e3bf37588d111b2733b2f30b22d1247111a7b6d290ed7882a +dist/2026-09-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=0c55a5f391d9e032ec946bf2ea977b80514239c54109438e4ef17257bbae05e6 +dist/2026-09-29/rustfmt-nightly-riscv64gc-unknown-linux-musl.tar.gz=e9f3036825eae095bc415b485ad9397c96edc3481a258865db9d4b54e7cc9134 +dist/2026-09-29/rustfmt-nightly-riscv64gc-unknown-linux-musl.tar.xz=e4b3cac7c35db29013a22fa6e374011dea824909e3411ce4dabdb197344e0a9d +dist/2026-09-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=c989d87883a750ae2e3d92366f22c0a55858dab9402260af5b2272b8b3eb10c2 +dist/2026-09-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=e9cbc14a8c2a85229bd523a46982aaf50e242a810708f3ebb3eff2b89c8d1ddd +dist/2026-09-29/rustfmt-nightly-sparcv9-sun-solaris.tar.gz=9bcbe9b3c071008b490ecfc47e0b6007ef0577a488b71ffe829cac10c3f7b467 +dist/2026-09-29/rustfmt-nightly-sparcv9-sun-solaris.tar.xz=319876228cd9ba5319749c819fd127ff7fd9fb87e2886aa4eb97f14e13e95cf3 +dist/2026-09-29/rustfmt-nightly-x86_64-apple-darwin.tar.gz=a71ddea3e092dcd35a2b18c2538a7fc7df24b7fbde464e5b2a8014f86b24b843 +dist/2026-09-29/rustfmt-nightly-x86_64-apple-darwin.tar.xz=5b0ccd75907f3dc4a603cd60bbe87a11c3d75dc793adbdeb453fd385ef91df1f +dist/2026-09-29/rustfmt-nightly-x86_64-pc-solaris.tar.gz=26149456d7e5823901a3df9e5b4e49a93a04e02a536b324bfe2aa16dc5a5f4b6 +dist/2026-09-29/rustfmt-nightly-x86_64-pc-solaris.tar.xz=874f59be83371e0371bd30ccd4abcfe038377c2544ee2c3c577b8a8882a28ee5 +dist/2026-09-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=bc002bd19c2d5c13692d8571c6a82cca5213dd5454e8f1d17215452683b612c3 +dist/2026-09-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=09c04f5a4a7bf944b58b1b3a0a3142ac8450d7db5277028b881d7ab96242a0b9 +dist/2026-09-29/rustfmt-nightly-x86_64-pc-windows-gnullvm.tar.gz=4af726ea96c30759085ad6886d3d0b0c429abb6ca68990c382f2490ec44cb022 +dist/2026-09-29/rustfmt-nightly-x86_64-pc-windows-gnullvm.tar.xz=77e0d096d1d241c238dd84266a0d32500f3dc0acf142a644012a99eb50fb00f7 +dist/2026-09-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=294cf327a6af4a8a88ddd6c3bd74a9877afe0940b6a451675f67b10c20588c1d +dist/2026-09-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=8d2be13b650f7ce0eea90ad26f7b8f5b02771d140ef4b13d3b50ca0a7fe53e21 +dist/2026-09-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=bb8a080ab727bf0503740763ce1eaadcedfd5f592b5462140d1038d397a973b7 +dist/2026-09-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=35dc1d5b43934cb35f390491d62c5ebb570005f64edc0baab6456bf2421a71d2 +dist/2026-09-29/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=7af5c6a369e6bee9a0239a5c2ebb901dbec8a5b4ed7dbefcd54b84d72cdcf2e1 +dist/2026-09-29/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=633ea7cccf1ff5d0999efcb16a35da4e47911ec276b03bf62db5e87b38e82e88 +dist/2026-09-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=cb4dc1c222f7cc67bb2a97418347fce26bdcec945567afc4867549901c9248ad +dist/2026-09-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=243f7fd02c5e75bdbd2e35b0ff0ad916de1fe812bf05ae92e51e73f085ebf3bf +dist/2026-09-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=864f2b4694d45c087f28a54096c5419970a8b7f21e8d60bcd34eef10c6505ab3 +dist/2026-09-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=a461bbc1b5162ae9c7f0c6d96025b6eecf35f4f0bd472715a52937934049bd52 +dist/2026-09-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=11653a0860011db783741465f11dd6833325d1396a82518acb4024d9f65cc545 +dist/2026-09-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=ba8ac6446ce72fc0bad895759fe9fa281acabbf06ed676908b07a303849f1139 +dist/2026-09-29/rustc-nightly-aarch64-apple-darwin.tar.gz=f8bd07a928a00f5a58ecb90eaa3f5383deeca284ecd269c259dce96229c8dd9f +dist/2026-09-29/rustc-nightly-aarch64-apple-darwin.tar.xz=e76cb7ea5f41feb883ee7ed89bd71f48ec029eca9605d3aa757d952bd6a153be +dist/2026-09-29/rustc-nightly-aarch64-pc-windows-gnullvm.tar.gz=0c6136923cf94fa3910caa5440e2e68a4c517366154a57824a1e96f30da4fc81 +dist/2026-09-29/rustc-nightly-aarch64-pc-windows-gnullvm.tar.xz=bc94e0fe4523abe8ae134c068651b571e24ddb44a2ed7bbf40feff344d1668f0 +dist/2026-09-29/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=1d0196716ec66f3a08092736407bcff0b5eeeb0ed9e700467f16959ca8167594 +dist/2026-09-29/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=c08b4c0f3f5df85fb2a39a9e7748be6ce73bb4c17aa00549d3098a4e30738336 +dist/2026-09-29/rustc-nightly-aarch64-unknown-freebsd.tar.gz=3a513dd49f1fd8c80c8a9b51d68bf40a01a4fe6cf0c98a12420dc130e28c3a0d +dist/2026-09-29/rustc-nightly-aarch64-unknown-freebsd.tar.xz=3553abe463701c7b10bc853849e4273eb1f3a0d1d3c6e3d5dda106a41729e2ad +dist/2026-09-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=23732a3568613f3a0b2b06ab28e1732282297399ddfa07baccaa67c12f50ebdf +dist/2026-09-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=651734f660be3f83022f4a627c920753e19e79a7e6c0ee1e6c41f4f78c59767d +dist/2026-09-29/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=fa01fe14d03160af899bf60866613826f83a180a6b9eafacb0cf97380059ebf8 +dist/2026-09-29/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=3a67ebd7e6083ba65598070c2097e322eab032d4a5084bb6a829a51d4923e6b8 +dist/2026-09-29/rustc-nightly-aarch64-unknown-linux-ohos.tar.gz=444251d96d77b80d3b8252ab13108ef053c9482340fbed582b1bef245c258b32 +dist/2026-09-29/rustc-nightly-aarch64-unknown-linux-ohos.tar.xz=1df09853d89ca89950dcf058933dd4d760d1aad172a67b9f60c5b25522f0fe40 +dist/2026-09-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=61f9a4ade7f6daf6b5dfab631321b99625533bab506020594fbc9b6b7c1065c5 +dist/2026-09-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=21ccf42a6618c0b7c1db874566d1e1abe48556c6d8b45139f7c858583debdafa +dist/2026-09-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=296d9251257c6b8a1225cc6cf5c422a790df5b9ccd2fb84d269bff701ee71928 +dist/2026-09-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=d732c98eeefb447784ef6cb61c59fc919c3e48d4c291efff524cd9492a44e8ae +dist/2026-09-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=5f50621c4463f2cd439922c2bb3b9d2e6af145bfe63aae0a2edec7073af7c758 +dist/2026-09-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=52af25e8af238a3fe660f984c1c1cd28f90355cb78d5ba6a967bba94377572ef +dist/2026-09-29/rustc-nightly-i686-unknown-linux-gnu.tar.gz=55f65a08943922d590639588d8c29a6fba4049b33f20332195d72a71a7af7d2e +dist/2026-09-29/rustc-nightly-i686-unknown-linux-gnu.tar.xz=e234eb2638f14654677955ecdf87fe369d439da77cd466e0154f673898bee09b +dist/2026-09-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=70772d9f7de70d4f0ac082e266bfe582a9c20969be33482f3f3244aeca11ee57 +dist/2026-09-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=4f021e104f149d5c128b646bfd7a889c3bef37322ace9a5759075b42cde2c193 +dist/2026-09-29/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=b771b86f7af7055f876cd842f70288d26f34c9fb594b7930a43d94d22e07e6f5 +dist/2026-09-29/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=bfa7b382ac38053d6cd2a5fbda87494168ce54bfad95b161c0bc3790e94d99bf +dist/2026-09-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=576a6faa602ebc4eec32cc06209fe958f98ae584db2c8ba52c7d55bca258c16a +dist/2026-09-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=7a9563061646816f62ed10d8470ddc931d1df850342bca8a5e109dca445a487e +dist/2026-09-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=d94deb2c8476421c2a223af821d7bda039ab853954e6e7eec3dc4235a4bd1de2 +dist/2026-09-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=9d21d197013585e2cba456b76885c41e3b43a30c4004845fdc313eb33a38afcd +dist/2026-09-29/rustc-nightly-powerpc64-unknown-linux-musl.tar.gz=bab32e4293dd8052aa081aaa6643303d7b0aa4fbe3acbfd91c717a0bea776a5f +dist/2026-09-29/rustc-nightly-powerpc64-unknown-linux-musl.tar.xz=445b9ff411c8dc74cbc337b1b353c72dc75bc431eb997a36436e6b80987059ec +dist/2026-09-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=c8ef38bc477c70fa0e7131c4971b52ae728524e80e29a2570dd5354d5dbe48f2 +dist/2026-09-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=afb3c35107b8e4cb6edb48cfa71113084d6fa5360b28127a0e8e1948fa2abc7e +dist/2026-09-29/rustc-nightly-powerpc64le-unknown-linux-musl.tar.gz=9ce50d28b324c020b5fdb37db1a5522ed5a59815a14cfc117177a6c0d98a0d73 +dist/2026-09-29/rustc-nightly-powerpc64le-unknown-linux-musl.tar.xz=9bed9c6990d3ae6b33e60ffa7b60d0e9f6020b24c2c8b5cf7fff61474c87c987 +dist/2026-09-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=5ae5f61985ed5dae8cd9f6d7638afe4957ef1d860a8e819249fdac1d58750e93 +dist/2026-09-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=445bef041d5e64fdbd50ad4e883c6b831c4df8bc170f04f779fdccd5db553f02 +dist/2026-09-29/rustc-nightly-riscv64gc-unknown-linux-musl.tar.gz=57f862b615abeef4aa0988e9b023468230757454c30ff8af847a87f884e43f41 +dist/2026-09-29/rustc-nightly-riscv64gc-unknown-linux-musl.tar.xz=eaa6fd5bbb2a8e256e8f0a335f9b7ef33c60a40f0d4bae7a72ad1341809dc8aa +dist/2026-09-29/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=1d2eb7ede0ef321f5a5eed1f19ff30c645048cad2dce1ee32a01fd473d07d529 +dist/2026-09-29/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=892a029d3c60c9b037c073a02cad2c22247bfdf6c21ef94891eb5709ac85b3aa +dist/2026-09-29/rustc-nightly-sparcv9-sun-solaris.tar.gz=75ebd4fd6a89b3fa3529fecc6ab418a88aaea6f2085d2041bf7aa65cab57d1e7 +dist/2026-09-29/rustc-nightly-sparcv9-sun-solaris.tar.xz=56b8da62b8a49658c8a9a575bee49c28eaf955d21442e77c1740935f94d4b0bc +dist/2026-09-29/rustc-nightly-x86_64-apple-darwin.tar.gz=a1063ef2cf262f973c63358955bb1381fb37e73f154b44828b77091d3156a450 +dist/2026-09-29/rustc-nightly-x86_64-apple-darwin.tar.xz=99773bfc304755bc642fbc3617989bc62ee79f2265008c64d6ac15c514673f10 +dist/2026-09-29/rustc-nightly-x86_64-pc-solaris.tar.gz=b9c97ef49440e32d0f62012b1614b8e5cb9773efafeeec5517f82f6ef4f21623 +dist/2026-09-29/rustc-nightly-x86_64-pc-solaris.tar.xz=a286922465f006f15c802a8c1dce3c12ea73846a89006a917c86ebe20e605d7b +dist/2026-09-29/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=ad9a406b01931b98be6021e991899cc1fb028a121b35ffd0a30d8b9359e3b940 +dist/2026-09-29/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=8de44d3694475f3d7579f24d9d8c0dc66f927cd816db4cb572f81eb1e3eb5656 +dist/2026-09-29/rustc-nightly-x86_64-pc-windows-gnullvm.tar.gz=404c667f59d56ac591e9d043ec0427ac2a676fd2a1825442efc3465fe48719f6 +dist/2026-09-29/rustc-nightly-x86_64-pc-windows-gnullvm.tar.xz=f581783eb350436723bb5b4f12257dec703651b055998e3490f7af616e987479 +dist/2026-09-29/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=530917988010ccbe9a6449f5136ba01958d5f94e282a41834b10e7017da11b20 +dist/2026-09-29/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=8ad2b5afbc056d7515626ac2aef4b81d992469f70ebf41701222cca1bc2bcd3b +dist/2026-09-29/rustc-nightly-x86_64-unknown-freebsd.tar.gz=b693055d8cd4da607549da8ed0a186876a3db81f3a27deba1872439d68748014 +dist/2026-09-29/rustc-nightly-x86_64-unknown-freebsd.tar.xz=b55c0de331ce5601970e8227a34ada46ec394a18a86b89700b50d369b6dd59d7 +dist/2026-09-29/rustc-nightly-x86_64-unknown-illumos.tar.gz=54a37b89c59f32e12225f183cb4b0cf2c79721fe5dc15f5801c9527d426b2df7 +dist/2026-09-29/rustc-nightly-x86_64-unknown-illumos.tar.xz=0cff97495e37bdb45230d2ce7d57ccf06b767f6fbbb7cf69df57ae1595b8511e +dist/2026-09-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=ee5cf66faf459f360fb13c9898c2f588f5e04525ce29539c81147b3d0daaa3e8 +dist/2026-09-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=dba6569dd43bf3566bea07621fd270baac5ee75ca70a729c45bcef46f2725b9f +dist/2026-09-29/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=ce2f90940e5911e475f10dc25f7f49a32a971b375bc5d990de4c729f3efde5e0 +dist/2026-09-29/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=7a3b06231fb1604c465c241951cb6c2286d841bb175da13d933c24bc5822a2f5 +dist/2026-09-29/rustc-nightly-x86_64-unknown-netbsd.tar.gz=ce146f46f22b2cb210fbd5a2ce33511b309101f2e1e290db4319e8ed14894bf9 +dist/2026-09-29/rustc-nightly-x86_64-unknown-netbsd.tar.xz=9c787a33d96d02b05e1ad8eb0ce6da8de1f531a05e05199ac4ed8dff051314cb +dist/2026-09-29/rust-nightly-aarch64-pc-windows-gnullvm.msi=a4c6d25c32b5a0a751b53568185e1bb29b6701e9c78a3c964c99de435d5df5d2 +dist/2026-09-29/rust-nightly-aarch64-pc-windows-msvc.msi=1bcc25f2c3c3d154578d314d51488de9a5db11759a38703a6ecf8bb5a5d6d6a3 +dist/2026-09-29/rust-nightly-x86_64-pc-windows-gnu.msi=3f8abd777867a484177ebce45009325559fd89f56065c257cc12e05b679b1658 +dist/2026-09-29/rust-nightly-x86_64-pc-windows-gnullvm.msi=be77343c9728e594b2f355f0d1c03a42ecde8757b2ff4ce4cd6da95a4dbd3e34 +dist/2026-09-29/rust-nightly-x86_64-pc-windows-msvc.msi=a080cc47533ac72c19cbd2b309fab14f33ae11f7aca18feb7a1c955883df37e6 +dist/2026-09-29/rust-nightly-aarch64-apple-darwin.pkg=1485843b8c0f53e3b50dd277aef08d2669a01ce6485bacf202c8f24fbebaf623 +dist/2026-09-29/rust-nightly-x86_64-apple-darwin.pkg=62ef2681dc83414c208c981949efbfc007b9b9ac8ab1bee776b3ed42130f2fe5 +dist/2026-09-29/rustc-nightly-src.tar.gz=54f78062b491bb27ba1eeedcf59fe8f0ce7c4e30189613af34b711feb4839ff8 +dist/2026-09-29/rustc-nightly-src.tar.xz=5d38310ee84c42e638094781bf1ec5456977fdc64021a83c8e0779d04371159a diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index 87bb44875aee9..0544f1bcac20f 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -7,7 +7,6 @@ #![feature(iter_partition_in_place)] #![feature(macro_metavar_expr)] #![feature(macro_metavar_expr_concat)] -#![cfg_attr(bootstrap, feature(never_type))] #![cfg_attr(bootstrap, feature(unwrap_infallible))] #![feature(rustc_private)] #![feature(stmt_expr_attributes)] diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs index 18897fbb5b8f0..0f5adb8b983e2 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs @@ -4,10 +4,9 @@ use clippy_utils::sugg::Sugg; use rustc_ast::util::parser::ExprPrecedence; use rustc_errors::Applicability; use rustc_hir::{Expr, Node}; -use rustc_hir_typeck::cast::check_cast; +use rustc_hir_typeck::cast::{CastKind, check_cast}; use rustc_lint::LateContext; use rustc_middle::ty::Ty; -use rustc_middle::ty::cast::CastKind; /// Checks for `transmutes_expressible_as_ptr_casts` lint. /// Returns `true` if it's triggered, otherwise returns `false`. diff --git a/src/tools/clippy/clippy_test_deps/Cargo.toml b/src/tools/clippy/clippy_test_deps/Cargo.toml index 880df6599c1e4..c3d236a17e1bb 100644 --- a/src/tools/clippy/clippy_test_deps/Cargo.toml +++ b/src/tools/clippy/clippy_test_deps/Cargo.toml @@ -18,3 +18,7 @@ itertools = "0.15" # Make sure we are not part of the rustc workspace. [workspace] + +[lints.cargo] +# Not all tests use all of the above dependencies +unused_dependencies = "allow" diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock index 166d45491242c..8cffd4defac3d 100644 --- a/src/tools/miri/Cargo.lock +++ b/src/tools/miri/Cargo.lock @@ -1020,8 +1020,10 @@ dependencies = [ "serde", "serde_json", "smallvec", + "socket2", "tempfile", "ui_test", + "windows-sys", ] [[package]] @@ -1484,6 +1486,16 @@ version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" +[[package]] +name = "socket2" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "spanned" version = "0.4.1" diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index de4687715c06b..1c52d35bf5bb2 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -28,6 +28,7 @@ directories = "6" bitflags = "2.6" serde_json = { version = "1.0", optional = true } mio = { version = "1.1.1", features = ["os-poll", "net"] } +socket2 = "0.6.5" [target.'cfg(unix)'.dependencies] libc = "0.2" @@ -47,6 +48,11 @@ capstone = { version = "0.14", features = ["arch_x86", "full"], default-features [target.'cfg(all(target_os = "linux", target_pointer_width = "64", target_endian = "little"))'.dependencies] genmc-sys = { path = "./genmc-sys/", version = "0.1.0", optional = true } +[target.'cfg(windows)'.dependencies] +windows-sys = { version = "0.61", features = [ + "Win32_Storage_FileSystem", +] } + [dev-dependencies] ui_test = "0.30.2" colored = "3" diff --git a/src/tools/miri/etc/rust_analyzer_helix.toml b/src/tools/miri/etc/rust_analyzer_helix.toml index 1015b4baa6b09..3b31ec68774d6 100644 --- a/src/tools/miri/etc/rust_analyzer_helix.toml +++ b/src/tools/miri/etc/rust_analyzer_helix.toml @@ -17,6 +17,10 @@ overrideCommand = [ "--message-format=json", ] +[language-server.rust-analyzer.config.diagnostics] +# RA reports false errors due to +enable = false + [language-server.rust-analyzer.config.cargo.extraEnv] MIRI_AUTO_OPS = "no" MIRI_IN_RA = "1" diff --git a/src/tools/miri/etc/rust_analyzer_zed.json b/src/tools/miri/etc/rust_analyzer_zed.json index e5ff400e989e7..f2debc2000acb 100644 --- a/src/tools/miri/etc/rust_analyzer_zed.json +++ b/src/tools/miri/etc/rust_analyzer_zed.json @@ -19,6 +19,10 @@ "--message-format=json" ] }, + "diagnostics": { + // RA reports false errors due to + "enable": false + }, "cargo": { "extraEnv": { "MIRI_AUTO_OPS": "no", diff --git a/src/tools/miri/priroda/Cargo.lock b/src/tools/miri/priroda/Cargo.lock index 8d4272630e08a..a690264e158fc 100644 --- a/src/tools/miri/priroda/Cargo.lock +++ b/src/tools/miri/priroda/Cargo.lock @@ -688,6 +688,8 @@ dependencies = [ "rand 0.10.2", "serde", "smallvec", + "socket2", + "windows-sys", ] [[package]] @@ -1115,6 +1117,16 @@ version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" +[[package]] +name = "socket2" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "spanned" version = "0.4.1" diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 89c3e1334a546..eb8c4fb20edfe 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -88638df1e741778019e42fcdf307072865d19501 +5c543b0b8c73c7b72bc8284ced4fb22ead15734d diff --git a/src/tools/miri/src/intrinsics/x86/sse2.rs b/src/tools/miri/src/intrinsics/x86/sse2.rs index b39bfcaedea59..d9ef809598765 100644 --- a/src/tools/miri/src/intrinsics/x86/sse2.rs +++ b/src/tools/miri/src/intrinsics/x86/sse2.rs @@ -1,4 +1,5 @@ use rustc_apfloat::ieee::Double; +use rustc_middle::mir; use rustc_span::Symbol; use super::{ @@ -272,6 +273,41 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { pmaddwd(this, left, right, dest)?; } + // Used to implement the _mm_mulhi_epi16 and _mm_mulhi_epu16 functions. + "pmulh.w" | "pmulhu.w" => { + let [left, right] = this.check_shim_sig_llvm_intrinsic(link_name, args)?; + + let (left, left_len) = this.project_to_simd(left)?; + let (right, right_len) = this.project_to_simd(right)?; + let (dest, dest_len) = this.project_to_simd(dest)?; + + assert_eq!(dest_len, left_len); + assert_eq!(dest_len, right_len); + + for i in 0..dest_len { + let left = this.read_immediate(&this.project_index(&left, i)?)?; + let right = this.read_immediate(&this.project_index(&right, i)?)?; + let dest = this.project_index(&dest, i)?; + + // Widen the operands to avoid overflow + let twice_wide = this.layout_of(this.get_twice_wide_int_ty(left.layout.ty))?; + let left = this.int_to_int_or_float(&left, twice_wide)?; + let right = this.int_to_int_or_float(&right, twice_wide)?; + + // Multiply + let multiplied = this.binary_op(mir::BinOp::Mul, &left, &right)?; + // Keep the high half + let high = this.binary_op( + mir::BinOp::Shr, + &multiplied, + &ImmTy::from_uint(dest.layout.size.bits(), twice_wide), + )?; + + // Narrow back to the original type + let res = this.int_to_int_or_float(&high, dest.layout)?; + this.write_immediate(*res, &dest)?; + } + } _ => return interp_ok(EmulateItemResult::NotSupported), } interp_ok(EmulateItemResult::NeedsReturn) diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index d1b3e1a1cf1f6..14684a5dcef84 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -14,7 +14,6 @@ #![feature(float_gamma)] #![feature(float_erf)] #![feature(map_try_insert)] -#![cfg_attr(bootstrap, feature(never_type))] #![feature(try_blocks)] #![feature(io_error_more)] #![feature(io_error_inprogress)] diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index fa025f839057f..65eb6e10d4518 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -14,11 +14,11 @@ use rustc_abi::{Align, ExternAbi, Size}; use rustc_apfloat::{Float, FloatConvert}; use rustc_ast::Mutability; use rustc_ast::expand::allocator::{self, SpecialAllocatorMethod}; +use rustc_attr_ir::{InlineAttr, Linkage}; use rustc_data_structures::either::Either; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; #[allow(unused)] use rustc_data_structures::static_assert_size; -use rustc_attr_ir::{InlineAttr, Linkage}; use rustc_hir::def::DefKind; use rustc_log::tracing; use rustc_middle::middle::codegen_fn_attrs::TargetFeatureKind; diff --git a/src/tools/miri/src/shims/files.rs b/src/tools/miri/src/shims/files.rs index cd7a7f4f0250b..d842f2f69b713 100644 --- a/src/tools/miri/src/shims/files.rs +++ b/src/tools/miri/src/shims/files.rs @@ -513,7 +513,24 @@ impl FileDescription for FileHandle { #[derive(Debug)] pub struct DirHandle { - pub(crate) dir: Dir, + pub(super) dir: Dir, + #[cfg(bootstrap)] + pub(super) fallback: std::path::PathBuf, + #[cfg(not(bootstrap))] + #[expect(unused)] + fallback: (), +} + +impl DirHandle { + pub fn open(path: &std::path::Path) -> io::Result { + #[cfg(bootstrap)] + let fallback = path.canonicalize()?; + #[cfg(not(bootstrap))] + let fallback = (); + + let dir = Dir::open(path)?; + Ok(DirHandle { dir, fallback }) + } } impl FileDescription for DirHandle { diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index cef93e9653430..66d65ead7c7bd 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -4,8 +4,8 @@ use std::path::Path; use rustc_abi::{Align, ExternAbi, Size}; use rustc_ast::expand::allocator::NO_ALLOC_SHIM_IS_UNSTABLE; -use rustc_data_structures::either::Either; use rustc_attr_ir::Linkage; +use rustc_data_structures::either::Either; use rustc_hir::def::DefKind; use rustc_hir::def_id::CrateNum; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; @@ -170,8 +170,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // picked by the linker. // Make sure we are consistent wrt what is 'first' and 'second'. - let original_span = - tcx.def_span(original.instance.def_id()); + let original_span = tcx.def_span(original.instance.def_id()); let span = tcx.def_span(def_id); if original_span.lo_hi() < span.lo_hi() { throw_machine_stop!( diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index f78c92de97bcc..54639db6e19cf 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -404,6 +404,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let result = this.stat(path, buf)?; this.write_scalar(result, dest)?; } + "fstatat" => { + let [dirfd, path, buf, flags] = this.check_shim_sig( + shim_sig!(extern "C" fn(i32, *_, *_, i32) -> i32), + (link_name, abi, args), + )?; + let result = this.fstatat(dirfd, path, buf, flags)?; + this.write_scalar(result, dest)?; + } "chmod" => { let [path, mode] = this.check_shim_sig( shim_sig!(extern "C" fn(*_, libc::mode_t) -> i32), diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index 98a7c2ff3c2cf..1b9133785ed4a 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use std::ffi::OsString; -use std::fs::{self, Dir, DirBuilder, File, FileTimes, FileType, OpenOptions, TryLockError}; +use std::fs::{self, DirBuilder, File, FileTimes, FileType, OpenOptions, TryLockError}; use std::io::{self, ErrorKind, Read, Seek, SeekFrom, Write}; use std::path::{self, Path}; use std::time::SystemTime; @@ -20,14 +20,14 @@ use crate::shims::sig::Varargs; use crate::shims::unix::fd::{EvalContextExt as _, FlockOp, UnixFileDescription}; use crate::*; -/// An open directory stream, tracked by DirTable. +/// An open directory stream (`DIR`), tracked by DirTable. #[derive(Debug)] struct DirStream { - /// The directory reader on the host. + /// The directory stream on the host. read_dir: fs::ReadDir, - /// An FD number for the same handle. Unix directory streams have an "underlying FD" that - /// can be exposed; this is that FD. We also store the FD ID to catch cases where - /// the FD was closed and a different one re-opened. + /// Unix directory streams have an "underlying FD" that can be exposed; this is that FD. This is + /// not a reference; it *can* be separately closed, leading to UB if the DIR is used again. We + /// also store the FD ID to catch cases where the FD was closed and a different one re-opened. fd_num: FdNum, fd_id: FdId, /// The "special" entries that must still be yielded by the iterator. @@ -387,15 +387,17 @@ trait EvalContextExtPrivate<'tcx>: crate::MiriInterpCxExt<'tcx> { }) } - #[cfg(unix)] fn host_permissions_from_mode(&self, mode: u32) -> InterpResult<'tcx, fs::Permissions> { - use std::os::unix::fs::PermissionsExt; - interp_ok(fs::Permissions::from_mode(mode)) - } - - #[cfg(not(unix))] - fn host_permissions_from_mode(&self, _mode: u32) -> InterpResult<'tcx, fs::Permissions> { - throw_unsup_format!("setting file permissions is only supported on Unix hosts") + cfg_select! { + unix => { + use std::os::unix::fs::PermissionsExt; + interp_ok(fs::Permissions::from_mode(mode)) + } + _ => { + let _ = mode; + throw_unsup_format!("setting file permissions is only supported on Unix hosts") + } + } } } @@ -481,20 +483,20 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; let mode = this.read_scalar(mode)?.to_u32()?; - #[cfg(unix)] - { - // Support all modes on UNIX host - use std::os::unix::fs::OpenOptionsExt; - options.mode(mode); - } - #[cfg(not(unix))] - { - // Only support default mode for non-UNIX (i.e. Windows) host - if mode != 0o666 { - throw_unsup_format!( - "non-default mode 0o{:o} is not supported on non-Unix hosts", - mode - ); + cfg_select! { + unix => { + // Support all modes on UNIX host + use std::os::unix::fs::OpenOptionsExt; + options.mode(mode); + } + _ => { + // Only support default mode for non-UNIX (i.e. Windows) host + if mode != 0o666 { + throw_unsup_format!( + "non-default mode 0o{:o} is not supported on non-Unix hosts", + mode + ); + } } } @@ -521,22 +523,20 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let o_nofollow = this.eval_libc_i32("O_NOFOLLOW"); + let mut nofollow = false; if flag & o_nofollow == o_nofollow { flag &= !o_nofollow; - #[cfg(unix)] - { - use std::os::unix::fs::OpenOptionsExt; - options.custom_flags(libc::O_NOFOLLOW); - } - // Strictly speaking, this emulation is not equivalent to the O_NOFOLLOW flag behavior: - // the path could change between us checking it here and the later call to `open`. - // But it's good enough for Miri purposes. - #[cfg(not(unix))] - { - // O_NOFOLLOW only fails when the trailing component is a symlink; - // the entire rest of the path can still contain symlinks. - if path.is_symlink() { - return this.set_errno_and_return_neg1_i32(LibcError("ELOOP")); + nofollow = true; + cfg_select! { + unix => { + use std::os::unix::fs::OpenOptionsExt; + options.custom_flags(libc::O_NOFOLLOW); + } + windows => { + use std::os::windows::fs::OpenOptionsExt; + options.custom_flags( + windows_sys::Win32::Storage::FileSystem::FILE_FLAG_OPEN_REPARSE_POINT, + ); } } } @@ -552,11 +552,23 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { return this.set_errno_and_return_neg1_i32(ErrorKind::PermissionDenied); } - let fd = options - .open(path) - .map(|file| this.machine.fds.insert_new(FileHandle { file, writable, readable })); - - interp_ok(Scalar::from_i32(this.try_unwrap_io_result(fd)?)) + let file = match options.open(path) { + Ok(file) => file, + Err(err) => return this.set_errno_and_return_neg1_i32(err), + }; + let metadata = file.metadata().expect("a just-opened file should have metadata"); + if metadata.is_dir() { + throw_unsup_format!("open: opening directories is not supported"); + } + if nofollow && !cfg!(unix) { + // On Windows, FILE_FLAG_OPEN_REPARSE_POINT makes opening still succeed, it just + // opens the symlink rather than the target. Turn that into an error. + if metadata.is_symlink() { + return this.set_errno_and_return_neg1_i32(LibcError("ELOOP")); + } + } + let fd = this.machine.fds.insert_new(FileHandle { file, writable, readable }); + interp_ok(Scalar::from_i32(fd)) } fn lseek( @@ -618,15 +630,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { target_op: &OpTy<'tcx>, linkpath_op: &OpTy<'tcx>, ) -> InterpResult<'tcx, Scalar> { - #[cfg(unix)] fn create_link(src: &Path, dst: &Path) -> std::io::Result<()> { - std::os::unix::fs::symlink(src, dst) - } - - #[cfg(windows)] - fn create_link(src: &Path, dst: &Path) -> std::io::Result<()> { - use std::os::windows::fs; - if src.is_dir() { fs::symlink_dir(src, dst) } else { fs::symlink_file(src, dst) } + cfg_select! { + unix => std::os::unix::fs::symlink(src, dst), + windows => { + use std::os::windows::fs; + // This is racy, but not much we can do about that. + if src.is_dir() { + fs::symlink_dir(src, dst) + } else { + fs::symlink_file(src, dst) + } + } + } } let this = self.eval_context_mut(); @@ -766,7 +782,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Reject if isolation is enabled. if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op { this.reject_in_isolation("`fstat`", reject_with)?; - // Set error code as "EBADF" (bad fd) + // Set error code as "EBADF" (bad fd); "EACCESS" does not make much sense here. return this.set_errno_and_return_neg1_i32(LibcError("EBADF")); } @@ -777,6 +793,83 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { interp_ok(Scalar::from_i32(this.write_stat_buf(metadata, buf_op)?)) } + fn fstatat( + &mut self, + dirfd_op: &OpTy<'tcx>, + path_op: &OpTy<'tcx>, + buf_op: &OpTy<'tcx>, + flags_op: &OpTy<'tcx>, + ) -> InterpResult<'tcx, Scalar> { + let this = self.eval_context_mut(); + + if !matches!( + &this.tcx.sess.target.os, + Os::MacOs | Os::FreeBsd | Os::Solaris | Os::Illumos | Os::Linux | Os::Android + ) { + panic!("`fstatat` should not be called on {}", this.tcx.sess.target.os); + } + + let dirfd = this.read_scalar(dirfd_op)?.to_i32()?; + let path = this.read_pointer(path_op)?; + let flags = this.read_scalar(flags_op)?.to_i32()?; + + // Reject if isolation is enabled. + if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op { + this.reject_in_isolation("`fstatat`", reject_with)?; + return this.set_errno_and_return_neg1_i32(LibcError("EACCES")); + } + + // Parse flags. + let mut flags = flags; + // AT_SYMLINK_NOFOLLOW + let at_symlink_nofollow = this.eval_libc_i32("AT_SYMLINK_NOFOLLOW"); + let symlink_nofollow_flag = flags & at_symlink_nofollow == at_symlink_nofollow; + flags &= !at_symlink_nofollow; + // Complain about unknown flags. + if flags != 0 { + throw_unsup_format!("unsupported flags for `fstatat`: {flags:#x}") + } + + let path = this.read_path_from_c_str(path)?.into_owned(); + let metadata = if path.is_empty() { + throw_unsup_format!("fstatat: empty path is not supported"); + } else if path.is_absolute() || dirfd == this.eval_libc_i32("AT_FDCWD") { + // Either absolute path (dirfd is ignored) or relative to working directory. + FileMetadata::from_host( + this, + if symlink_nofollow_flag { path.symlink_metadata() } else { path.metadata() }, + )? + } else { + // relative to dirfd, which must be a directory handle + let Some(fd) = this.machine.fds.get(dirfd) else { + return this.set_errno_and_return_neg1_i32(LibcError("EBADF")); + }; + let Some(dir) = fd.downcast::() else { + return this.set_errno_and_return_neg1_i32(LibcError("EBADF")); + }; + + #[cfg(not(bootstrap))] + let metadata = if symlink_nofollow_flag { + dir.dir.symlink_metadata(path) + } else { + dir.dir.metadata(path) + }; + #[cfg(bootstrap)] + let metadata = if symlink_nofollow_flag { + dir.fallback.join(path).symlink_metadata() + } else { + dir.fallback.join(path).metadata() + }; + FileMetadata::from_host(this, metadata)? + }; + + let metadata = match metadata { + Ok(metadata) => metadata, + Err(err) => return this.set_errno_and_return_neg1_i32(err), + }; + interp_ok(Scalar::from_i32(this.write_stat_buf(metadata, buf_op)?)) + } + fn linux_statx( &mut self, dirfd_op: &OpTy<'tcx>, // Should be an `int` @@ -836,18 +929,30 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Either absolute path (dirfd is ignored) or relative to working directory. FileMetadata::from_host( this, - if symlink_nofollow_flag { fs::symlink_metadata(path) } else { fs::metadata(path) }, + if symlink_nofollow_flag { path.symlink_metadata() } else { path.metadata() }, )? } else { // relative to dirfd, which must be a directory handle let Some(fd) = this.machine.fds.get(dirfd) else { return this.set_errno_and_return_neg1_i32(LibcError("EBADF")); }; - let Some(_dir) = fd.downcast::() else { + let Some(dir) = fd.downcast::() else { return this.set_errno_and_return_neg1_i32(LibcError("EBADF")); }; - throw_unsup_format!("statx relative to a directory handle is not supported"); + #[cfg(not(bootstrap))] + let metadata = if symlink_nofollow_flag { + dir.dir.symlink_metadata(path) + } else { + dir.dir.metadata(path) + }; + #[cfg(bootstrap)] + let metadata = if symlink_nofollow_flag { + dir.fallback.join(path).symlink_metadata() + } else { + dir.fallback.join(path).metadata() + }; + FileMetadata::from_host(this, metadata)? }; let metadata = match metadata { @@ -1117,12 +1222,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // in between above and here. One day, the standard library will support converting // between `Dir` and `ReadDir` (one of the two directions would suffice for our // needs), then we'll use that. - let Ok(dir) = Dir::open(name) else { + let Ok(dir) = DirHandle::open(&name) else { throw_unsup_format!( "cannot `opendir` this directory: failed to create directory handle" ); }; - let dir = this.machine.fds.new_ref(DirHandle { dir }); + let dir = this.machine.fds.new_ref(dir); let dir_fd_id = dir.id(); let dir_fd_num = this.machine.fds.insert(dir); @@ -1859,9 +1964,6 @@ fn extract_sec_and_nsec<'tcx>( } fn file_type_to_mode_name(file_type: std::fs::FileType) -> &'static str { - #[cfg(unix)] - use std::os::unix::fs::FileTypeExt; - if file_type.is_file() { "S_IFREG" } else if file_type.is_dir() { @@ -1872,6 +1974,7 @@ fn file_type_to_mode_name(file_type: std::fs::FileType) -> &'static str { // Certain file types are only available when the host is a Unix system. #[cfg(unix)] { + use std::os::unix::fs::FileTypeExt; if file_type.is_socket() { return "S_IFSOCK"; } else if file_type.is_fifo() { diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs index b33de1b713fea..25ff4fe43b659 100644 --- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs @@ -65,6 +65,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let result = this.fstat(fd, buf)?; this.write_scalar(result, dest)?; } + "fstatat$INODE64" => { + let [dirfd, path, buf, flags] = this.check_shim_sig( + shim_sig!(extern "C" fn(i32, *_, *_, i32) -> i32), + (link_name, abi, args), + )?; + let result = this.fstatat(dirfd, path, buf, flags)?; + this.write_scalar(result, dest)?; + } "opendir$INODE64" => { let [name] = this.check_shim_sig_deprecated(abi, CanonAbi::C, link_name, args)?; let result = this.opendir(name)?; diff --git a/src/tools/miri/src/shims/unix/socket.rs b/src/tools/miri/src/shims/unix/socket.rs index 8c442df216a47..ce1f5c06b6b2c 100644 --- a/src/tools/miri/src/shims/unix/socket.rs +++ b/src/tools/miri/src/shims/unix/socket.rs @@ -10,14 +10,6 @@ use crate::shims::unix::socket_address::EvalContextExt as _; use crate::shims::unix::tcp_socket::TcpSocket; use crate::*; -#[derive(Debug, PartialEq)] -pub enum SocketFamily { - // IPv4 internet protocols - IPv4, - // IPv6 internet protocols - IPv6, -} - /// Represents unix-specific socket file descriptions. /// /// Not to be confused with Unix domain sockets. @@ -204,9 +196,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let family = if domain == this.eval_libc_i32("AF_INET") { - SocketFamily::IPv4 + socket2::Domain::IPV4 } else if domain == this.eval_libc_i32("AF_INET6") { - SocketFamily::IPv6 + socket2::Domain::IPV6 } else { throw_unsup_format!( "socket: domain {:#x} is unsupported, only AF_INET and \ @@ -229,8 +221,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); } + let socket = match TcpSocket::new(family, is_non_block) { + Ok(socket) => socket, + Err(e) => return this.set_errno_and_return_neg1_i32(e), + }; let fds = &mut this.machine.fds; - let fd = fds.new_ref(TcpSocket::new(family, is_non_block)); + let fd = fds.new_ref(socket); interp_ok(Scalar::from_i32(fds.insert(fd))) } diff --git a/src/tools/miri/src/shims/unix/tcp_socket.rs b/src/tools/miri/src/shims/unix/tcp_socket.rs index b59174cd71c2d..394f80a151f06 100644 --- a/src/tools/miri/src/shims/unix/tcp_socket.rs +++ b/src/tools/miri/src/shims/unix/tcp_socket.rs @@ -1,9 +1,9 @@ use std::cell::{Cell, RefCell, RefMut}; -use std::io; use std::io::Read; -use std::net::{Ipv4Addr, Shutdown, SocketAddr, SocketAddrV4}; +use std::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, SocketAddrV4, SocketAddrV6}; use std::sync::atomic::AtomicBool; use std::time::Duration; +use std::{io, mem}; use mio::event::Source; use mio::net::{TcpListener, TcpStream}; @@ -14,7 +14,7 @@ use rustc_target::spec::Os; use crate::shims::files::{EvalContextExt as _, FdNum, FileDescription, FileDescriptionRef}; use crate::shims::sig::Varargs; use crate::shims::unix::UnixFileDescription; -use crate::shims::unix::socket::{SocketFamily, UnixSocketFileDescription}; +use crate::shims::unix::socket::UnixSocketFileDescription; use crate::*; /// On Linux a TCP socket is initally in the TCP_CLOSE state: @@ -35,12 +35,10 @@ const INITIAL_TCP_SOCKET_READINESS: Readiness = #[derive(Debug)] enum SocketState { /// No syscall after `socket` has been made. - Initial, - /// The `bind` syscall has been called on the socket. - /// This is only reachable from the [`SocketState::Initial`] state. - Bound(SocketAddr), + Initial(socket2::Socket), /// The `listen` syscall has been called on the socket. - /// This is only reachable from the [`SocketState::Bound`] state. + /// This is reachable from the [`SocketState::Initial`] and the + /// [`SocketState::Listening`] states. Listening(TcpListener), /// The `connect` syscall has been called and we weren't yet able /// to ensure the connection is established. This is only reachable @@ -59,17 +57,45 @@ enum SocketState { /// and thus nothing (except destroying the socket) should be /// supported when a socket is in this state. ConnectionFailed(TcpStream), + /// The socket state machine is transitioning between two states + /// which contain an underlying host socket. This state is never + /// observable, it's only needed as a placeholder state to safely + /// acquire ownership of the underlying host socket. + // FIXME: This would not be needed with `replace_with`, but sadly + // this isn't part of the standard library and we don't want to add + // an extra dependency for this. + None, +} + +impl SocketState { + /// View the underlying host socket as a [`socket2::SockRef`]. + /// + /// **Note**: Potentially blocking operations need to be performed on the + /// underlying [`TcpStream`] and [`TcpListener`] as it would break the mio + /// poll on Windows hosts when performed directly on the [`socket2::SockRef`]. + fn as_socket_ref<'a>(&'a self) -> socket2::SockRef<'a> { + match self { + SocketState::Initial(socket) => socket.into(), + SocketState::Listening(listener) => listener.into(), + SocketState::Connecting(stream) + | SocketState::Connected(stream) + | SocketState::ConnectionFailed(stream) => stream.into(), + SocketState::None => unreachable!(), + } + } } #[derive(Debug)] pub(super) struct TcpSocket { /// Family of the socket, used to ensure socket only binds/connects to address of /// same family. - family: SocketFamily, + family: socket2::Domain, /// Current state of the inner socket. state: RefCell, /// Whether this fd is non-blocking or not. is_non_block: Cell, + /// Whether the socket is implicitly or explicitly bound to an address. + is_bound: Cell, /// The current blocking I/O readiness of the file description. io_readiness: RefCell, /// [`Some`] when the socket had an async error which has not yet been fetched via `SO_ERROR`. @@ -91,17 +117,41 @@ pub(super) struct TcpSocket { } impl TcpSocket { - pub fn new(family: SocketFamily, is_non_block: bool) -> Self { - TcpSocket { + pub fn new(family: socket2::Domain, is_non_block: bool) -> io::Result { + let socket = + socket2::Socket::new(family, socket2::Type::STREAM, Some(socket2::Protocol::TCP))?; + // The underlying host socket needs to be non-blocking. The actual + // blocking mode of the socket is stored in `is_non_block`. + socket.set_nonblocking(true)?; + + // We don't add the newly created socket to the blocking I/O manager + // until we can create a mio TcpStream or TcpListener because + // `socket2::Socket` doesn't implement `mio::Source`. + // This is fine since the readiness of a TCP socket (at least under Linux) + // does have a static initial readiness until `connect` or `listen` is + // invoked on it. + + Ok(TcpSocket { family, - state: RefCell::new(SocketState::Initial), + state: RefCell::new(SocketState::Initial(socket)), is_non_block: Cell::new(is_non_block), + is_bound: Cell::new(false), io_readiness: RefCell::new(INITIAL_TCP_SOCKET_READINESS), error: RefCell::new(None), read_timeout: Cell::new(None), write_timeout: Cell::new(None), watched: ReadinessWatched::default(), - } + }) + } + + /// Invoke `cb` with a [`socket2::SockRef`] to the underlying host socket. + /// + /// **Note**: Potentially blocking operations need to be performed on the + /// underlying [`TcpStream`] and [`TcpListener`] as it would break the mio + /// poll on Windows hosts when performed directly on the [`socket2::SockRef`]. + fn with_socket_ref(&self, cb: impl FnOnce(socket2::SockRef<'_>) -> T) -> T { + let state = self.state.borrow(); + cb(state.as_socket_ref()) } } @@ -251,54 +301,45 @@ impl UnixSocketFileDescription for TcpSocket { assert!(communicate_allowed, "cannot have `TcpSocket` with isolation enabled!"); ecx.ensure_not_failed(&self, "bind")?; - let mut state = self.state.borrow_mut(); + let address_family = match &address { + SocketAddr::V4(_) => socket2::Domain::IPV4, + SocketAddr::V6(_) => socket2::Domain::IPV6, + }; - match *state { - SocketState::Initial => { - let address_family = match &address { - SocketAddr::V4(_) => SocketFamily::IPv4, - SocketAddr::V6(_) => SocketFamily::IPv6, - }; + if self.family != address_family { + // Attempted to bind an address from a family that doesn't match + // the family of the socket. + let err = if matches!(ecx.tcx.sess.target.os, Os::Linux | Os::Android) { + // Linux man page states that `EINVAL` is used when there is an address family mismatch. + // See + LibcError("EINVAL") + } else { + // POSIX man page states that `EAFNOSUPPORT` should be used when there is an address + // family mismatch. + // See + LibcError("EAFNOSUPPORT") + }; + return interp_ok(Err(err)); + } - if self.family != address_family { - // Attempted to bind an address from a family that doesn't match - // the family of the socket. - let err = if matches!(ecx.tcx.sess.target.os, Os::Linux | Os::Android) { - // Linux man page states that `EINVAL` is used when there is an address family mismatch. - // See - LibcError("EINVAL") - } else { - // POSIX man page states that `EAFNOSUPPORT` should be used when there is an address - // family mismatch. - // See - LibcError("EAFNOSUPPORT") - }; - return interp_ok(Err(err)); - } + let state = self.state.borrow(); + let socket = state.as_socket_ref(); - *state = SocketState::Bound(address); - } - SocketState::Connecting(_) | SocketState::Connected(_) => - throw_unsup_format!( - "bind: tcp socket is already connected and binding a - connected socket is unsupported" - ), - SocketState::Bound(_) | SocketState::Listening(_) => - throw_unsup_format!( - "bind: tcp socket is already bound and binding a socket \ - multiple times is unsupported" - ), - SocketState::ConnectionFailed(_) => unreachable!(), + // `bind` is a non-blocking operation for TCP sockets. + if let Err(e) = socket.bind(&socket2::SockAddr::from(address)) { + return interp_ok(Err(IoError::HostError(e))); } + // The socket has been explicitly bound to a local address. + self.is_bound.set(true); + interp_ok(Ok(())) } fn listen<'tcx>( self: FileDescriptionRef, communicate_allowed: bool, - // Since the backlog value is just a performance hint we can ignore it. - _backlog: i32, + backlog: i32, ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, Result<(), IoError>> { assert!(communicate_allowed, "cannot have `TcpSocket` with isolation enabled!"); @@ -306,43 +347,111 @@ impl UnixSocketFileDescription for TcpSocket { let mut state = self.state.borrow_mut(); - match *state { - SocketState::Bound(socket_addr) => - match TcpListener::bind(socket_addr) { - Ok(listener) => { - *state = SocketState::Listening(listener); - drop(state); - - // After invoking `listen` on a TCP socket, it transitions out of the - // TCP_CLOSE state which affects the socket's readiness. Because we - // register the socket afterwards to the blocking I/O manager, we just - // clear its readiness here as the blocking I/O manager will update its - // readiness accordingly. - self.io_readiness.replace(Readiness::EMPTY); - ecx.update_fd_readiness(self.clone(), ReadinessUpdateFlags::DEFAULT)?; - - // Register the socket to the blocking I/O manager because - // we now have an associated host socket. - ecx.machine.blocking_io.register(self); - } - Err(e) => return interp_ok(Err(IoError::HostError(e))), - }, - SocketState::Initial => { - throw_unsup_format!( - "listen: listening on a tcp socket which isn't bound is unsupported" - ) - } - SocketState::Listening(_) => { - throw_unsup_format!( - "listen: listening on a tcp socket multiple times is unsupported" - ) - } - SocketState::Connecting(_) | SocketState::Connected(_) => { - throw_unsup_format!("listen: listening on a connected tcp socket is unsupported") + // We'll only attempt to invoke `listen` on the socket if it's not already + // connected because POSIX specifies that EINVAL should be returned in this + // case. + let socket = match &*state { + SocketState::Initial(_) | SocketState::Listening(_) => state.as_socket_ref(), + // POSIX states that connected sockets cannot start listening, + // so we can return early here to simplify the remaining shim. + SocketState::Connecting(_) | SocketState::Connected(_) => + return interp_ok(Err(LibcError("EINVAL"))), + SocketState::ConnectionFailed(_) | SocketState::None => unreachable!(), + }; + + // Despite not being specified by POSIX, on most of our supported Unix-like platforms + // (confirmed on Linux, macOS, FreeBSD, and Solaris) TCP sockets get implicitly bound + // to the unspecified address at a random port when `listen` is invoked on an unbound + // socket. Thus, Miri models the same non-POSIX behavior and treats a socket as bound + // once `listen` has successfully been invoked on an unbound socket. + + if cfg!(windows) && !self.is_bound.get() { + // Implicitly binding a TCP socket by invoking `listen` on an + // unbound socket causes EINVAL on Windows hosts. We thus + // explicitly bind the socket to an unspecified address with + // a random port before listening. + // + // When the subsequent `listen` fails we behave incorrectly + // because a previously unbound socket is now bound. However, + // since `listen` can only fail for system resource errors + // (e.g., ENOBUFS) this isn't a problem in reality. + + let address = if self.family == socket2::Domain::IPV4 { + SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, /* port */ 0)) + } else { + SocketAddr::V6(SocketAddrV6::new( + Ipv6Addr::UNSPECIFIED, + /* port */ 0, + /* flowinfo */ 0, + /* scope_id */ 0, + )) + }; + + if let Err(e) = socket.bind(&socket2::SockAddr::from(address)) { + return interp_ok(Err(IoError::HostError(e))); } - SocketState::ConnectionFailed(_) => unreachable!(), + + // We just explicitly bound the socket to a local address. + self.is_bound.set(true); } + if let Err(e) = socket.listen(backlog) { + return interp_ok(Err(IoError::HostError(e))); + } + + // As mentioned above, we treat listening sockets as implicitly bound to a + // local address if they weren't already bound before the `listen` invocation. + self.is_bound.set(true); + + if let SocketState::Listening(_) = &*state { + // The socket was already listening; we just changed the backlog. + // The socket is already registered to the blocking I/O manager + // and we also don't need to perform a state transition. + return interp_ok(Ok(())); + } + + // Temporarily use dummy state to take ownership of the underlying socket. + let SocketState::Initial(socket) = mem::replace(&mut *state, SocketState::None) else { + unreachable!() + }; + + // FIXME: Rustfmt has a bug where it incorrectly removes the outer braces of {{ .. }} inside + // a `cfg_select!` block. See . + #[rustfmt::skip] + let listener = cfg_select! { + // Turn the `socket2::Socket` into a `mio::TcpListener`. + // We follow Tokio's TCP socket implementation: + // See + // SAFETY: mio specifies that it is safe to use `from_raw_fd` and + // `from_raw_socket` as long as it's ensured that the socket is non-blocking. + // Because we immediately make the socket non-blocking after creation, that + // is always guaranteed. + + unix => {{ + use std::os::fd::{IntoRawFd, FromRawFd}; + let raw_fd = socket.into_raw_fd(); + unsafe { TcpListener::from_raw_fd(raw_fd) } + }}, + windows => {{ + use std::os::windows::io::{IntoRawSocket, FromRawSocket}; + let raw_socket = socket.into_raw_socket(); + unsafe { TcpListener::from_raw_socket(raw_socket) } + }}, + _ => unreachable!("unsupported host platform") + }; + + *state = SocketState::Listening(listener); + drop(state); + + // Clear the "artificial" readiness as we are about to put the blocking + // I/O manager in charge of handling readiness. + self.io_readiness.replace(Readiness::EMPTY); + ecx.update_fd_readiness(self.clone(), ReadinessUpdateFlags::DEFAULT)?; + + // Register the socket to the blocking I/O manager. Can only happen + // now that we have created a mio TcpListener. + ecx.machine.blocking_io.register(self); + interp_ok(Ok(())) } @@ -394,52 +503,110 @@ impl UnixSocketFileDescription for TcpSocket { assert!(communicate_allowed, "cannot have `TcpSocket` with isolation enabled!"); ecx.ensure_not_failed(&self, "connect")?; - match &*self.state.borrow() { - SocketState::Initial => { /* fall-through to below */ } + let mut state = self.state.borrow_mut(); + + // We'll only attempt to invoke `connect` on the socket if it's not already + // connected or listening because POSIX specifies error codes which should + // be returned in those cases. + let socket = match &*state { + SocketState::Initial(socket) => socket, + SocketState::Listening(_) => { + let err = if matches!(ecx.tcx.sess.target.os, Os::Linux | Os::Android) { + // Linux-like targets return EISCONN when attempting to invoke + // `connect` on an already listening socket. + // See + LibcError("EISCONN") + } else { + // POSIX specifies to return EOPNOTSUPP when attempting to invoke + // `connect` on an already listening socket. + // See + LibcError("EOPNOTSUPP") + }; + return finish.call(ecx, Err(err)); + } + // The socket is already connected. + // Subsequent connection attempts return EISCONN for TCP sockets. + SocketState::Connected(_) => return finish.call(ecx, Err(LibcError("EISCONN"))), // The socket is already in a connecting state. + // Subsequent connection attempts return EALREADY for TCP sockets. SocketState::Connecting(_) => return finish.call(ecx, Err(LibcError("EALREADY"))), - // We don't return EISCONN for already connected sockets, for which we're - // sure that the connection is established, since TCP sockets are usually - // allowed to be connected multiple times. - _ => - throw_unsup_format!( - "connect: connecting is only supported for tcp sockets which are neither \ - bound, listening nor already connected" - ), + SocketState::ConnectionFailed(_) | SocketState::None => unreachable!(), + }; + + let result = socket.connect(&socket2::SockAddr::from(address)); + + // Boolean whether the connection attempt "failed" because it could not be + // completed immediately without blocking. + let is_in_progress = result.as_ref().is_err_and(|e| { + // On Windows hosts non-blocking connects fail with EWOULDBLOCK when the connection cannot + // be established immediately, while on Unix-like hosts they fail with EINPROGRESS. + matches!(e.kind(), io::ErrorKind::WouldBlock | io::ErrorKind::InProgress) + }); + + if !is_in_progress && let Err(e) = result { + // There was a "real" error during connection establishment. + return finish.call(ecx, Err(IoError::HostError(e))); } - // This begins establishing the connection, but does not block until the stream is fully connected. - // We deal with that below. - match TcpStream::connect(address) { - Ok(stream) => { - *self.state.borrow_mut() = SocketState::Connecting(stream); - - // After invoking `connect` on a TCP socket, it transitions out of the - // TCP_CLOSE state which affects the socket's readiness. Because we - // register the socket afterwards to the blocking I/O manager, we just - // clear its readiness here as the blocking I/O manager will update its - // readiness accordingly. - self.io_readiness.replace(Readiness::EMPTY); - ecx.update_fd_readiness(self.clone(), ReadinessUpdateFlags::DEFAULT)?; - - // Register the socket to the blocking I/O manager because - // we now have an associated host socket. - ecx.machine.blocking_io.register(self.clone()); - } - Err(e) => return finish.call(ecx, Err(IoError::HostError(e))), + // Temporarily use dummy state to take ownership of the underlying socket. + let SocketState::Initial(socket) = mem::replace(&mut *state, SocketState::None) else { + unreachable!() }; + // FIXME: Rustfmt has a bug where it incorrectly removes the outer braces of {{ .. }} inside + // a `cfg_select!` block. See . + #[rustfmt::skip] + let stream = cfg_select! { + // Turn the `socket2::Socket` into a `mio::TcpStream`. + // We follow Tokio's TCP socket implementation: + // See + // SAFETY: mio specifies that it is safe to use `from_raw_fd` and + // `from_raw_socket` as long as it's ensured that the socket is non-blocking. + // Because we immediately make the socket non-blocking after creation, that + // is always guaranteed. + + unix => {{ + use std::os::fd::{IntoRawFd, FromRawFd}; + let raw_fd = socket.into_raw_fd(); + unsafe { TcpStream::from_raw_fd(raw_fd) } + }}, + windows => {{ + use std::os::windows::io::{IntoRawSocket, FromRawSocket}; + let raw_socket = socket.into_raw_socket(); + unsafe { TcpStream::from_raw_socket(raw_socket) } + }}, + _ => unreachable!("unsupported host platform") + }; + + *state = SocketState::Connecting(stream); + drop(state); + + // Connecting sockets are implicitly bound to a local address. + self.is_bound.set(true); + + // Clear the "artificial" readiness as we are about to put the blocking + // I/O manager in charge of handling readiness. + self.io_readiness.replace(Readiness::EMPTY); + ecx.update_fd_readiness(self.clone(), ReadinessUpdateFlags::DEFAULT)?; + + // Register the socket to the blocking I/O manager. Can only happen + // now that we have created a mio TcpStream. + ecx.machine.blocking_io.register(self.clone()); + if self.is_non_block.get() { // We have a non-blocking socket and thus don't want to block until // the connection is established. - // Since the [`TcpStream::connect`] function of mio hides the EINPROGRESS - // we just always return EINPROGRESS and check whether the connection succeeded - // once we want to use the connected socket. - finish.call(ecx, Err(LibcError("EINPROGRESS"))) + if is_in_progress { + finish.call(ecx, Err(LibcError("EINPROGRESS"))) + } else { + finish.call(ecx, Ok(())) + } } else { // The socket is in blocking mode and thus the connect call should block - // until the connection with the server is established. + // until the connection with the server is established. A potential + // EWOULDBLOCK or EINPROGRESS error code is ignored as we emulate a + // blocking socket. if self.write_timeout.get().is_some() { // Some Unixes like Linux also apply the SO_SNDTIMEO socket option @@ -647,19 +814,7 @@ impl UnixSocketFileDescription for TcpSocket { let option_value = ecx.ptr_to_mplace(value_ptr, ecx.machine.layouts.u32); let ttl = ecx.read_scalar(&option_value)?.to_u32()?; - let result = match &*self.state.borrow() { - SocketState::Initial | SocketState::Bound(_) => - throw_unsup_format!( - "setsockopt: setting option IP_TTL on level IPPROTO_IP is only supported \ - on connected and listening tcp sockets" - ), - SocketState::Listening(listener) => listener.set_ttl(ttl), - SocketState::Connecting(stream) | SocketState::Connected(stream) => - stream.set_ttl(ttl), - SocketState::ConnectionFailed(_) => unreachable!(), - }; - - return match result { + return match self.with_socket_ref(|s| s.set_ttl_v4(ttl)) { Ok(_) => interp_ok(Ok(())), Err(e) => interp_ok(Err(IoError::HostError(e))), }; @@ -679,18 +834,7 @@ impl UnixSocketFileDescription for TcpSocket { let option_value = ecx.ptr_to_mplace(value_ptr, ecx.machine.layouts.i32); let nodelay = ecx.read_scalar(&option_value)?.to_i32()? != 0; - let result = match &*self.state.borrow() { - SocketState::Initial | SocketState::Bound(_) | SocketState::Listening(_) => - throw_unsup_format!( - "setsockopt: setting option TCP_NODELAY on level IPPROTO_TCP is only supported \ - on connected tcp sockets" - ), - SocketState::Connecting(stream) | SocketState::Connected(stream) => - stream.set_nodelay(nodelay), - SocketState::ConnectionFailed(_) => unreachable!(), - }; - - return match result { + return match self.with_socket_ref(|s| s.set_tcp_nodelay(nodelay)) { Ok(_) => interp_ok(Ok(())), Err(e) => interp_ok(Err(IoError::HostError(e))), }; @@ -772,19 +916,7 @@ impl UnixSocketFileDescription for TcpSocket { let opt_ip_ttl = ecx.eval_libc_i32("IP_TTL"); if option == opt_ip_ttl { - let ttl = match &*self.state.borrow() { - SocketState::Initial | SocketState::Bound(_) => - throw_unsup_format!( - "getsockopt: reading option IP_TTL on level IPPROTO_IP is only supported \ - on connected and listening tcp sockets" - ), - SocketState::Listening(listener) => listener.ttl(), - SocketState::Connecting(stream) | SocketState::Connected(stream) => - stream.ttl(), - SocketState::ConnectionFailed(_) => unreachable!(), - }; - - let ttl = match ttl { + let ttl = match self.with_socket_ref(|s| s.ttl_v4()) { Ok(ttl) => ttl, Err(e) => return interp_ok(Err(IoError::HostError(e))), }; @@ -802,18 +934,7 @@ impl UnixSocketFileDescription for TcpSocket { let opt_tcp_nodelay = ecx.eval_libc_i32("TCP_NODELAY"); if option == opt_tcp_nodelay { - let nodelay = match &*self.state.borrow() { - SocketState::Initial | SocketState::Bound(_) | SocketState::Listening(_) => - throw_unsup_format!( - "getsockopt: reading option TCP_NODELAY on level IPPROTO_TCP is only supported \ - on connected tcp sockets" - ), - SocketState::Connecting(stream) | SocketState::Connected(stream) => - stream.nodelay(), - SocketState::ConnectionFailed(_) => unreachable!(), - }; - - let nodelay = match nodelay { + let nodelay = match self.with_socket_ref(|s| s.tcp_nodelay()) { Ok(nodelay) => nodelay, Err(e) => return interp_ok(Err(IoError::HostError(e))), }; @@ -843,52 +964,45 @@ impl UnixSocketFileDescription for TcpSocket { assert!(communicate_allowed, "cannot have `TcpSocket` with isolation enabled!"); ecx.ensure_not_failed(&self, "getsockname")?; - let state = self.state.borrow(); + if !self.is_bound.get() { + // Since Windows returns EINVAL when invoking `getsockname` on + // a socket which hasn't been bound yet, we need to manually + // return an unspecified address here. - let address = match &*state { - SocketState::Bound(address) => { - if address.port() == 0 { - // The socket is bound to a zero-port which means it gets assigned a random - // port. Since we don't yet have an underlying socket, we don't know what this - // random port will be and thus this is unsupported. - throw_unsup_format!( - "getsockname: when the port is 0, getting the tcp socket address before \ - calling `listen` or `connect` is unsupported" - ) - } + let address = if self.family == socket2::Domain::IPV4 { + SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, /* port */ 0)) + } else { + SocketAddr::V6(SocketAddrV6::new( + Ipv6Addr::UNSPECIFIED, + /* port */ 0, + /* flowinfo */ 0, + /* scope_id */ 0, + )) + }; + return interp_ok(Ok(address)); + } - *address - } - SocketState::Listening(listener) => - match listener.local_addr() { - Ok(address) => address, - Err(e) => return interp_ok(Err(IoError::HostError(e))), - }, - SocketState::Connecting(stream) | SocketState::Connected(stream) => { - if cfg!(windows) && matches!(&*state, SocketState::Connecting(_)) { - // FIXME: On Windows hosts `TcpStream::local_addr` returns `0.0.0.0:0` whilst - // the socket is connecting: - // - // This is problematic because UNIX targets could expect a real local address even - // for a connecting non-blocking socket. - - static DEDUP: AtomicBool = AtomicBool::new(false); - if !DEDUP.swap(true, std::sync::atomic::Ordering::Relaxed) { - ecx.emit_diagnostic(NonHaltingDiagnostic::ConnectingSocketGetsockname); - } - } - match stream.local_addr() { - Ok(address) => address, - Err(e) => return interp_ok(Err(IoError::HostError(e))), - } + let state = self.state.borrow(); + let socket = state.as_socket_ref(); + + if cfg!(windows) + && let SocketState::Connecting(_) = &*state + { + // FIXME: On Windows hosts `getsockname` returns `0.0.0.0:0` whilst the socket is connecting: + // + // This is problematic because UNIX targets could expect a real local address even + // for a connecting non-blocking socket. + + static DEDUP: AtomicBool = AtomicBool::new(false); + if !DEDUP.swap(true, std::sync::atomic::Ordering::Relaxed) { + ecx.emit_diagnostic(NonHaltingDiagnostic::ConnectingSocketGetsockname); } - // For non-bound sockets the POSIX manual says the returned address is unspecified. - // Often this is 0.0.0.0:0 and thus we set it to this value. - SocketState::Initial => SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0)), - SocketState::ConnectionFailed(_) => unreachable!(), - }; + } - interp_ok(Ok(address)) + match socket.local_addr() { + Ok(address) => interp_ok(Ok(address.as_socket().unwrap())), + Err(e) => interp_ok(Err(IoError::HostError(e))), + } } fn getpeername<'tcx>( @@ -1077,14 +1191,16 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { }; let family = match addr { - SocketAddr::V4(_) => SocketFamily::IPv4, - SocketAddr::V6(_) => SocketFamily::IPv6, + SocketAddr::V4(_) => socket2::Domain::IPV4, + SocketAddr::V6(_) => socket2::Domain::IPV6, }; let fd = this.machine.fds.new_ref(TcpSocket { family, state: RefCell::new(SocketState::Connected(stream)), is_non_block: Cell::new(is_client_sock_nonblock), + // Connected sockets are implicitly bound to a local address. + is_bound: Cell::new(true), io_readiness: RefCell::new(Readiness::EMPTY), error: RefCell::new(None), read_timeout: Cell::new(None), @@ -1481,16 +1597,17 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // In other words, we are assuming that there will be no spurious // wakeups while establishing the connection. - // The connection is established. + // The connection is established. Update the state. + let mut state = socket.state.borrow_mut(); // Temporarily use dummy state to take ownership of the stream. - let mut state = socket.state.borrow_mut(); - let SocketState::Connecting(stream) = std::mem::replace(&mut*state, SocketState::Initial) else { + let SocketState::Connecting(stream) = mem::replace(&mut *state, SocketState::None) else { // At the start of the function we ensured that we're currently connecting. unreachable!() }; *state = SocketState::Connected(stream); drop(state); + action.call(this, Ok(())) } ), @@ -1525,14 +1642,8 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn update_last_error(&self, socket: &FileDescriptionRef) { let mut state = socket.state.borrow_mut(); - let new_error = match &*state { - SocketState::Listening(listener) => - listener.take_error().expect("Reading SO_ERROR should not fail"), - SocketState::Connecting(stream) | SocketState::Connected(stream) => - stream.take_error().expect("Reading SO_ERROR should not fail"), - SocketState::Initial | SocketState::Bound(_) | SocketState::ConnectionFailed(_) => None, - }; - + let new_error = + state.as_socket_ref().take_error().expect("Reading SO_ERROR should not fail"); let Some(new_error) = new_error else { return }; // Store the error such that we can return it when @@ -1546,8 +1657,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // We thus change the socket state to `ConnectionFailed`. // Temporarily use dummy state to take ownership of the stream. - let SocketState::Connecting(stream) = - std::mem::replace(&mut *state, SocketState::Initial) + let SocketState::Connecting(stream) = mem::replace(&mut *state, SocketState::None) else { unreachable!() }; diff --git a/src/tools/miri/src/shims/windows/fs.rs b/src/tools/miri/src/shims/windows/fs.rs index bab26d80dee70..6fc9d37070f67 100644 --- a/src/tools/miri/src/shims/windows/fs.rs +++ b/src/tools/miri/src/shims/windows/fs.rs @@ -1,7 +1,6 @@ -use std::fs::{self, Dir}; -use std::io; use std::io::SeekFrom; use std::time::SystemTime; +use std::{fs, io}; use bitflags::bitflags; use rustc_abi::Size; @@ -214,7 +213,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Open this as a directory. // FIXME: shouldn't we check `creation_disposition` here? We do know that it already // exists. - let dir = match Dir::open(&file_name) { + let dir = match DirHandle::open(&file_name) { Ok(dir) => dir, Err(e) => { if e.kind() == io::ErrorKind::NotADirectory { @@ -226,9 +225,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } }; #[cfg(bootstrap)] - let metadata = dir.metadata(); + let metadata = dir.dir.metadata(); #[cfg(not(bootstrap))] - let metadata = dir.self_metadata(); + let metadata = dir.dir.self_metadata(); if !metadata.unwrap().is_dir() { // This changed from a directory to a file. Retry. continue; @@ -239,7 +238,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.set_last_error(IoError::WindowsError("ERROR_ALREADY_EXISTS"))?; } - let fd_num = this.machine.fds.insert_new(DirHandle { dir }); + let fd_num = this.machine.fds.insert_new(dir); return interp_ok(Handle::File(fd_num)); } else { // Per the documentation: @@ -381,7 +380,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let attributes = if file_type.is_dir() { this.eval_windows_u32("c", "FILE_ATTRIBUTE_DIRECTORY") } else if file_type.is_file() { - this.eval_windows_u32("c", "FILE_ATTRIBUTE_NORMAL") + // Normal files seem to have the "archive" attribute. There's also + // `FILE_ATTRIBUTE_NORMAL` but that's for files without any other attribute which, + // apparently, is not normal. + this.eval_windows_u32("c", "FILE_ATTRIBUTE_ARCHIVE") } else { this.eval_windows_u32("c", "FILE_ATTRIBUTE_DEVICE") }; diff --git a/src/tools/miri/tests/deps/Cargo.toml b/src/tools/miri/tests/deps/Cargo.toml index a377141f98aaf..6b6d4a9e2f443 100644 --- a/src/tools/miri/tests/deps/Cargo.toml +++ b/src/tools/miri/tests/deps/Cargo.toml @@ -37,3 +37,7 @@ windows-sys = { version = "0.61", features = [ # Make sure we are not part of the rustc workspace. [workspace] members = ["cross-crate-items"] + +[lints.cargo] +# Not all tests use all of the above dependencies +unused_dependencies = "allow" diff --git a/src/tools/miri/tests/deps/cross-crate-items/Cargo.toml b/src/tools/miri/tests/deps/cross-crate-items/Cargo.toml index 1f9fc93cd5237..ca6818dc0fe25 100644 --- a/src/tools/miri/tests/deps/cross-crate-items/Cargo.toml +++ b/src/tools/miri/tests/deps/cross-crate-items/Cargo.toml @@ -5,3 +5,7 @@ edition = "2021" [dependencies] futures = { version = "0.3.0", default-features = false, features = ["alloc", "async-await"] } + +[lints.cargo] +# panic_abort is not directly used but must be linked in +unused_dependencies = "allow" diff --git a/src/tools/miri/tests/fail-dep/libc/dirfd-closed.rs b/src/tools/miri/tests/fail-dep/libc/dirfd-closed.rs index 7cab24bc4d4d9..b34a36babb2a9 100644 --- a/src/tools/miri/tests/fail-dep/libc/dirfd-closed.rs +++ b/src/tools/miri/tests/fail-dep/libc/dirfd-closed.rs @@ -1,9 +1,7 @@ //@ignore-target: windows # no libc //@compile-flags: -Zmiri-disable-isolation -use std::ffi::CString; use std::fs::create_dir; -use std::os::unix::ffi::OsStrExt; #[path = "../../utils/mod.rs"] mod utils; @@ -16,7 +14,7 @@ use libc_utils::errno_check; fn main() { let path = utils::prepare_dir("miri_test_libc_dirfd_closed"); create_dir(&path).expect("create_dir failed"); - let cpath = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); + let cpath = utils::into_c_string(path); let dir: *mut libc::DIR = unsafe { libc::opendir(cpath.as_ptr()) }; assert!(!dir.is_null()); diff --git a/src/tools/miri/tests/fail-dep/libc/dirfd-replaced.rs b/src/tools/miri/tests/fail-dep/libc/dirfd-replaced.rs index e5e2336e96d63..dd6d404874401 100644 --- a/src/tools/miri/tests/fail-dep/libc/dirfd-replaced.rs +++ b/src/tools/miri/tests/fail-dep/libc/dirfd-replaced.rs @@ -1,9 +1,7 @@ //@ignore-target: windows # no libc //@compile-flags: -Zmiri-disable-isolation -use std::ffi::CString; use std::fs::create_dir; -use std::os::unix::ffi::OsStrExt; #[path = "../../utils/mod.rs"] mod utils; @@ -16,7 +14,7 @@ use libc_utils::{errno_check, errno_result}; fn main() { let path = utils::prepare_dir("miri_test_libc_dirfd_replaced"); create_dir(&path).expect("create_dir failed"); - let cpath = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); + let cpath = utils::into_c_string(path); let dir: *mut libc::DIR = unsafe { libc::opendir(cpath.as_ptr()) }; assert!(!dir.is_null()); diff --git a/src/tools/miri/tests/fail-dep/libc/libc-read-and-uninit-premature-eof.rs b/src/tools/miri/tests/fail-dep/libc/libc-read-and-uninit-premature-eof.rs index 4400d52e59d6c..aa9cbe4298105 100644 --- a/src/tools/miri/tests/fail-dep/libc/libc-read-and-uninit-premature-eof.rs +++ b/src/tools/miri/tests/fail-dep/libc/libc-read-and-uninit-premature-eof.rs @@ -4,7 +4,6 @@ // Short FD ops can affect the exact error message here //@compile-flags: -Zmiri-disable-isolation -Zmiri-no-short-fd-operations -use std::ffi::CString; use std::fs::remove_file; use std::mem::MaybeUninit; @@ -16,8 +15,8 @@ mod libc_utils; fn main() { let path = - utils::prepare_with_content("fail-libc-read-and-uninit-premature-eof.txt", &[1u8, 2, 3]); - let cpath = CString::new(path.clone().into_os_string().into_encoded_bytes()).unwrap(); + utils::prepare_with_content("miri-libc-read-and-uninit-premature-eof.txt", &[1u8, 2, 3]); + let cpath = utils::into_c_string(&path); unsafe { let fd = libc::open(cpath.as_ptr(), libc::O_RDONLY); assert_ne!(fd, -1); diff --git a/src/tools/miri/tests/fail-dep/libc/open_wrong_var_arg_type.rs b/src/tools/miri/tests/fail-dep/libc/open_wrong_var_arg_type.rs index 3382670b50f18..39d2acffc0708 100644 --- a/src/tools/miri/tests/fail-dep/libc/open_wrong_var_arg_type.rs +++ b/src/tools/miri/tests/fail-dep/libc/open_wrong_var_arg_type.rs @@ -4,13 +4,10 @@ #![allow(invalid_runtime_symbol_definitions)] -use std::ffi::{CString, OsStr}; -use std::os::unix::ffi::OsStrExt; - use libc::open; fn main() { - let c_path = CString::new(OsStr::new("./text").as_bytes()).expect("CString::new failed"); + let c_path = c"./text"; let _fd = unsafe { open(c_path.as_ptr(), libc::O_CREAT, /* should be mode_t */ 0u64) //~^ ERROR: /expected argument #3 to have type `(u32|i32)` but got incompatible type `u64`/ diff --git a/src/tools/miri/tests/fail/shims/input_arg_mismatch.rs b/src/tools/miri/tests/fail/shims/input_arg_mismatch.rs index d355da73174e9..5fa07989c895f 100644 --- a/src/tools/miri/tests/fail/shims/input_arg_mismatch.rs +++ b/src/tools/miri/tests/fail/shims/input_arg_mismatch.rs @@ -3,8 +3,7 @@ #![allow(suspicious_runtime_symbol_definitions)] -use std::ffi::{CString, OsStr, c_char, c_int}; -use std::os::unix::ffi::OsStrExt; +use std::ffi::{c_char, c_int}; extern "C" { fn open(path: *const c_char, oflag: c_int, ...) -> c_int; @@ -13,7 +12,7 @@ extern "C" { } fn main() { - let c_path = CString::new(OsStr::new("./text").as_bytes()).expect("CString::new failed"); + let c_path = c"./text"; let fd = unsafe { open(c_path.as_ptr(), /* value does not matter */ 0) } as u32; diff --git a/src/tools/miri/tests/fail/shims/return_type_mismatch.rs b/src/tools/miri/tests/fail/shims/return_type_mismatch.rs index bcde5d8040f59..1b22dfbd44872 100644 --- a/src/tools/miri/tests/fail/shims/return_type_mismatch.rs +++ b/src/tools/miri/tests/fail/shims/return_type_mismatch.rs @@ -3,8 +3,7 @@ #![allow(suspicious_runtime_symbol_definitions)] -use std::ffi::{CString, OsStr, c_char, c_int, c_short}; -use std::os::unix::ffi::OsStrExt; +use std::ffi::{c_char, c_int, c_short}; extern "C" { fn open(path: *const c_char, oflag: c_int, ...) -> c_int; @@ -13,7 +12,7 @@ extern "C" { } fn main() { - let c_path = CString::new(OsStr::new("./text").as_bytes()).expect("CString::new failed"); + let c_path = c"./text"; let fd = unsafe { open(c_path.as_ptr(), /* value does not matter */ 0) }; diff --git a/src/tools/miri/tests/fail/shims/vararg_callee_signature_mismatch.rs b/src/tools/miri/tests/fail/shims/vararg_callee_signature_mismatch.rs index ce0c6c289faf0..c00a1f0b22814 100644 --- a/src/tools/miri/tests/fail/shims/vararg_callee_signature_mismatch.rs +++ b/src/tools/miri/tests/fail/shims/vararg_callee_signature_mismatch.rs @@ -3,8 +3,7 @@ #![allow(invalid_runtime_symbol_definitions)] -use std::ffi::{CString, OsStr, c_char, c_int}; -use std::os::unix::ffi::OsStrExt; +use std::ffi::{c_char, c_int}; // Declare a variadic function as non-variadic. extern "C" { @@ -12,7 +11,7 @@ extern "C" { } fn main() { - let c_path = CString::new(OsStr::new("./text").as_bytes()).expect("CString::new failed"); + let c_path = c"./text"; let _fd = unsafe { open(c_path.as_ptr(), /* value does not matter */ 0) //~^ ERROR: is a c-variadic function, but the caller is using a non-variadic signature diff --git a/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.rs b/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.rs index 34f6ae24f3e1d..f4e7a02b838fa 100644 --- a/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.rs +++ b/src/tools/miri/tests/fail/shims/wrong_fixed_arg_count.rs @@ -3,15 +3,14 @@ #![allow(invalid_runtime_symbol_definitions)] -use std::ffi::{CString, OsStr, c_char, c_int}; -use std::os::unix::ffi::OsStrExt; +use std::ffi::{c_char, c_int}; extern "C" { fn open(path: *const c_char, ...) -> c_int; } fn main() { - let c_path = CString::new(OsStr::new("./text").as_bytes()).expect("CString::new failed"); + let c_path = c"./text"; let _fd = unsafe { open(c_path.as_ptr(), /* value does not matter */ 0) //~^ ERROR: takes 2 fixed (non-variadic) arguments, but 1 argument was given diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs-permissions.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs-permissions.rs index 819717fed8523..dd79c96e179c8 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-fs-permissions.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-fs-permissions.rs @@ -3,9 +3,8 @@ //@compile-flags: -Zmiri-disable-isolation //@run-native -use std::ffi::{CStr, CString}; +use std::ffi::CStr; use std::mem::MaybeUninit; -use std::os::unix::ffi::OsStrExt; #[path = "../../utils/mod.rs"] mod utils; @@ -28,7 +27,7 @@ fn getmod(path: &CStr) -> u32 { fn test_chmod() { let path = utils::prepare_with_content("miri_test_libc_chmod.txt", b"abcdef"); - let c_path = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); + let c_path = utils::into_c_string(path); unsafe { errno_check(libc::chmod(c_path.as_ptr(), 0o777)) }; assert_eq!(getmod(&c_path), 0o777); @@ -38,7 +37,7 @@ fn test_chmod() { fn test_fchmod() { let path = utils::prepare_with_content("miri_test_libc_chmod.txt", b"abcdef"); - let c_path = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); + let c_path = utils::into_c_string(path); let fd = unsafe { errno_result(libc::open(c_path.as_ptr(), libc::O_RDONLY)).unwrap() }; unsafe { errno_check(libc::fchmod(fd, 0o777)) }; diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs-symlink.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs-symlink.rs deleted file mode 100644 index 4fe66c338a045..0000000000000 --- a/src/tools/miri/tests/pass-dep/libc/libc-fs-symlink.rs +++ /dev/null @@ -1,82 +0,0 @@ -// Symlink tests are separate since they don't in general work on a Windows host. -//@ignore-host: windows # creating symlinks requires admin permissions on Windows -//@ignore-target: windows # File handling is not implemented yet -//@compile-flags: -Zmiri-disable-isolation -//@run-native - -use std::ffi::CString; -use std::io::ErrorKind; -use std::os::unix::ffi::OsStrExt; - -#[path = "../../utils/libc.rs"] -mod libc_utils; -#[path = "../../utils/mod.rs"] -mod utils; -use libc_utils::errno_result; - -fn main() { - test_readlink(); - test_nofollow_symlink(); -} - -fn test_readlink() { - let bytes = b"Hello, World!\n"; - let path = utils::prepare_with_content("miri_test_fs_link_target.txt", bytes); - let expected_path = path.as_os_str().as_bytes(); - - let symlink_path = utils::prepare("miri_test_fs_symlink.txt"); - std::os::unix::fs::symlink(&path, &symlink_path).unwrap(); - - // Test that the expected string gets written to a buffer of proper - // length, and that a trailing null byte is not written. - let symlink_c_str = CString::new(symlink_path.as_os_str().as_bytes()).unwrap(); - let symlink_c_ptr = symlink_c_str.as_ptr(); - - // Make the buf one byte larger than it needs to be, - // and check that the last byte is not overwritten. - let mut large_buf = vec![0xFF; expected_path.len() + 1]; - let res = errno_result(unsafe { - libc::readlink(symlink_c_ptr, large_buf.as_mut_ptr().cast(), large_buf.len()) - }) - .unwrap(); - // Check that the resolved path was properly written into the buf. - assert_eq!(&large_buf[..(large_buf.len() - 1)], expected_path); - assert_eq!(large_buf.last(), Some(&0xFF)); - assert_eq!(res, (large_buf.len() - 1) as isize); - - // Test that the resolved path is truncated if the provided buffer - // is too small. - let mut small_buf = [0u8; 2]; - let res = errno_result(unsafe { - libc::readlink(symlink_c_ptr, small_buf.as_mut_ptr().cast(), small_buf.len()) - }) - .unwrap(); - assert_eq!(small_buf, &expected_path[..small_buf.len()]); - assert_eq!(res, small_buf.len() as isize); - - // Test that we report a proper error for a missing path. - let err = errno_result(unsafe { - libc::readlink( - c"MIRI_MISSING_FILE_NAME".as_ptr(), - small_buf.as_mut_ptr().cast(), - small_buf.len(), - ) - }) - .unwrap_err(); - assert_eq!(err.kind(), ErrorKind::NotFound); -} - -fn test_nofollow_symlink() { - let path = utils::prepare_with_content("test_nofollow_symlink_target.txt", b"Hello, World!\n"); - - let symlink_path = utils::prepare("test_nofollow_symlink.txt"); - std::os::unix::fs::symlink(&path, &symlink_path).unwrap(); - - let symlink_cpath = CString::new(symlink_path.as_os_str().as_bytes()).unwrap(); - - let err = errno_result(unsafe { - libc::open(symlink_cpath.as_ptr(), libc::O_NOFOLLOW | libc::O_CLOEXEC) - }) - .unwrap_err(); - assert_eq!(err.raw_os_error(), Some(libc::ELOOP)); -} diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs index d5418d3612a42..b3f063ef07cba 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs @@ -5,10 +5,11 @@ use std::ffi::{CStr, CString, OsString}; use std::fs::{self, File, canonicalize, create_dir, remove_dir, remove_file}; use std::io::{ErrorKind, Write}; +use std::mem::MaybeUninit; use std::os::unix::ffi::OsStrExt; use std::os::unix::io::AsRawFd; use std::path::PathBuf; -use std::ptr; +use std::{env, ptr}; #[path = "../../utils/mod.rs"] mod utils; @@ -27,10 +28,10 @@ fn main() { test_ftruncate::(libc::ftruncate); #[cfg(target_os = "linux")] test_ftruncate::(libc::ftruncate64); - test_file_open_unix_allow_two_args(); - test_file_open_unix_needs_three_args(); - test_file_open_unix_extra_third_arg(); - test_file_open_dir(); + test_file_open_allow_two_args(); + test_file_open_needs_three_args(); + test_file_open_extra_third_arg(); + test_file_open_nofollow(); #[cfg(target_os = "linux")] test_o_tmpfile_flag(); test_posix_mkstemp(); @@ -49,24 +50,22 @@ fn main() { test_fallocate::(libc::fallocate64); #[cfg(target_os = "linux")] test_sync_file_range(); + test_opendir_closedir(); + test_readdir(); + test_dirfd(); test_fstat(); + test_fstatat(); test_stat(); test_lstat(); test_futimens(); test_isatty(); test_read_and_uninit(); - test_nofollow_not_symlink(); #[cfg(target_os = "macos")] test_ioctl(); - test_opendir_closedir(); - test_readdir(); - test_dirfd(); #[cfg(target_os = "linux")] - test_statx_on_file_path(); + test_statx(); #[cfg(target_os = "linux")] - test_statx_on_file_descriptor(); - #[cfg(target_os = "linux")] - test_statx_empty_path_on_pipe(); + test_statx_on_empty_path(); test_readv(); test_readv_empty_bufs(); #[cfg(not(target_os = "solaris"))] @@ -77,6 +76,7 @@ fn main() { #[cfg(not(target_os = "solaris"))] test_pwritev(); test_pwrite(); + test_readlink(); test_linkat(); } @@ -115,61 +115,55 @@ fn assert_statx_matches_metadata(stx: &libc::statx, meta: &fs::Metadata, expecte } #[cfg(target_os = "linux")] -fn test_statx_on_file_descriptor() { - use std::mem::MaybeUninit; - +fn test_statx() { let bytes = b"hello"; - let path = utils::prepare_with_content("miri_test_libc_statx_fd.txt", bytes); - let file = File::open(&path).unwrap(); - let meta = file.metadata().unwrap(); + let path = utils::prepare_with_content("miri_test_libc_statx.txt", bytes); + let c_path = utils::into_c_string(&path); + let meta = fs::metadata(&path).unwrap(); + // Relative to working directory. unsafe { + let old_cwd = env::current_dir().unwrap(); + env::set_current_dir(path.parent().unwrap()).unwrap(); + let mut stx = MaybeUninit::::zeroed(); errno_check(libc::statx( - file.as_raw_fd(), - c"".as_ptr(), - libc::AT_EMPTY_PATH, + libc::AT_FDCWD, + c"miri_test_libc_statx.txt".as_ptr(), + 0, libc::STATX_BASIC_STATS | libc::STATX_BTIME, stx.as_mut_ptr(), )); let stx = stx.assume_init(); assert_statx_matches_metadata(&stx, &meta, bytes.len() as u64); + + env::set_current_dir(old_cwd).unwrap(); } - // If we don't set AT_EMPTY_PATH, we get an error. + // Setting AT_EMPTY_PATH is fine even if the path is not actually empty. unsafe { let mut stx = MaybeUninit::::zeroed(); - let err = errno_result(libc::statx( - file.as_raw_fd(), - c"".as_ptr(), - 0, + errno_check(libc::statx( + libc::AT_FDCWD, + c_path.as_ptr(), + libc::AT_EMPTY_PATH, libc::STATX_BASIC_STATS | libc::STATX_BTIME, stx.as_mut_ptr(), - )) - .unwrap_err(); - assert_eq!(err.raw_os_error().unwrap(), libc::ENOENT); - } - - drop(file); - remove_file(&path).unwrap(); -} - -#[cfg(target_os = "linux")] -fn test_statx_on_file_path() { - use std::mem::MaybeUninit; + )); - let bytes = b"hello"; - let path = utils::prepare_with_content("miri_test_libc_statx.txt", bytes); - let c_path = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); - let meta = fs::metadata(&path).unwrap(); + let stx = stx.assume_init(); + assert_statx_matches_metadata(&stx, &meta, bytes.len() as u64); + } + // dirfd is ignored because our path is absolute. + assert!(path.is_absolute()); unsafe { let mut stx = MaybeUninit::::zeroed(); errno_check(libc::statx( - libc::AT_FDCWD, + 999, // dirfd c_path.as_ptr(), - 0, + libc::AT_EMPTY_PATH, libc::STATX_BASIC_STATS | libc::STATX_BTIME, stx.as_mut_ptr(), )); @@ -178,28 +172,48 @@ fn test_statx_on_file_path() { assert_statx_matches_metadata(&stx, &meta, bytes.len() as u64); } - // Setting AT_EMPTY_PATH is fine even if the path is not actually empty. + // Symlink following. + let symlinkpath = utils::prepare("miri_test_libc_statx.link"); + let c_symlinkpath = utils::into_c_string(&symlinkpath); + std::os::unix::fs::symlink(&path, &symlinkpath).unwrap(); unsafe { let mut stx = MaybeUninit::::zeroed(); errno_check(libc::statx( - libc::AT_FDCWD, - c_path.as_ptr(), + 999, // dirfd + c_symlinkpath.as_ptr(), libc::AT_EMPTY_PATH, libc::STATX_BASIC_STATS | libc::STATX_BTIME, stx.as_mut_ptr(), )); - let stx = stx.assume_init(); assert_statx_matches_metadata(&stx, &meta, bytes.len() as u64); } - - // dirfd is ignored because our path is absolute. - assert!(path.is_absolute()); unsafe { let mut stx = MaybeUninit::::zeroed(); errno_check(libc::statx( 999, // dirfd - c_path.as_ptr(), + c_symlinkpath.as_ptr(), + libc::AT_SYMLINK_NOFOLLOW, + libc::STATX_BASIC_STATS | libc::STATX_BTIME, + stx.as_mut_ptr(), + )); + let stx = stx.assume_init(); + assert!(stx.stx_mask & libc::STATX_TYPE != 0); + assert_eq!((stx.stx_mode as libc::mode_t) & libc::S_IFMT, libc::S_IFLNK); + assert!(stx.stx_mask & libc::STATX_MODE != 0); + assert_ne!((stx.stx_mode as libc::mode_t) & !libc::S_IFMT, 0); + } + + // Relative to a dirfd. + // The only way to get a dirfd in Miri currently is via a `dirfd`. Slightly silly, but whatever. + let dirstream = unsafe { libc::opendir(utils::into_c_string(path.parent().unwrap()).as_ptr()) }; + assert!(!dirstream.is_null()); + let dirfd = unsafe { libc::dirfd(dirstream) }; + unsafe { + let mut stx = MaybeUninit::::zeroed(); + errno_check(libc::statx( + dirfd, + c"miri_test_libc_statx.txt".as_ptr(), libc::AT_EMPTY_PATH, libc::STATX_BASIC_STATS | libc::STATX_BTIME, stx.as_mut_ptr(), @@ -208,17 +222,56 @@ fn test_statx_on_file_path() { let stx = stx.assume_init(); assert_statx_matches_metadata(&stx, &meta, bytes.len() as u64); } + errno_check(unsafe { libc::closedir(dirstream) }); remove_file(&path).unwrap(); + remove_file(&symlinkpath).unwrap(); } #[cfg(target_os = "linux")] -fn test_statx_empty_path_on_pipe() { +fn test_statx_on_empty_path() { + let bytes = b"hello"; + let path = utils::prepare_with_content("miri_test_libc_statx_fd.txt", bytes); + let file = File::open(&path).unwrap(); + let meta = file.metadata().unwrap(); + + unsafe { + let mut stx = MaybeUninit::::zeroed(); + errno_check(libc::statx( + file.as_raw_fd(), + c"".as_ptr(), + libc::AT_EMPTY_PATH, + libc::STATX_BASIC_STATS | libc::STATX_BTIME, + stx.as_mut_ptr(), + )); + + let stx = stx.assume_init(); + assert_statx_matches_metadata(&stx, &meta, bytes.len() as u64); + } + + // If we don't set AT_EMPTY_PATH, we get an error. + unsafe { + let mut stx = MaybeUninit::::zeroed(); + let err = errno_result(libc::statx( + file.as_raw_fd(), + c"".as_ptr(), + 0, + libc::STATX_BASIC_STATS | libc::STATX_BTIME, + stx.as_mut_ptr(), + )) + .unwrap_err(); + assert_eq!(err.raw_os_error().unwrap(), libc::ENOENT); + } + + drop(file); + remove_file(&path).unwrap(); + + // Test it on a pipe as well. unsafe { let mut fds = [0; 2]; errno_check(libc::pipe(fds.as_mut_ptr())); - let mut statx_buf = std::mem::MaybeUninit::::zeroed(); + let mut statx_buf = MaybeUninit::::zeroed(); errno_check(libc::statx( fds[0], @@ -251,50 +304,50 @@ fn test_statx_empty_path_on_pipe() { } } -fn test_file_open_unix_allow_two_args() { - let path = utils::prepare_with_content("test_file_open_unix_allow_two_args.txt", &[]); - let name = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); +fn test_file_open_allow_two_args() { + let path = utils::prepare_with_content("miri_test_file_open_allow_two_args.txt", &[]); + let name = utils::into_c_string(path); let _fd = errno_result(unsafe { libc::open(name.as_ptr(), libc::O_RDONLY) }).unwrap(); } -fn test_file_open_unix_needs_three_args() { - let path = utils::prepare_with_content("test_file_open_unix_needs_three_args.txt", &[]); - let name = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); +fn test_file_open_needs_three_args() { + let path = utils::prepare_with_content("miri_test_file_open_needs_three_args.txt", &[]); + let name = utils::into_c_string(path); let _fd = errno_result(unsafe { libc::open(name.as_ptr(), libc::O_CREAT | libc::O_RDWR, 0o666) }) .unwrap(); } -fn test_file_open_unix_extra_third_arg() { - let path = utils::prepare_with_content("test_file_open_unix_extra_third_arg.txt", &[]); - let name = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); +fn test_file_open_extra_third_arg() { + let path = utils::prepare_with_content("miri_test_file_open_extra_third_arg.txt", &[]); + let name = utils::into_c_string(path); let _fd = errno_result(unsafe { libc::open(name.as_ptr(), libc::O_RDONLY, 42) }).unwrap(); } -fn test_file_open_dir() { - let dir_path = utils::prepare_dir("miri_test_fs_dir"); - create_dir(&dir_path).unwrap(); - let dir_name = CString::new(dir_path.into_os_string().into_encoded_bytes()).unwrap(); +fn test_file_open_nofollow() { + let bytes = b"Hello, World!\n"; + let path = utils::prepare_with_content("miri_test_nofollow_not_symlink.txt", bytes); + let cpath = utils::into_c_string(path); + let fd = + errno_result(unsafe { libc::open(cpath.as_ptr(), libc::O_NOFOLLOW | libc::O_CLOEXEC) }) + .unwrap(); + errno_check(unsafe { libc::close(fd) }); - // Opening it for read-write fails. The error code differs between Unix and Windows hosts. - let err = errno_result(unsafe { libc::open(dir_name.as_ptr(), libc::O_RDWR) }).unwrap_err(); - assert!( - [libc::EISDIR, libc::EPERM].contains(&err.raw_os_error().unwrap()), - "unexpected errno: {err}" - ); + let path = utils::prepare_with_content("miri_test_open_nofollow_symlink_target.txt", bytes); + + let symlink_path = utils::prepare("miri_test_open_nofollow_symlink.txt"); + std::os::unix::fs::symlink(&path, &symlink_path).unwrap(); - // Opening it for reading succeeds, but then reading fails. - // FIXME: currently does not behave as expected on Windows hosts. - // See . - // let fd = errno_result(unsafe { libc::open(dir_name.as_ptr(), libc::O_RDONLY) }).unwrap(); - // let mut buf = [0u8; 4]; - // let err = - // errno_result(unsafe { libc::read(fd, buf.as_mut_ptr().cast(), buf.len()) }).unwrap_err(); - // assert_eq!(err.raw_os_error().unwrap(), libc::EISDIR, "unexpected errno: {err}"); - // errno_check(unsafe { libc::close(fd) }); + let symlink_cpath = utils::into_c_string(symlink_path); + + let err = errno_result(unsafe { + libc::open(symlink_cpath.as_ptr(), libc::O_NOFOLLOW | libc::O_CLOEXEC) + }) + .unwrap_err(); + assert_eq!(err.raw_os_error(), Some(libc::ELOOP)); } fn test_dup_stdout_stderr() { @@ -311,7 +364,7 @@ fn test_dup_stdout_stderr() { fn test_dup() { let bytes = b"dup and dup2"; let path = utils::prepare_with_content("miri_test_libc_dup.txt", bytes); - let name = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); + let name = utils::into_c_string(path); unsafe { let fd = errno_result(libc::open(name.as_ptr(), libc::O_RDONLY)).unwrap(); @@ -373,8 +426,8 @@ fn test_rename() { let file = File::create(&path1).unwrap(); drop(file); - let c_path1 = CString::new(path1.as_os_str().as_bytes()).expect("CString::new failed"); - let c_path2 = CString::new(path2.as_os_str().as_bytes()).expect("CString::new failed"); + let c_path1 = utils::into_c_string(&path1); + let c_path2 = utils::into_c_string(&path2); // Renaming should succeed unsafe { libc::rename(c_path1.as_ptr(), c_path2.as_ptr()) }; @@ -404,7 +457,7 @@ fn test_ftruncate>( file.sync_all().unwrap(); assert_eq!(file.metadata().unwrap().len(), 5); - let c_path = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); + let c_path = utils::into_c_string(&path); let fd = unsafe { libc::open(c_path.as_ptr(), libc::O_RDWR) }; // Truncate to a bigger size @@ -506,11 +559,11 @@ fn test_posix_mkstemp() { /// Test allocating variant of `realpath`. fn test_posix_realpath_alloc() { - use std::os::unix::ffi::{OsStrExt, OsStringExt}; + use std::os::unix::ffi::OsStringExt; let buf; let path = utils::prepare("miri_test_libc_posix_realpath_alloc"); - let c_path = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); + let c_path = utils::into_c_string(&path); // Create file. drop(File::create(&path).unwrap()); @@ -529,11 +582,10 @@ fn test_posix_realpath_alloc() { /// Test non-allocating variant of `realpath`. fn test_posix_realpath_noalloc() { - use std::ffi::{CStr, CString}; - use std::os::unix::ffi::OsStrExt; + use std::ffi::CStr; let path = utils::prepare("miri_test_libc_posix_realpath_noalloc"); - let c_path = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); + let c_path = utils::into_c_string(&path); let mut v = vec![0; libc::PATH_MAX as usize]; @@ -554,16 +606,12 @@ fn test_posix_realpath_noalloc() { /// Test failure cases for `realpath`. fn test_posix_realpath_errors() { - use std::ffi::CString; - use std::io::ErrorKind; - // Test nonexistent path returns an error. - let c_path = CString::new("./nothing_to_see_here").expect("CString::new failed"); + let c_path = c"./nothing_to_see_here"; let r = unsafe { libc::realpath(c_path.as_ptr(), std::ptr::null_mut()) }; assert!(r.is_null()); let e = std::io::Error::last_os_error(); assert_eq!(e.raw_os_error(), Some(libc::ENOENT)); - assert_eq!(e.kind(), ErrorKind::NotFound); } #[cfg(target_os = "linux")] @@ -615,7 +663,7 @@ fn test_posix_fallocate>( assert_eq!(ret, libc::EINVAL); // fd not writable - let c_path = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); + let c_path = utils::into_c_string(path); let fd = unsafe { libc::open(c_path.as_ptr(), libc::O_RDONLY) }; let ret = unsafe { posix_fallocate(fd, T::from(0), T::from(10)) }; assert_eq!(ret, libc::EBADF); @@ -629,7 +677,7 @@ fn test_posix_fallocate>( file.sync_all().unwrap(); assert_eq!(file.metadata().unwrap().len(), 5); - let c_path = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); + let c_path = utils::into_c_string(&path); let fd = unsafe { libc::open(c_path.as_ptr(), libc::O_RDWR) }; // Allocate to a bigger size from offset 0 @@ -692,7 +740,7 @@ fn test_fallocate>( assert_eq!(err.raw_os_error().unwrap(), libc::EINVAL); // fd not writable - let c_path = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); + let c_path = utils::into_c_string(path); let fd = errno_result(unsafe { libc::open(c_path.as_ptr(), libc::O_RDONLY) }).unwrap(); let err = errno_result(unsafe { fallocate(fd, 0, T::from(0), T::from(10)) }).unwrap_err(); assert_eq!(err.raw_os_error().unwrap(), libc::EBADF); @@ -705,7 +753,7 @@ fn test_fallocate>( file.sync_all().unwrap(); assert_eq!(file.metadata().unwrap().len(), 5); - let c_path = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); + let c_path = utils::into_c_string(&path); let fd = errno_result(unsafe { libc::open(c_path.as_ptr(), libc::O_RDWR) }).unwrap(); // Allocate to a bigger size from offset 0 @@ -770,7 +818,6 @@ fn test_sync_file_range() { } fn test_fstat() { - use std::mem::MaybeUninit; use std::os::unix::io::AsRawFd; let path = utils::prepare_with_content("miri_test_libc_fstat.txt", b"hello"); @@ -789,17 +836,97 @@ fn test_fstat() { check_stat_fields(stat); remove_file(&path).unwrap(); + + // Test it on a pipe as well. + unsafe { + let mut fds = [0; 2]; + errno_check(libc::pipe(fds.as_mut_ptr())); + + let mut stat = MaybeUninit::::uninit(); + errno_check(libc::fstat(fds[0], stat.as_mut_ptr())); + let stat = stat.assume_init_ref(); + + assert_eq!(stat.st_mode & libc::S_IFMT, libc::S_IFIFO); + assert_ne!(stat.st_mode & !libc::S_IFMT, 0, "some permission should be set"); + assert_eq!(stat.st_size, 0); + + errno_check(libc::close(fds[0])); + errno_check(libc::close(fds[1])); + } +} + +fn test_fstatat() { + let testdir = utils::prepare_dir("miri_test_fstatat"); + fs::create_dir(&testdir).unwrap(); + let filename = "file.txt"; + let cfilename = c"file.txt"; + fs::write(testdir.join(filename), b"hello").unwrap(); + let absfilename = testdir.join(filename); + assert!(absfilename.is_absolute()); + + // The only way to get a dirfd in Miri currently is via a `dirfd`. Slightly silly, but whatever. + let dirstream = unsafe { libc::opendir(utils::into_c_string(&testdir).as_ptr()) }; + assert!(!dirstream.is_null()); + let dirfd = unsafe { libc::dirfd(dirstream) }; + + let checkstat = |stat: &libc::stat| { + assert_eq!(stat.st_mode & libc::S_IFMT, libc::S_IFREG); + assert_ne!(stat.st_mode & !libc::S_IFMT, 0, "some permission should be set"); + assert_eq!(stat.st_size, 5); + check_stat_fields(stat); + }; + + // Relative to working directory. + let old_cwd = env::current_dir().unwrap(); + env::set_current_dir(&testdir).unwrap(); + let mut stat = MaybeUninit::::uninit(); + errno_check(unsafe { libc::fstatat(libc::AT_FDCWD, cfilename.as_ptr(), stat.as_mut_ptr(), 0) }); + checkstat(unsafe { stat.assume_init_ref() }); + env::set_current_dir(old_cwd).unwrap(); + + // Absolute path, dirfd is ignored. + let mut stat = MaybeUninit::::uninit(); + errno_check(unsafe { + libc::fstatat( + 999, // dirfd + utils::into_c_string(&absfilename).as_ptr(), + stat.as_mut_ptr(), + 0, // flags + ) + }); + checkstat(unsafe { stat.assume_init_ref() }); + + // Relative to dirfd. + let mut stat = MaybeUninit::::uninit(); + errno_check(unsafe { libc::fstatat(dirfd, cfilename.as_ptr(), stat.as_mut_ptr(), 0) }); + checkstat(unsafe { stat.assume_init_ref() }); + + // Symlink following. + let linkname = testdir.join("link"); + std::os::unix::fs::symlink(&absfilename, &linkname).unwrap(); + let mut stat = MaybeUninit::::uninit(); + errno_check(unsafe { libc::fstatat(dirfd, c"link".as_ptr(), stat.as_mut_ptr(), 0) }); + checkstat(unsafe { stat.assume_init_ref() }); + let mut stat = MaybeUninit::::uninit(); + errno_check(unsafe { + libc::fstatat(dirfd, c"link".as_ptr(), stat.as_mut_ptr(), libc::AT_SYMLINK_NOFOLLOW) + }); + let stat = unsafe { stat.assume_init_ref() }; + assert_eq!(stat.st_mode & libc::S_IFMT, libc::S_IFLNK); // not S_IFREG! + assert_ne!(stat.st_mode & !libc::S_IFMT, 0, "some permission should be set"); + check_stat_fields(stat); + + errno_check(unsafe { libc::closedir(dirstream) }); } fn test_stat() { - use std::mem::MaybeUninit; // Also make sure we *do* follow symlinks. let path = utils::prepare_with_content("miri_test_libc_stat.txt", b"hello"); let symlink_path = utils::prepare("miri_test_libc_lstat_symlink.txt"); std::os::unix::fs::symlink(&path, &symlink_path).unwrap(); - let cpath = CString::new(symlink_path.as_os_str().as_bytes()).unwrap(); + let cpath = utils::into_c_string(symlink_path); let mut stat = MaybeUninit::::uninit(); errno_check(unsafe { libc::stat(cpath.as_ptr(), stat.as_mut_ptr()) }); @@ -816,13 +943,11 @@ fn test_stat() { } fn test_lstat() { - use std::mem::MaybeUninit; - let path = utils::prepare_with_content("miri_test_libc_lstat.txt", b"hello"); let symlink_path = utils::prepare("miri_test_libc_lstat_symlink.txt"); std::os::unix::fs::symlink(&path, &symlink_path).unwrap(); - let cpath = CString::new(symlink_path.as_os_str().as_bytes()).unwrap(); + let cpath = utils::into_c_string(&symlink_path); let mut stat = MaybeUninit::::uninit(); errno_check(unsafe { libc::lstat(cpath.as_ptr(), stat.as_mut_ptr()) }); @@ -839,7 +964,6 @@ fn test_lstat() { } fn test_futimens() { - use std::mem::MaybeUninit; use std::time::{SystemTime, UNIX_EPOCH}; let path = utils::prepare_with_content("miri_test_libc_futimens.txt", b"hello"); @@ -905,7 +1029,7 @@ fn test_isatty() { libc::isatty(libc::STDERR_FILENO); // But when we open a file, it is definitely not a TTY. - let path = utils::prepare("notatty.txt"); + let path = utils::prepare("miri_notatty.txt"); let file = File::create(&path).unwrap(); assert_eq!(libc::isatty(file.as_raw_fd()), 0); @@ -918,15 +1042,14 @@ fn test_isatty() { } fn test_read_and_uninit() { - use std::mem::MaybeUninit; { // We test that libc::read initializes its buffer. - let path = utils::prepare_with_content("pass-libc-read-and-uninit.txt", &[1u8, 2, 3]); - let cpath = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); + let path = utils::prepare_with_content("miri-pass-libc-read-and-uninit.txt", &[1u8, 2, 3]); + let cpath = utils::into_c_string(path); unsafe { let fd = libc::open(cpath.as_ptr(), libc::O_RDONLY); assert_ne!(fd, -1); - let mut buf: MaybeUninit = std::mem::MaybeUninit::uninit(); + let mut buf: MaybeUninit = MaybeUninit::uninit(); assert_eq!(libc::read(fd, buf.as_mut_ptr().cast::(), 1), 1); let buf = buf.assume_init(); assert_eq!(buf, 1); @@ -938,8 +1061,8 @@ fn test_read_and_uninit() { // We test that if we requested to read 4 bytes, but actually read 3 bytes, then // 3 bytes (not 4) will be overwritten, and remaining byte will be left as-is. let data = [1u8, 2, 3]; - let path = utils::prepare_with_content("pass-libc-read-and-uninit-2.txt", &data); - let cpath = CString::new(path.clone().into_os_string().into_encoded_bytes()).unwrap(); + let path = utils::prepare_with_content("miri-pass-libc-read-and-uninit-2.txt", &data); + let cpath = utils::into_c_string(&path); unsafe { let fd = libc::open(cpath.as_ptr(), libc::O_RDONLY); assert_ne!(fd, -1); @@ -959,18 +1082,10 @@ fn test_read_and_uninit() { } } -fn test_nofollow_not_symlink() { - let bytes = b"Hello, World!\n"; - let path = utils::prepare_with_content("test_nofollow_not_symlink.txt", bytes); - let cpath = CString::new(path.as_os_str().as_bytes()).unwrap(); - let ret = unsafe { libc::open(cpath.as_ptr(), libc::O_NOFOLLOW | libc::O_CLOEXEC) }; - assert!(ret >= 0); -} - #[cfg(target_os = "macos")] fn test_ioctl() { let path = utils::prepare_with_content("miri_test_libc_ioctl.txt", &[]); - let name = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); + let name = utils::into_c_string(path); unsafe { // 100 surely is an invalid FD. @@ -987,7 +1102,7 @@ fn test_opendir_closedir() { // dir should exist let path = utils::prepare_dir("miri_test_libc_opendir_closedir"); create_dir(&path).expect("create_dir failed"); - let cpath = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); + let cpath = utils::into_c_string(&path); let dir: *mut libc::DIR = unsafe { libc::opendir(cpath.as_ptr()) }; assert!(!dir.is_null()); errno_check(unsafe { libc::closedir(dir) }); @@ -1001,8 +1116,8 @@ fn test_opendir_closedir() { assert_eq!(e.kind(), ErrorKind::NotFound); // open normal file as dir should fail - let file_path = utils::prepare_with_content("test_not_a_dir.txt", b"hello"); - let cfile = CString::new(file_path.as_os_str().as_bytes()).expect("CString::new failed"); + let file_path = utils::prepare_with_content("miri_test_not_a_dir.txt", b"hello"); + let cfile = utils::into_c_string(&file_path); let dir: *mut libc::DIR = unsafe { libc::opendir(cfile.as_ptr()) }; assert!(dir.is_null()); let e = std::io::Error::last_os_error(); @@ -1023,7 +1138,7 @@ fn test_readdir() { write(&file1, b"content1").unwrap(); write(&file2, b"content2").unwrap(); - let c_path = CString::new(dir_path.as_os_str().as_bytes()).unwrap(); + let c_path = utils::into_c_string(&dir_path); unsafe { let dirp = libc::opendir(c_path.as_ptr()); @@ -1050,11 +1165,9 @@ fn test_readdir() { } fn test_dirfd() { - use std::mem::MaybeUninit; - let path = utils::prepare_dir("miri_test_libc_opendir_closedir"); create_dir(&path).expect("create_dir failed"); - let cpath = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); + let cpath = utils::into_c_string(path); let dir: *mut libc::DIR = unsafe { libc::opendir(cpath.as_ptr()) }; assert!(!dir.is_null()); @@ -1100,8 +1213,8 @@ pub fn check_stat_fields(stat: &libc::stat) { /// Test vectored reads with multiple buffers. fn test_readv() { let file_contents = [1u8, 2, 3, 4, 5, 6]; - let path = utils::prepare_with_content("pass-libc-readv.txt", &file_contents); - let cpath = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); + let path = utils::prepare_with_content("miri-pass-libc-readv.txt", &file_contents); + let cpath = utils::into_c_string(path); let fd = unsafe { libc::open(cpath.as_ptr(), libc::O_RDONLY) }; assert_ne!(fd, -1); @@ -1136,8 +1249,8 @@ fn test_readv_empty_bufs() { return; } - let path = utils::prepare_with_content("pass-libc-readv-empty-bufs.txt", &[1u8, 2, 3]); - let cpath = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); + let path = utils::prepare_with_content("miri-pass-libc-readv-empty-bufs.txt", &[1u8, 2, 3]); + let cpath = utils::into_c_string(path); let fd = unsafe { libc::open(cpath.as_ptr(), libc::O_RDONLY) }; assert_ne!(fd, -1); unsafe { assert_eq!(errno_result(libc::readv(fd, ptr::null::(), 0)).unwrap(), 0) }; @@ -1150,8 +1263,8 @@ fn test_readv_empty_bufs() { #[cfg(not(target_os = "solaris"))] fn test_preadv() { let file_contents = [1u8, 2, 3, 4, 5, 6]; - let path = utils::prepare_with_content("pass-libc-preadv.txt", &file_contents); - let cpath = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); + let path = utils::prepare_with_content("miri-pass-libc-preadv.txt", &file_contents); + let cpath = utils::into_c_string(path); let fd = unsafe { libc::open(cpath.as_ptr(), libc::O_RDONLY) }; assert_ne!(fd, -1); @@ -1191,8 +1304,8 @@ fn test_preadv() { /// Test reading with an offset. fn test_pread() { let file_contents = [1u8, 2, 3, 4, 5, 6]; - let path = utils::prepare_with_content("pass-libc-pread.txt", &file_contents); - let cpath = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); + let path = utils::prepare_with_content("miri-pass-libc-pread.txt", &file_contents); + let cpath = utils::into_c_string(path); let fd = unsafe { libc::open(cpath.as_ptr(), libc::O_RDONLY) }; assert_ne!(fd, -1); @@ -1218,8 +1331,8 @@ fn test_pread() { /// Test vectored writes with multiple buffers. fn test_writev() { - let path = utils::prepare_with_content("pass-libc-writev.txt", &[]); - let cpath = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); + let path = utils::prepare_with_content("miri-pass-libc-writev.txt", &[]); + let cpath = utils::into_c_string(path); let fd = unsafe { libc::open(cpath.as_ptr(), libc::O_WRONLY) }; assert_ne!(fd, -1); @@ -1269,8 +1382,8 @@ fn test_writev_empty_bufs() { return; } - let path = utils::prepare_with_content("pass-libc-writev-empty-bufs.txt", &[1u8, 2, 3]); - let cpath = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); + let path = utils::prepare_with_content("miri-pass-libc-writev-empty-bufs.txt", &[1u8, 2, 3]); + let cpath = utils::into_c_string(path); let fd = unsafe { libc::open(cpath.as_ptr(), libc::O_WRONLY) }; assert_ne!(fd, -1); unsafe { @@ -1284,8 +1397,8 @@ fn test_writev_empty_bufs() { /// doesn't have `pwritev`. #[cfg(not(target_os = "solaris"))] fn test_pwritev() { - let path = utils::prepare_with_content("pass-libc-pwritev.txt", &[]); - let cpath = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); + let path = utils::prepare_with_content("miri-pass-libc-pwritev.txt", &[]); + let cpath = utils::into_c_string(path); let fd = unsafe { libc::open(cpath.as_ptr(), libc::O_WRONLY) }; assert_ne!(fd, -1); @@ -1340,8 +1453,8 @@ fn test_pwritev() { /// Test writing with an offset. fn test_pwrite() { - let path = utils::prepare_with_content("pass-libc-pwritev.txt", &[]); - let cpath = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); + let path = utils::prepare_with_content("miri-pass-libc-pwritev.txt", &[]); + let cpath = utils::into_c_string(path); let fd = unsafe { libc::open(cpath.as_ptr(), libc::O_WRONLY) }; assert_ne!(fd, -1); @@ -1381,12 +1494,59 @@ fn test_pwrite() { assert_eq!(&write_buffer[0..bytes_written], &read_buffer[OFFSET..(bytes_written + OFFSET)]); } +fn test_readlink() { + let bytes = b"Hello, World!\n"; + let path = utils::prepare_with_content("miri_test_fs_link_target.txt", bytes); + let expected_path = path.as_os_str().as_bytes(); + + let symlink_path = utils::prepare("miri_test_fs_symlink.txt"); + std::os::unix::fs::symlink(&path, &symlink_path).unwrap(); + + // Test that the expected string gets written to a buffer of proper + // length, and that a trailing null byte is not written. + let symlink_c_str = utils::into_c_string(symlink_path); + let symlink_c_ptr = symlink_c_str.as_ptr(); + + // Make the buf one byte larger than it needs to be, + // and check that the last byte is not overwritten. + let mut large_buf = vec![0xFF; expected_path.len() + 1]; + let res = errno_result(unsafe { + libc::readlink(symlink_c_ptr, large_buf.as_mut_ptr().cast(), large_buf.len()) + }) + .unwrap(); + // Check that the resolved path was properly written into the buf. + assert_eq!(&large_buf[..(large_buf.len() - 1)], expected_path); + assert_eq!(large_buf.last(), Some(&0xFF)); + assert_eq!(res, (large_buf.len() - 1) as isize); + + // Test that the resolved path is truncated if the provided buffer + // is too small. + let mut small_buf = [0u8; 2]; + let res = errno_result(unsafe { + libc::readlink(symlink_c_ptr, small_buf.as_mut_ptr().cast(), small_buf.len()) + }) + .unwrap(); + assert_eq!(small_buf, &expected_path[..small_buf.len()]); + assert_eq!(res, small_buf.len() as isize); + + // Test that we report a proper error for a missing path. + let err = errno_result(unsafe { + libc::readlink( + c"MIRI_MISSING_FILE_NAME".as_ptr(), + small_buf.as_mut_ptr().cast(), + small_buf.len(), + ) + }) + .unwrap_err(); + assert_eq!(err.kind(), ErrorKind::NotFound); +} + fn test_linkat() { let source = utils::prepare_with_content("miri_test_libc_linkat_source.txt", b"hello"); let link = utils::prepare("miri_test_libc_linkat_link.txt"); - let c_source = CString::new(source.as_os_str().as_bytes()).expect("CString::new failed"); - let c_link = CString::new(link.as_os_str().as_bytes()).expect("CString::new failed"); + let c_source = utils::into_c_string(&source); + let c_link = utils::into_c_string(&link); // Call linkat unsafe { diff --git a/src/tools/miri/tests/pass-dep/libc/libc-socket-invalid-addr.rs b/src/tools/miri/tests/pass-dep/libc/libc-socket-invalid-addr.rs index 4e46870da204b..40a3a60068d90 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-socket-invalid-addr.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-socket-invalid-addr.rs @@ -7,7 +7,6 @@ mod libc_utils; #[path = "../../utils/mod.rs"] mod utils; -use std::ffi::CString; use std::ptr; use libc_utils::*; @@ -15,8 +14,8 @@ use libc_utils::*; /// Test doing address resolution using the `getaddrinfo` syscall. /// This also tests freeing the address linked list using `freeaddrinfo`. fn main() { - let node_c_str = CString::new("this-is-not-a-valid-address").unwrap(); - let service_c_str = CString::new("8080").unwrap(); + let node_c_str = c"this-is-not-a-valid-address"; + let service_c_str = c"8080"; let mut hints: libc::addrinfo = unsafe { std::mem::zeroed() }; hints.ai_socktype = libc::SOCK_STREAM; diff --git a/src/tools/miri/tests/pass-dep/libc/libc-socket-no-blocking-epoll.rs b/src/tools/miri/tests/pass-dep/libc/libc-socket-no-blocking-epoll.rs index c91f3474793e3..563c2a3842a19 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-socket-no-blocking-epoll.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-socket-no-blocking-epoll.rs @@ -57,9 +57,9 @@ fn test_connect_nonblock() { net::accept_ipv4(server_sockfd).unwrap(); }); - // Non-blocking connects always "fail" with EINPROGRESS. - let err = net::connect_ipv4(client_sockfd, addr).unwrap_err(); - assert_eq!(err.kind(), ErrorKind::InProgress); + let result = net::connect_ipv4(client_sockfd, addr); + // This might succeed immediately or return EINPROGRESS. + assert!(result.is_ok() || result.is_err_and(|e| e.kind() == ErrorKind::InProgress)); // Add client socket with WRITABLE interest to epoll. epoll_ctl_add(epfd, client_sockfd, EPOLLOUT | EPOLLET | EPOLLERR).unwrap(); @@ -145,9 +145,10 @@ fn test_connect_nonblock_err() { // a zero port. let addr = net::sock_addr_ipv4([127, 0, 1, 1], 12321); - // Non-blocking connect should fail with EINPROGRESS. let err = net::connect_ipv4(client_sockfd, addr).unwrap_err(); - assert_eq!(err.kind(), ErrorKind::InProgress); + // Since the address is not bound, the `connect` can never succeed + // immediately and thus it always "fails" with EINPROGRESS. + assert!(err.kind() == ErrorKind::InProgress); // Add interest for client socket. epoll_ctl_add(epfd, client_sockfd, EPOLLOUT | EPOLLET | libc::EPOLLERR).unwrap(); diff --git a/src/tools/miri/tests/pass-dep/libc/libc-socket-no-blocking.rs b/src/tools/miri/tests/pass-dep/libc/libc-socket-no-blocking.rs index de718feb47990..0325fe06dab82 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-socket-no-blocking.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-socket-no-blocking.rs @@ -58,6 +58,9 @@ fn main() { test_getpeername_ipv4_nonblock(); test_getpeername_ipv4_nonblock_no_peer(); + + test_listen_connecting(); + test_connect_connecting(); } /// Test that setting the O_NONBLOCK flag changes the blocking state of a socket. @@ -225,15 +228,22 @@ fn test_connect_nonblock() { // Yield to server thread to ensure that it's currently accepting. thread::sleep(Duration::from_millis(10)); - // Non-blocking connects always "fail" with EINPROGRESS. - let err = net::connect_ipv4(client_sockfd, addr).unwrap_err(); + let Err(err) = net::connect_ipv4(client_sockfd, addr) else { + // The connection could be established immediately. We don't + // need to enter the loop and check whether the connection could + // really be established. + return server_thread.join().unwrap(); + }; + // The connection could not be established immediately. The `connect` + // should thus return EINPROGRESS. assert_eq!(err.kind(), ErrorKind::InProgress); loop { // There should be no error during async connection. - let errno = net::getsockopt::(client_sockfd, libc::SOL_SOCKET, libc::SO_ERROR) - .unwrap(); - assert_eq!(errno, 0); + let so_error = + net::getsockopt::(client_sockfd, libc::SOL_SOCKET, libc::SO_ERROR) + .unwrap(); + assert_eq!(so_error, 0); let result = net::sockname_ipv4(|storage, len| unsafe { libc::getpeername(client_sockfd, storage, len) @@ -667,9 +677,10 @@ fn test_getsockname_ipv4_connect_nonblock() { // a zero port. let addr = net::sock_addr_ipv4([192, 0, 2, 1], 12321); - // Non-blocking connect should fail with EINPROGRESS. let err = net::connect_ipv4(client_sockfd, addr).unwrap_err(); - assert_eq!(err.kind(), ErrorKind::InProgress); + // Since we're connecting to a blackhole address, the `connect` can + // never succeed immediately and thus it always "fails" with EINPROGRESS. + assert!(err.kind() == ErrorKind::InProgress); let (_, sock_addr) = net::sockname_ipv4(|storage, len| unsafe { libc::getsockname(client_sockfd, storage, len) @@ -712,8 +723,14 @@ fn test_getpeername_ipv4_nonblock() { // Yield to server thread to ensure that it's currently accepting. thread::sleep(Duration::from_millis(10)); - // Non-blocking connects always "fail" with EINPROGRESS. - let err = net::connect_ipv4(client_sockfd, addr).unwrap_err(); + let Err(err) = net::connect_ipv4(client_sockfd, addr) else { + // The connection could be established immediately. We don't + // need to enter the loop and check whether the connection could + // really be established. + return server_thread.join().unwrap(); + }; + // The connection could not be established immediately. The `connect` + // should thus return EINPROGRESS. assert_eq!(err.kind(), ErrorKind::InProgress); loop { @@ -764,14 +781,15 @@ fn test_getpeername_ipv4_nonblock_no_peer() { // a zero port. let addr = net::sock_addr_ipv4([192, 0, 2, 1], 12321); - // Non-blocking connect should fail with EINPROGRESS. let err = net::connect_ipv4(client_sockfd, addr).unwrap_err(); - assert_eq!(err.kind(), ErrorKind::InProgress); + // Since we're connecting to a blackhole address, the `connect` can + // never succeed immediately and thus it always "fails" with EINPROGRESS. + assert!(err.kind() == ErrorKind::InProgress); // There should be no error during async connection. - let errno = + let so_error = net::getsockopt::(client_sockfd, libc::SOL_SOCKET, libc::SO_ERROR).unwrap(); - assert_eq!(errno, 0); + assert_eq!(so_error, 0); // Since we're never accepting the connection, the socket should never be // successfully connected and thus we should be unable to read the peername. @@ -782,3 +800,81 @@ fn test_getpeername_ipv4_nonblock_no_peer() { }; assert_eq!(err.kind(), ErrorKind::NotConnected); } + +/// Test that `listen` returns EINVAL for a non-blocking IPv4 +/// socket which is stuck at connecting to a remote address. +fn test_listen_connecting() { + let client_sockfd = + unsafe { errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0)).unwrap() }; + + unsafe { + // Change client socket to be non-blocking. + errno_check(libc::fcntl(client_sockfd, libc::F_SETFL, libc::O_NONBLOCK)); + } + + // We cannot attempt to connect to a localhost address because + // it could be the case that a socket from another test is + // currently listening on `localhost:12321` because we bind to + // random ports everywhere. For `192.0.2.1` we know that nothing is + // listening because it's a blackhole address: + // + // The port `12321` is just a random non-zero port because Windows + // and Apple hosts return EADDRNOTAVAIL when attempting to connect to + // a zero port. + let addr = net::sock_addr_ipv4([192, 0, 2, 1], 12321); + + // Non-blocking connect should fail with EINPROGRESS. + let err = net::connect_ipv4(client_sockfd, addr).unwrap_err(); + assert_eq!(err.kind(), ErrorKind::InProgress); + + // There should be no error during async connection. + let so_error = + net::getsockopt::(client_sockfd, libc::SOL_SOCKET, libc::SO_ERROR).unwrap(); + assert_eq!(so_error, 0); + + // Connecting sockets cannot start listening, thus the operation should + // fail with EINVAL. + let err = unsafe { errno_result(libc::listen(client_sockfd, 16)).unwrap_err() }; + // Check that it is the right error. + assert_eq!(err.raw_os_error(), Some(libc::EINVAL)); +} + +/// Test that invoking `connect` on an already connecting client +/// TCP socket returns EALREADY. +fn test_connect_connecting() { + let client_sockfd = + unsafe { errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0)).unwrap() }; + + unsafe { + // Change client socket to be non-blocking. + errno_check(libc::fcntl(client_sockfd, libc::F_SETFL, libc::O_NONBLOCK)); + } + + // We cannot attempt to connect to a localhost address because + // it could be the case that a socket from another test is + // currently listening on `localhost:12321` because we bind to + // random ports everywhere. For `192.0.2.1` we know that nothing is + // listening because it's a blackhole address: + // + // The port `12321` is just a random non-zero port because Windows + // and Apple hosts return EADDRNOTAVAIL when attempting to connect to + // a zero port. + let addr = net::sock_addr_ipv4([192, 0, 2, 1], 12321); + + // Non-blocking connect should fail with EINPROGRESS. + let err = net::connect_ipv4(client_sockfd, addr).unwrap_err(); + assert_eq!(err.kind(), ErrorKind::InProgress); + + // There should be no error during async connection. + let so_error = + net::getsockopt::(client_sockfd, libc::SOL_SOCKET, libc::SO_ERROR).unwrap(); + assert_eq!(so_error, 0); + + // Create a socket which listens on `addr`. + let (_, addr) = net::make_listener_ipv4().unwrap(); + + let err = net::connect_ipv4(client_sockfd, addr).unwrap_err(); + // The standard library doesn't provide an error kind for EALREADY; + // we thus cannot assert the correct error kind. + assert_eq!(err.raw_os_error(), Some(libc::EALREADY)); +} diff --git a/src/tools/miri/tests/pass-dep/libc/libc-socket.rs b/src/tools/miri/tests/pass-dep/libc/libc-socket.rs index 85d6302a0175d..d581f358cac95 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-socket.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-socket.rs @@ -33,10 +33,17 @@ fn main() { } test_bind_ipv4_invalid_addr_len(); test_bind_ipv6(); + test_bind_twice(); + test_bind_connected(); + test_bind_listening(); test_listen(); + test_listen_connected(); + test_listen_listening(); test_accept_connect(); test_connect_error(); + test_connect_connected(); + test_connect_listening(); test_send_peek_recv(); test_write_read(); test_readv(); @@ -47,6 +54,7 @@ fn main() { test_getsockname_ipv4_unbound(); test_getsockname_ipv4_connect(); test_getsockname_ipv6(); + test_getsockname_ipv6_unbound(); test_getpeername_ipv4(); test_getpeername_ipv6(); @@ -236,21 +244,123 @@ fn test_bind_ipv6() { } } -fn test_listen() { +/// Test that invoking `bind` on an already bound TCP socket +/// returns EINVAL. +fn test_bind_twice() { let sockfd = unsafe { errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0)).unwrap() }; let addr = net::sock_addr_ipv4(net::IPV4_LOCALHOST, 0); - unsafe { + let err = unsafe { errno_check(libc::bind( sockfd, (&addr as *const libc::sockaddr_in).cast::(), size_of::() as libc::socklen_t, )); - } + errno_result(libc::bind( + sockfd, + (&addr as *const libc::sockaddr_in).cast::(), + size_of::() as libc::socklen_t, + )) + .unwrap_err() + }; + // Check that it is the right error. + assert_eq!(err.raw_os_error(), Some(libc::EINVAL)); +} + +/// Test that invoking `bind` on an already connected client +/// TCP socket returns EINVAL. +fn test_bind_connected() { + let (server_sockfd, addr) = net::make_listener_ipv4().unwrap(); + let client_sockfd = + unsafe { errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0)).unwrap() }; + + net::connect_ipv4(client_sockfd, addr).unwrap(); + net::accept_ipv4(server_sockfd).unwrap(); + + let addr = net::sock_addr_ipv4(net::IPV4_LOCALHOST, 0); + let err = unsafe { + errno_result(libc::bind( + client_sockfd, + (&addr as *const libc::sockaddr_in).cast::(), + size_of::() as libc::socklen_t, + )) + .unwrap_err() + }; + // Check that it is the right error. + assert_eq!(err.raw_os_error(), Some(libc::EINVAL)); +} + +/// Test that invoking `bind` on an already listening server +/// TCP socket returns EINVAL. +fn test_bind_listening() { + let server_sockfd = + unsafe { errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0)).unwrap() }; unsafe { - errno_check(libc::listen(sockfd, 16)); + errno_check(libc::listen(server_sockfd, 16)); } + + let addr = net::sock_addr_ipv4(net::IPV4_LOCALHOST, 0); + let err = unsafe { + errno_result(libc::bind( + server_sockfd, + (&addr as *const libc::sockaddr_in).cast::(), + size_of::() as libc::socklen_t, + )) + .unwrap_err() + }; + // Check that it is the right error. + assert_eq!(err.raw_os_error(), Some(libc::EINVAL)); +} + +/// Test that a socket can start listening. This also tests +/// whether sockets are bound implicitly after `listen` has been +/// invoked on them. +fn test_listen() { + let sockfd = + unsafe { errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0)).unwrap() }; + + unsafe { errno_check(libc::listen(sockfd, 16)) }; + + let (_, sock_addr) = + net::sockname_ipv4(|storage, len| unsafe { libc::getsockname(sockfd, storage, len) }) + .unwrap(); + + // Libc representation of an unspecified IPv4 address with zero port. + let addr = net::sock_addr_ipv4([0, 0, 0, 0], 0); + + // Ensure that the socket got implicitly bound to the unspecified + // local address with a non-zero port. + assert!(sock_addr.sin_port > 0); + assert_eq!(addr.sin_family, sock_addr.sin_family); + assert_eq!(addr.sin_addr.s_addr, sock_addr.sin_addr.s_addr); +} + +/// Test that `listen` returns EINVAL for a client TCP socket which +/// is already connected to a peer socket. +fn test_listen_connected() { + let (server_sockfd, addr) = net::make_listener_ipv4().unwrap(); + let client_sockfd = + unsafe { errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0)).unwrap() }; + + net::connect_ipv4(client_sockfd, addr).unwrap(); + net::accept_ipv4(server_sockfd).unwrap(); + + // Connected sockets cannot start listening, thus the operation should + // fail with EINVAL. + let err = unsafe { errno_result(libc::listen(client_sockfd, 16)).unwrap_err() }; + // Check that it is the right error. + assert_eq!(err.raw_os_error(), Some(libc::EINVAL)); +} + +/// Test that `listen` succeeds for a server TCP socket which is already +/// listening. +fn test_listen_listening() { + let (server_sockfd, _) = net::make_listener_ipv4().unwrap(); + + // Invoking `listen` multiple times should be allowed as it can be used to change + // the backlog value. + unsafe { errno_check(libc::listen(server_sockfd, 16)) }; } /// Test accepting connections by running a server in a separate thread and connecting clients @@ -318,6 +428,46 @@ fn test_connect_error() { )); } +/// Test that invoking `connect` on an already connected client +/// TCP socket returns EISCONN. +fn test_connect_connected() { + let (server_sockfd1, addr1) = net::make_listener_ipv4().unwrap(); + let (_, addr2) = net::make_listener_ipv4().unwrap(); + let client_sockfd = + unsafe { errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0)).unwrap() }; + + net::connect_ipv4(client_sockfd, addr1).unwrap(); + net::accept_ipv4(server_sockfd1).unwrap(); + + let err = net::connect_ipv4(client_sockfd, addr2).unwrap_err(); + // The standard library doesn't provide an error kind for EISCONN; + // we thus cannot assert the correct error kind. + assert_eq!(err.raw_os_error(), Some(libc::EISCONN)); +} + +/// Test that invoking `connect` on an already listening server +/// TCP socket returns EOPNOTSUPP on non-Linux-like targets and +/// EISCONN on Linux-like targets. +fn test_connect_listening() { + let (_, addr1) = net::make_listener_ipv4().unwrap(); + let (server_sockfd2, _) = net::make_listener_ipv4().unwrap(); + + let err = net::connect_ipv4(server_sockfd2, addr1).unwrap_err(); + + if cfg!(any(target_os = "linux", target_os = "android")) { + // Linux-like targets return EISCONN when attempting to invoke + // `connect` on an already listening socket. + + // The standard library doesn't provide an error kind for EISCONN; + // we thus cannot assert the correct error kind. + assert_eq!(err.raw_os_error(), Some(libc::EISCONN)); + } else { + // POSIX specifies EOPNOTSUPP when attempting to invoke + // `connect` on an already listening socket. + assert_eq!(err.raw_os_error(), Some(libc::EOPNOTSUPP)); + } +} + /// Test sending bytes into a connected stream and then peeking and receiving /// them from the other end. /// We especially want to test that the peeking doesn't remove the bytes from @@ -606,6 +756,32 @@ fn test_getsockname_ipv6() { assert_eq!(addr.sin6_addr.s6_addr, sock_addr.sin6_addr.s6_addr); } +/// Test the `getsockname` syscall on an IPv6 socket which is not bound. +/// The `getsockname` syscall should return [::]:0 with flowinfo and scope id +/// of zero. +fn test_getsockname_ipv6_unbound() { + let sockfd = + unsafe { errno_result(libc::socket(libc::AF_INET6, libc::SOCK_STREAM, 0)).unwrap() }; + + let (_, sock_addr) = + net::sockname_ipv6(|storage, len| unsafe { libc::getsockname(sockfd, storage, len) }) + .unwrap(); + + // Libc representation of an unspecified IPv6 address with zero port, flowinfo and scope id. + let addr = net::sock_addr_full_ipv6( + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + /* port */ 0, + /* flowinfo */ 0, + /* scope_id */ 0, + ); + + assert_eq!(addr.sin6_family, sock_addr.sin6_family); + assert_eq!(addr.sin6_port, sock_addr.sin6_port); + assert_eq!(addr.sin6_flowinfo, sock_addr.sin6_flowinfo); + assert_eq!(addr.sin6_scope_id, sock_addr.sin6_scope_id); + assert_eq!(addr.sin6_addr.s6_addr, sock_addr.sin6_addr.s6_addr); +} + /// Test the `getpeername` syscall on an IPv4 socket. /// For a connected socket, the `getpeername` syscall should /// return the same address as the socket was connected to. diff --git a/src/tools/miri/tests/pass-dep/shims/windows-fs.rs b/src/tools/miri/tests/pass-dep/shims/windows-fs.rs index 80f8ef9359d3b..b012b7328eaf3 100644 --- a/src/tools/miri/tests/pass-dep/shims/windows-fs.rs +++ b/src/tools/miri/tests/pass-dep/shims/windows-fs.rs @@ -1,5 +1,7 @@ //@only-target: windows # this directly tests windows-only functions //@compile-flags: -Zmiri-disable-isolation +//@run-native + #![allow(nonstandard_style)] use std::io::{ErrorKind, Read, Seek, SeekFrom, Write}; @@ -19,15 +21,19 @@ use windows_sys::Win32::Foundation::{ }; use windows_sys::Win32::Storage::FileSystem::{ BY_HANDLE_FILE_INFORMATION, CREATE_ALWAYS, CREATE_NEW, CreateFileW, DeleteFileW, - FILE_ALLOCATION_INFO, FILE_ATTRIBUTE_DIRECTORY, FILE_ATTRIBUTE_NORMAL, FILE_BEGIN, - FILE_CURRENT, FILE_END_OF_FILE_INFO, FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT, - FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE, FileAllocationInfo, FileEndOfFileInfo, - FlushFileBuffers, GetFileInformationByHandle, MoveFileExW, OPEN_ALWAYS, OPEN_EXISTING, - SetFileInformationByHandle, SetFilePointerEx, + FILE_ALLOCATION_INFO, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_DIRECTORY, FILE_ATTRIBUTE_NORMAL, + FILE_BEGIN, FILE_CURRENT, FILE_END_OF_FILE_INFO, FILE_FLAG_BACKUP_SEMANTICS, + FILE_FLAG_OPEN_REPARSE_POINT, FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE, + FileAllocationInfo, FileEndOfFileInfo, FlushFileBuffers, GetFileInformationByHandle, + MoveFileExW, OPEN_ALWAYS, OPEN_EXISTING, SetFileInformationByHandle, SetFilePointerEx, }; use windows_sys::Win32::System::IO::IO_STATUS_BLOCK; use windows_sys::Win32::System::Threading::GetCurrentProcess; +// Windows seems to usually but not always set FILE_ATTRIBUTE_ARCHIVE for new files. +// So we accept either "ARCHIVE" or "NORMAL". +const REGULAR_FILE: u32 = FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_NORMAL; + fn main() { unsafe { test_create_dir_file(); @@ -71,7 +77,7 @@ unsafe fn test_create_dir_file() { } unsafe fn test_create_normal_file() { - let temp = utils::prepare("test_create_normal_file.txt"); + let temp = utils::prepare("miri_test_create_normal_file.txt"); let raw_path = to_wide_cstr(&temp); let handle = CreateFileW( raw_path.as_ptr(), @@ -87,9 +93,8 @@ unsafe fn test_create_normal_file() { if GetFileInformationByHandle(handle, &mut info) == 0 { panic!("Failed to get file information: {}", GetLastError()) }; - // FIXME: this test is wrong, somehow. It doesn't pass when run natively. - // - assert!(info.dwFileAttributes & FILE_ATTRIBUTE_NORMAL != 0); + assert!(info.dwFileAttributes & REGULAR_FILE != 0); + assert!(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == 0); if CloseHandle(handle) == 0 { panic!("Failed to close file") }; @@ -121,7 +126,7 @@ unsafe fn test_create_normal_file() { if GetFileInformationByHandle(handle, &mut info) == 0 { panic!("Failed to get file information: {}", GetLastError()) }; - assert!(info.dwFileAttributes & FILE_ATTRIBUTE_NORMAL != 0); + assert!(info.dwFileAttributes & REGULAR_FILE != 0); if CloseHandle(handle) == 0 { panic!("Failed to close file") }; @@ -129,7 +134,7 @@ unsafe fn test_create_normal_file() { /// Tests that CREATE_ALWAYS sets the error value correctly based on whether the file already exists unsafe fn test_create_always_twice() { - let temp = utils::prepare("test_create_always.txt"); + let temp = utils::prepare("miri_test_create_always.txt"); let raw_path = to_wide_cstr(&temp); let handle = CreateFileW( raw_path.as_ptr(), @@ -164,7 +169,7 @@ unsafe fn test_create_always_twice() { /// Tests that OPEN_ALWAYS sets the error value correctly based on whether the file already exists unsafe fn test_open_always_twice() { - let temp = utils::prepare("test_open_always.txt"); + let temp = utils::prepare("miri_test_open_always.txt"); let raw_path = to_wide_cstr(&temp); let handle = CreateFileW( raw_path.as_ptr(), @@ -223,7 +228,7 @@ unsafe fn test_open_always_twice() { // } unsafe fn test_delete_file() { - let temp = utils::prepare("test_delete_file.txt"); + let temp = utils::prepare("miri_test_delete_file.txt"); let raw_path = to_wide_cstr(&temp); let _ = fs::File::create(&temp).unwrap(); @@ -244,7 +249,7 @@ unsafe fn test_ntstatus_to_dos() { } unsafe fn test_file_read_write() { - let temp = utils::prepare("test_file_read_write.txt"); + let temp = utils::prepare("miri_test_file_read_write.txt"); let file = fs::File::create(&temp).unwrap(); let handle = file.as_raw_handle(); @@ -295,7 +300,7 @@ unsafe fn test_file_read_write() { } unsafe fn test_set_file_info() { - let temp = utils::prepare("test_set_file.txt"); + let temp = utils::prepare("miri_test_set_file.txt"); let mut file = fs::File::create(&temp).unwrap(); let handle = file.as_raw_handle(); @@ -321,7 +326,7 @@ unsafe fn test_set_file_info() { } unsafe fn test_dup_handle() { - let temp = utils::prepare("test_dup.txt"); + let temp = utils::prepare("miri_test_dup.txt"); let mut file1 = fs::File::options().read(true).write(true).create(true).open(&temp).unwrap(); @@ -354,7 +359,7 @@ unsafe fn test_dup_handle() { } unsafe fn test_file_seek() { - let temp = utils::prepare("test_file_seek.txt"); + let temp = utils::prepare("miri_test_file_seek.txt"); let mut file = fs::File::options().create(true).write(true).read(true).open(&temp).unwrap(); file.write_all(b"Hello, World!\n").unwrap(); @@ -379,7 +384,7 @@ unsafe fn test_file_seek() { } unsafe fn test_flush_buffers() { - let temp = utils::prepare("test_flush_buffers.txt"); + let temp = utils::prepare("miri_test_flush_buffers.txt"); let file = fs::File::options().create(true).write(true).read(true).open(&temp).unwrap(); if FlushFileBuffers(file.as_raw_handle()) == 0 { panic!("Failed to flush buffers"); @@ -392,8 +397,8 @@ unsafe fn test_flush_buffers() { } unsafe fn test_move_file() { - let temp = utils::prepare("test_move_file.txt"); - let temp_new = utils::prepare("test_move_file_new.txt"); + let temp = utils::prepare("miri_test_move_file.txt"); + let temp_new = utils::prepare("miri_test_move_file_new.txt"); let mut file = fs::File::options().create(true).write(true).open(&temp).unwrap(); file.write_all(b"Hello, World!\n").unwrap(); diff --git a/src/tools/miri/tests/pass-dep/tokio/file-io.rs b/src/tools/miri/tests/pass-dep/tokio/file-io.rs index 982768111a511..d7704af1402e9 100644 --- a/src/tools/miri/tests/pass-dep/tokio/file-io.rs +++ b/src/tools/miri/tests/pass-dep/tokio/file-io.rs @@ -17,7 +17,7 @@ async fn main() { } async fn test_create_and_write() -> io::Result<()> { - let path = utils::prepare("foo.txt"); + let path = utils::prepare("miri_tokio_test_create_and_write.txt"); let mut file = File::create(&path).await?; // Write 10 bytes to the file. @@ -34,7 +34,7 @@ async fn test_create_and_write() -> io::Result<()> { async fn test_create_and_read() -> io::Result<()> { let bytes = b"more bytes"; - let path = utils::prepare_with_content("foo.txt", bytes); + let path = utils::prepare_with_content("miri_tokio_test_create_and_read.txt", bytes); let mut file = OpenOptions::new().read(true).open(&path).await.unwrap(); let mut buffer = vec![]; diff --git a/src/tools/miri/tests/pass/shims/available-parallelism-miri-num-cpus.rs b/src/tools/miri/tests/pass/shims/available-parallelism-miri-num-cpus.rs index 0d96bc2f5e737..fa83de8bc127e 100644 --- a/src/tools/miri/tests/pass/shims/available-parallelism-miri-num-cpus.rs +++ b/src/tools/miri/tests/pass/shims/available-parallelism-miri-num-cpus.rs @@ -1,4 +1,6 @@ //@compile-flags: -Zmiri-num-cpus=1024 +// FIXME: Disabled on FreeBSD due to +//@ignore-target: freebsd use std::num::NonZero; use std::thread::available_parallelism; diff --git a/src/tools/miri/tests/utils/fs.rs b/src/tools/miri/tests/utils/fs.rs index e312feda7e62b..afcd66dd16e58 100644 --- a/src/tools/miri/tests/utils/fs.rs +++ b/src/tools/miri/tests/utils/fs.rs @@ -1,15 +1,11 @@ -use std::ffi::OsString; +use std::ffi::{CStr, OsString}; use std::path::PathBuf; use std::{fs, io}; -use super::miri_extern; +use super::{into_c_string, miri_extern}; pub fn host_to_target_path(path: OsString) -> PathBuf { - use std::ffi::{CStr, CString}; - - // Once into_encoded_bytes is stable we can use it here. - // (Unstable features would need feature flags in each test...) - let path = CString::new(path.into_string().unwrap()).unwrap(); + let path = into_c_string(path); let mut out = Vec::with_capacity(1024); unsafe { @@ -32,6 +28,8 @@ pub fn tmp() -> PathBuf { /// Prepare: compute filename and make sure the file does not exist. pub fn prepare(filename: &str) -> PathBuf { + assert!(filename.starts_with("miri")); + let path = tmp().join(filename); // Clean the paths for robustness. fs::remove_file(&path).ok(); @@ -47,6 +45,8 @@ pub fn prepare_with_content(filename: &str, content: &[u8]) -> PathBuf { /// Prepare directory: compute directory name and make sure it does not exist. pub fn prepare_dir(dirname: &str) -> PathBuf { + assert!(dirname.starts_with("miri")); + let path = tmp().join(&dirname); // Clean the directory for robustness. fs::remove_dir_all(&path).ok(); diff --git a/src/tools/miri/tests/utils/mod.rs b/src/tools/miri/tests/utils/mod.rs index f855f115e43dc..3fe655350776c 100644 --- a/src/tools/miri/tests/utils/mod.rs +++ b/src/tools/miri/tests/utils/mod.rs @@ -1,6 +1,8 @@ #![allow(dead_code)] #![allow(unused_imports)] +use std::ffi::{CString, OsString}; + #[macro_use] mod macros; @@ -12,6 +14,11 @@ pub use self::fs::*; pub use self::io::*; pub use self::miri_extern::*; +/// Return a `CString` version of the given string. +pub fn into_c_string(str: impl Into) -> CString { + CString::new(str.into().into_string().unwrap()).unwrap() +} + pub fn run_provenance_gc() { // SAFETY: No preconditions. The GC is fine to run at any time. unsafe { miri_run_provenance_gc() } diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index d77e89df45e44..f46092fd799e7 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -68,10 +68,8 @@ parser = { path = "./crates/parser", version = "0.0.0" } paths = { path = "./crates/paths", version = "0.0.0" } proc-macro-api = { path = "./crates/proc-macro-api", version = "0.0.0" } proc-macro-srv = { path = "./crates/proc-macro-srv", version = "0.0.0" } -proc-macro-srv-cli = { path = "./crates/proc-macro-srv-cli", version = "0.0.0" } profile = { path = "./crates/profile", version = "0.0.0" } project-model = { path = "./crates/project-model", version = "0.0.0" } -query-group = { package = "query-group-macro", path = "./crates/query-group-macro", version = "0.0.0" } span = { path = "./crates/span", version = "0.0.0" } stdx = { path = "./crates/stdx", version = "0.0.0" } syntax = { path = "./crates/syntax", version = "0.0.0" } diff --git a/src/tools/rust-analyzer/crates/macros/Cargo.toml b/src/tools/rust-analyzer/crates/macros/Cargo.toml index 8184cc6d1c03d..b0d0000268588 100644 --- a/src/tools/rust-analyzer/crates/macros/Cargo.toml +++ b/src/tools/rust-analyzer/crates/macros/Cargo.toml @@ -17,3 +17,6 @@ proc-macro2 = "1" quote = "1" syn = "2.0.9" synstructure = "0.13.0" + +[lints] +workspace = true diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/Cargo.toml index 78630ddb4d7d8..668188340e5c8 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/Cargo.toml @@ -11,3 +11,6 @@ doctest = false [build-dependencies] cargo_metadata = "0.23.0" + +[lints] +workspace = true diff --git a/src/tools/rust-analyzer/lib/ungrammar/ungrammar2json/Cargo.toml b/src/tools/rust-analyzer/lib/ungrammar/ungrammar2json/Cargo.toml index 0fa08bbbd0485..f17587e3f556c 100644 --- a/src/tools/rust-analyzer/lib/ungrammar/ungrammar2json/Cargo.toml +++ b/src/tools/rust-analyzer/lib/ungrammar/ungrammar2json/Cargo.toml @@ -10,3 +10,6 @@ edition = "2024" [dependencies] write-json = "0.1.1" ungrammar = { path = "../", version = "1.1.0" } + +[lints] +workspace = true diff --git a/tests/codegen-llvm/direct-access-external-data.rs b/tests/codegen-llvm/direct-access-external-data.rs index a151bb6012e1e..43ee290d3a058 100644 --- a/tests/codegen-llvm/direct-access-external-data.rs +++ b/tests/codegen-llvm/direct-access-external-data.rs @@ -22,15 +22,6 @@ unsafe extern "C" { // When "linkage" is used, we generate an indirection global. // Check dso_local is still applied to the actual global. - // CHECK: @EXTERNAL = external - // DEFAULT-SAME: dso_local - // PIE-NOT: dso_local - // DIRECT-SAME: dso_local - // INDIRECT-NOT: dso_local - // CHECK-SAME: global i8 - #[linkage = "external"] - safe static EXTERNAL: *const u32; - // CHECK: @WEAK = extern_weak // DEFAULT-SAME: dso_local // PIE-NOT: dso_local @@ -44,6 +35,5 @@ unsafe extern "C" { #[no_mangle] pub fn refer() { core::hint::black_box(VAR); - core::hint::black_box(EXTERNAL); core::hint::black_box(WEAK); } diff --git a/tests/codegen-llvm/loongarch/direct-access-external-data.rs b/tests/codegen-llvm/loongarch/direct-access-external-data.rs index de495d7fe9a72..e5b7124a722e2 100644 --- a/tests/codegen-llvm/loongarch/direct-access-external-data.rs +++ b/tests/codegen-llvm/loongarch/direct-access-external-data.rs @@ -20,15 +20,6 @@ unsafe extern "C" { // When "linkage" is used, we generate an indirection global. // Check dso_local is still applied to the actual global. - // CHECK: @EXTERNAL = external - // DEFAULT-NOT: dso_local - // PIE-NOT: dso_local - // DIRECT-SAME: dso_local - // INDIRECT-NOT: dso_local - // CHECK-SAME: global i8 - #[linkage = "external"] - safe static EXTERNAL: *const u32; - // CHECK: @WEAK = extern_weak // DEFAULT-NOT: dso_local // PIE-NOT: dso_local @@ -42,6 +33,5 @@ unsafe extern "C" { #[no_mangle] pub fn refer() { core::hint::black_box(VAR); - core::hint::black_box(EXTERNAL); core::hint::black_box(WEAK); } diff --git a/tests/crashes/156101.rs b/tests/crashes/156101.rs deleted file mode 100644 index c95361fab2ecc..0000000000000 --- a/tests/crashes/156101.rs +++ /dev/null @@ -1,4 +0,0 @@ -//@ known-bug: #156101 -fn main() { - format_args!(concat!("𐏿", "{f:?#}")); -} diff --git a/tests/run-make/linkage-attr-on-static/bar.rs b/tests/run-make/linkage-attr-on-static/bar.rs index 68607cbb65721..cbab76ba6f403 100644 --- a/tests/run-make/linkage-attr-on-static/bar.rs +++ b/tests/run-make/linkage-attr-on-static/bar.rs @@ -1,7 +1,7 @@ #![feature(linkage)] #[no_mangle] -#[linkage = "external"] +#[linkage = "weak"] static BAZ: i32 = 21; #[link(name = "foo", kind = "static")] diff --git a/tests/run-make/linkage-attr-on-static/rmake.rs b/tests/run-make/linkage-attr-on-static/rmake.rs index cd85542e9587d..f1cf80a2b0c5a 100644 --- a/tests/run-make/linkage-attr-on-static/rmake.rs +++ b/tests/run-make/linkage-attr-on-static/rmake.rs @@ -5,6 +5,8 @@ //@ ignore-cross-compile // Reason: the compiled binary is executed +//@ ignore-i686-pc-windows-gnu weak symbols broken with MinGW linker +//@ ignore-x86_64-pc-windows-gnu weak symbols broken with MinGW linker use run_make_support::{build_native_static_lib, run, rustc}; diff --git a/tests/run-make/metrics-dir-crate-hash/lib.rs b/tests/run-make/metrics-dir-crate-hash/lib.rs new file mode 100644 index 0000000000000..e0673f64605f5 --- /dev/null +++ b/tests/run-make/metrics-dir-crate-hash/lib.rs @@ -0,0 +1,4 @@ +#![feature(ascii_char)] // random lib feature +#![feature(test_unstable_lint)] // random lang feature + +pub fn documented() {} diff --git a/tests/run-make/metrics-dir-crate-hash/main.rs b/tests/run-make/metrics-dir-crate-hash/main.rs new file mode 100644 index 0000000000000..844b362c9f179 --- /dev/null +++ b/tests/run-make/metrics-dir-crate-hash/main.rs @@ -0,0 +1,6 @@ +#![feature(ascii_char)] // random lib feature +#![feature(test_unstable_lint)] // random lang feature + +fn main() { + println!("foobar"); +} diff --git a/tests/run-make/metrics-dir-crate-hash/rmake.rs b/tests/run-make/metrics-dir-crate-hash/rmake.rs new file mode 100644 index 0000000000000..90e0b16859c04 --- /dev/null +++ b/tests/run-make/metrics-dir-crate-hash/rmake.rs @@ -0,0 +1,51 @@ +// Verifies that when a crate hash is required solely for a metrics dir, that +// crate hash is successfully generated, either by the fallback mechanism or +// metadata generation. +// See https://github.com/rust-lang/rust/issues/163426. + +//@ ignore-cross-compile + +use std::path::{Path, PathBuf}; + +use run_make_support::rfs::create_dir_all; +use run_make_support::{ + cwd, filename_contains, has_extension, run_in_tmpdir, rustc, rustdoc, shallow_find_files, +}; + +fn find_feature_usage_metrics>(dir: P) -> Vec { + shallow_find_files(dir, |path| { + filename_contains(path, "unstable_feature_usage") && has_extension(path, "json") + }) +} + +fn main() { + let metrics_dir = "metrics-rustdoc"; + create_dir_all(&metrics_dir); + rustdoc() + .input("lib.rs") + .out_dir("doc") + .env("RUST_BACKTRACE", "short") + .arg(format!("-Zmetrics-dir={}", metrics_dir)) + .run() + .assert_stderr_not_contains("internal compiler error"); + assert_eq!( + find_feature_usage_metrics(&metrics_dir).len(), + 1, + "rustdoc should dump exactly one metrics file" + ); + + let metrics_dir = "metrics-rustc"; + create_dir_all(&metrics_dir); + rustc() + .input("main.rs") + .crate_type("bin") + .env("RUST_BACKTRACE", "short") + .arg(format!("-Zmetrics-dir={}", metrics_dir)) + .run() + .assert_stderr_not_contains("internal compiler error"); + assert_eq!( + find_feature_usage_metrics(&metrics_dir).len(), + 1, + "rustc should dump exactly one metrics file" + ); +} diff --git a/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs b/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs index ce787f83ade6d..8d699a665ae24 100644 --- a/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs +++ b/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs @@ -51,17 +51,6 @@ pub extern "C" fn public_naked_generic() -> u32 { naked_asm!("mov rax, {}", "ret", const T::COUNT) } -#[linkage = "external"] -extern "C" fn vanilla_external_linkage() -> u32 { - 42 -} - -#[unsafe(naked)] -#[linkage = "external"] -extern "C" fn naked_external_linkage() -> u32 { - naked_asm!("mov rax, 42", "ret") -} - #[cfg(not(windows))] #[linkage = "weak"] extern "C" fn vanilla_weak_linkage() -> u32 { diff --git a/tests/run-make/naked-symbol-visibility/rmake.rs b/tests/run-make/naked-symbol-visibility/rmake.rs index 69317c872f895..1acbe11dc4ae4 100644 --- a/tests/run-make/naked-symbol-visibility/rmake.rs +++ b/tests/run-make/naked-symbol-visibility/rmake.rs @@ -29,9 +29,6 @@ fn main() { // -Zshare-generics. global_function(&rdylib, "public_naked_generic"); - global_function(&rdylib, "vanilla_external_linkage"); - global_function(&rdylib, "naked_external_linkage"); - // FIXME: make this work on windows (gnu and msvc). See the PR // https://github.com/rust-lang/rust/pull/128362 for some approaches // that don't work diff --git a/tests/ui/array-slice-vec/vec-res-add.stderr b/tests/ui/array-slice-vec/vec-res-add.stderr index 6d5ad1d3c9694..4e13dbd0366d0 100644 --- a/tests/ui/array-slice-vec/vec-res-add.stderr +++ b/tests/ui/array-slice-vec/vec-res-add.stderr @@ -8,7 +8,6 @@ LL | let k = i + j; | note: `Vec` does not implement `Add` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - ::: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL | = note: `Vec` is defined in another crate diff --git a/tests/ui/asm/naked-functions/naked-functions.rs b/tests/ui/asm/naked-functions/naked-functions.rs index d994b1151514a..e7da65a169074 100644 --- a/tests/ui/asm/naked-functions/naked-functions.rs +++ b/tests/ui/asm/naked-functions/naked-functions.rs @@ -224,7 +224,7 @@ pub extern "C" fn compatible_doc_attributes() { naked_asm!("", options(raw)); } -#[linkage = "external"] +#[linkage = "weak"] #[unsafe(naked)] pub extern "C" fn compatible_linkage() { naked_asm!("", options(raw)); diff --git a/tests/ui/attributes/codegen_attr_on_required_trait_method.rs b/tests/ui/attributes/codegen_attr_on_required_trait_method.rs index 737ebf7f2b144..2ea4e0b5a395c 100644 --- a/tests/ui/attributes/codegen_attr_on_required_trait_method.rs +++ b/tests/ui/attributes/codegen_attr_on_required_trait_method.rs @@ -11,7 +11,7 @@ trait Test { //~^ ERROR cannot be used on required trait methods [unused_attributes] //~| WARN previously accepted fn method2(&self); - #[linkage = "common"] + #[linkage = "weak"] //~^ ERROR `linkage` attribute cannot be used on required trait methods fn method3(&self); #[track_caller] diff --git a/tests/ui/attributes/codegen_attr_on_required_trait_method.stderr b/tests/ui/attributes/codegen_attr_on_required_trait_method.stderr index b5452ba2882c0..729231956337d 100644 --- a/tests/ui/attributes/codegen_attr_on_required_trait_method.stderr +++ b/tests/ui/attributes/codegen_attr_on_required_trait_method.stderr @@ -1,7 +1,7 @@ error: the `linkage` attribute cannot be used on required trait methods --> $DIR/codegen_attr_on_required_trait_method.rs:14:7 | -LL | #[linkage = "common"] +LL | #[linkage = "weak"] | ^^^^^^^ | = help: the `linkage` attribute can be applied to foreign functions, foreign statics, functions with a body, and statics diff --git a/tests/ui/conditional-compilation/cfg-attr-duplicate-attrs.rs b/tests/ui/conditional-compilation/cfg-attr-duplicate-attrs.rs new file mode 100644 index 0000000000000..30434569dbe73 --- /dev/null +++ b/tests/ui/conditional-compilation/cfg-attr-duplicate-attrs.rs @@ -0,0 +1,34 @@ +// Test for handling of duplicated attributes within `cfg_attr`, in particular the suggestions of +// what to remove. + +#[inline] +#[inline] +//~^ WARN unused attribute +//~| WARN this was previously accepted +fn f1() {} + +#[deprecated] +#[deprecated] +//~^ ERROR multiple `deprecated` attributes +fn f2() {} + +#[inline] +#[cfg_attr(true, inline)] +//~^ WARN unused attribute +//~| WARN this was previously accepted +fn f3() {} + +#[deprecated] +#[cfg_attr(true, deprecated)] +//~^ ERROR multiple `deprecated` attributes +fn f4() {} + +#[inline] +#[deprecated] +#[cfg_attr(true, inline, deprecated)] +//~^ WARN unused attribute +//~| WARN this was previously accepted +//~| ERROR multiple `deprecated` attributes +fn f5() {} + +fn main() {} diff --git a/tests/ui/conditional-compilation/cfg-attr-duplicate-attrs.stderr b/tests/ui/conditional-compilation/cfg-attr-duplicate-attrs.stderr new file mode 100644 index 0000000000000..c30bc26b22ce7 --- /dev/null +++ b/tests/ui/conditional-compilation/cfg-attr-duplicate-attrs.stderr @@ -0,0 +1,78 @@ +error: multiple `deprecated` attributes + --> $DIR/cfg-attr-duplicate-attrs.rs:11:1 + | +LL | #[deprecated] + | ^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/cfg-attr-duplicate-attrs.rs:10:1 + | +LL | #[deprecated] + | ^^^^^^^^^^^^^ + +error: multiple `deprecated` attributes + --> $DIR/cfg-attr-duplicate-attrs.rs:22:18 + | +LL | #[cfg_attr(true, deprecated)] + | ^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/cfg-attr-duplicate-attrs.rs:21:1 + | +LL | #[deprecated] + | ^^^^^^^^^^^^^ + +error: multiple `deprecated` attributes + --> $DIR/cfg-attr-duplicate-attrs.rs:28:26 + | +LL | #[cfg_attr(true, inline, deprecated)] + | ^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/cfg-attr-duplicate-attrs.rs:27:1 + | +LL | #[deprecated] + | ^^^^^^^^^^^^^ + +warning: unused attribute + --> $DIR/cfg-attr-duplicate-attrs.rs:5:1 + | +LL | #[inline] + | ^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/cfg-attr-duplicate-attrs.rs:4:1 + | +LL | #[inline] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: requested on the command line with `-W unused-attributes` + +warning: unused attribute + --> $DIR/cfg-attr-duplicate-attrs.rs:16:18 + | +LL | #[cfg_attr(true, inline)] + | ^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/cfg-attr-duplicate-attrs.rs:15:1 + | +LL | #[inline] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +warning: unused attribute + --> $DIR/cfg-attr-duplicate-attrs.rs:28:18 + | +LL | #[cfg_attr(true, inline, deprecated)] + | ^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/cfg-attr-duplicate-attrs.rs:26:1 + | +LL | #[inline] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: aborting due to 3 previous errors; 3 warnings emitted + diff --git a/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.rs b/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.rs index 907e1b966766f..508b449358964 100644 --- a/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.rs +++ b/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.rs @@ -46,6 +46,9 @@ struct S12; //~| WARN previously accepted struct S13; +#[cfg_attr(true, cfg_attr(true, 3))] //~ ERROR expected identifier, found `3` +struct S14; + #[cfg_attr(true, inline())] //~ ERROR malformed `inline` attribute input fn f1() {} diff --git a/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.stderr b/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.stderr index e901460a4eb88..048affd1c4191 100644 --- a/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.stderr +++ b/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.stderr @@ -120,6 +120,19 @@ LL - #[cfg_attr(true)] LL + #[cfg_attr(predicate, attr1, attr2, ...)] | +error: expected identifier, found `3` + --> $DIR/cfg_attr-attr-syntax-validation.rs:49:33 + | +LL | #[cfg_attr(true, cfg_attr(true, 3))] + | ^ expected identifier + | + = note: for more information, visit +help: must be of the form + | +LL - #[cfg_attr(true, cfg_attr(true, 3))] +LL + #[cfg_attr(true, cfg_attr(predicate, attr1, attr2, ...))] + | + error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `expr` metavariable --> $DIR/cfg_attr-attr-syntax-validation.rs:30:30 | @@ -157,7 +170,7 @@ LL | #[cfg_attr(true, link_section = "name")] | ++++++++ error[E0805]: malformed `inline` attribute input - --> $DIR/cfg_attr-attr-syntax-validation.rs:49:18 + --> $DIR/cfg_attr-attr-syntax-validation.rs:52:18 | LL | #[cfg_attr(true, inline())] | ^^^^^^-- @@ -185,7 +198,7 @@ LL | #[cfg_attr(true, link_section)] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: requested on the command line with `-W unused-attributes` -error: aborting due to 13 previous errors; 1 warning emitted +error: aborting due to 14 previous errors; 1 warning emitted Some errors have detailed explanations: E0539, E0565, E0805. For more information about an error, try `rustc --explain E0539`. diff --git a/tests/ui/const-generics/renamed-feature-gates.stderr b/tests/ui/const-generics/renamed-feature-gates.stderr index b5478b7412f0e..96e68daf5ac3a 100644 --- a/tests/ui/const-generics/renamed-feature-gates.stderr +++ b/tests/ui/const-generics/renamed-feature-gates.stderr @@ -4,7 +4,7 @@ error[E0557]: feature has been removed LL | #![feature(min_generic_const_args)] | ^^^^^^^^^^^^^^^^^^^^^^ feature has been removed | - = note: removed in CURRENT_RUSTC_VERSION + = note: removed in 1.100.0 = note: renamed to `gca_min_const_items` error[E0557]: feature has been removed @@ -13,7 +13,7 @@ error[E0557]: feature has been removed LL | #![feature(generic_const_args)] | ^^^^^^^^^^^^^^^^^^ feature has been removed | - = note: removed in CURRENT_RUSTC_VERSION + = note: removed in 1.100.0 = note: renamed to `gca_const_items` error[E0557]: feature has been removed @@ -22,7 +22,7 @@ error[E0557]: feature has been removed LL | #![feature(macroless_generic_const_args)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ feature has been removed | - = note: removed in CURRENT_RUSTC_VERSION + = note: removed in 1.100.0 = note: renamed to `gca_macroless_args` error[E0557]: feature has been removed @@ -31,7 +31,7 @@ error[E0557]: feature has been removed LL | #![feature(macroless_const_item_generic_const_args)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ feature has been removed | - = note: removed in CURRENT_RUSTC_VERSION + = note: removed in 1.100.0 = note: renamed to `gca_macroless_items` error: aborting due to 4 previous errors diff --git a/tests/ui/consts/const_in_pattern/suggest_equality_comparison_instead_of_pattern_matching.stderr b/tests/ui/consts/const_in_pattern/suggest_equality_comparison_instead_of_pattern_matching.stderr index ab823c8fc73b9..38440af675feb 100644 --- a/tests/ui/consts/const_in_pattern/suggest_equality_comparison_instead_of_pattern_matching.stderr +++ b/tests/ui/consts/const_in_pattern/suggest_equality_comparison_instead_of_pattern_matching.stderr @@ -123,7 +123,6 @@ LL | V => {} | ^ constant of non-structural type | --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - ::: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL | = note: `Vec<()>` is not usable in patterns | @@ -144,7 +143,6 @@ LL | if let V = vec![] {} | ^ constant of non-structural type | --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - ::: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL | = note: `Vec<()>` is not usable in patterns | @@ -160,7 +158,6 @@ LL | let V = vec![] else { return; }; | ^ constant of non-structural type | --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - ::: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL | = note: `Vec<()>` is not usable in patterns | @@ -176,7 +173,6 @@ LL | let V = Vec::new() else { return; }; | ^ constant of non-structural type | --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - ::: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL | = note: `Vec<()>` is not usable in patterns | diff --git a/tests/ui/fmt/format-args-concat-multibyte-suggestion.rs b/tests/ui/fmt/format-args-concat-multibyte-suggestion.rs new file mode 100644 index 0000000000000..51504607d2b61 --- /dev/null +++ b/tests/ui/fmt/format-args-concat-multibyte-suggestion.rs @@ -0,0 +1,38 @@ +// Regression test for #156101. +// +// When the format string comes from `concat!`, the parser's inner offsets are relative to the +// expanded string, not to the source, so they must not be turned into spans in the source. +// Before the fix, suggestions built from those offsets went wrong in two ways: +// +// - If the span landed inside a multibyte character, rendering the suggestion caused an ICE. +// The `ReorderFormatParameter` and `AddMissingColon` cases below are padded so that the span +// falls inside `é` (2 bytes) or `𐏿` (4 bytes). +// - If the span landed on unrelated source text, `UsePositional` suggested a bogus argument +// copied from that text. +// +// After the fix, no suggestion is emitted for these format strings. + +fn main() { + // The original reproducer from the issue. + format_args!(concat!("𐏿", "{f:?#}")); + //~^ ERROR invalid format string + + // `Suggestion::ReorderFormatParameter` + format_args!(concat!("é", "aaa{:?#}"), 1); + //~^ ERROR invalid format string + format_args!(concat!("𐏿", "a{:?#}"), 1); + //~^ ERROR invalid format string + + // `Suggestion::AddMissingColon` + format_args!(concat!("é", "aaaa{x?}")); + //~^ ERROR invalid format string + format_args!(concat!("𐏿", "aa{x?}")); + //~^ ERROR invalid format string + + // `Suggestion::UsePositional`: these did not ICE, but before the fix they suggested a bogus + // argument taken from the `concat!` invocation instead of from the format string. + format_args!(concat!("{}{a.b}", "")); + //~^ ERROR invalid format string + format_args!(concat!("{}{a.0}", "")); + //~^ ERROR invalid format string +} diff --git a/tests/ui/fmt/format-args-concat-multibyte-suggestion.stderr b/tests/ui/fmt/format-args-concat-multibyte-suggestion.stderr new file mode 100644 index 0000000000000..5eb8a4848a612 --- /dev/null +++ b/tests/ui/fmt/format-args-concat-multibyte-suggestion.stderr @@ -0,0 +1,52 @@ +error: invalid format string: expected `}`, found `#` + --> $DIR/format-args-concat-multibyte-suggestion.rs:17:18 + | +LL | format_args!(concat!("𐏿", "{f:?#}")); + | ^^^^^^^^^^^^^^^^^^^^^^ expected `'}'` in format string + +error: invalid format string: expected `}`, found `#` + --> $DIR/format-args-concat-multibyte-suggestion.rs:21:18 + | +LL | format_args!(concat!("é", "aaa{:?#}"), 1); + | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `'}'` in format string + +error: invalid format string: expected `}`, found `#` + --> $DIR/format-args-concat-multibyte-suggestion.rs:23:18 + | +LL | format_args!(concat!("𐏿", "a{:?#}"), 1); + | ^^^^^^^^^^^^^^^^^^^^^^ expected `'}'` in format string + +error: invalid format string: expected `}`, found `?` + --> $DIR/format-args-concat-multibyte-suggestion.rs:27:18 + | +LL | format_args!(concat!("é", "aaaa{x?}")); + | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `:` before `?` to format with `Debug` in format string + | + = note: to print `{`, you can escape it using `{{` + +error: invalid format string: expected `}`, found `?` + --> $DIR/format-args-concat-multibyte-suggestion.rs:29:18 + | +LL | format_args!(concat!("𐏿", "aa{x?}")); + | ^^^^^^^^^^^^^^^^^^^^^^ expected `:` before `?` to format with `Debug` in format string + | + = note: to print `{`, you can escape it using `{{` + +error: invalid format string: field access isn't supported + --> $DIR/format-args-concat-multibyte-suggestion.rs:34:18 + | +LL | format_args!(concat!("{}{a.b}", "")); + | ^^^^^^^^^^^^^^^^^^^^^^ not supported in format string + | + = note: consider moving this expression to a local variable and then using the local here instead + +error: invalid format string: tuple index access isn't supported + --> $DIR/format-args-concat-multibyte-suggestion.rs:36:18 + | +LL | format_args!(concat!("{}{a.0}", "")); + | ^^^^^^^^^^^^^^^^^^^^^^ not supported in format string + | + = note: consider moving this expression to a local variable and then using the local here instead + +error: aborting due to 7 previous errors + diff --git a/tests/ui/linkage-attr/auxiliary/def_external.rs b/tests/ui/linkage-attr/auxiliary/def_external.rs deleted file mode 100644 index 2300930e513af..0000000000000 --- a/tests/ui/linkage-attr/auxiliary/def_external.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![feature(linkage)] -#![crate_type = "lib"] - -#[linkage="external"] -pub static EXTERN: u32 = 0; diff --git a/tests/ui/linkage-attr/auxiliary/def_weak.rs b/tests/ui/linkage-attr/auxiliary/def_weak.rs new file mode 100644 index 0000000000000..a8940f73c5536 --- /dev/null +++ b/tests/ui/linkage-attr/auxiliary/def_weak.rs @@ -0,0 +1,5 @@ +#![feature(linkage)] +#![crate_type = "lib"] + +#[linkage = "weak"] +pub static WEAK: u32 = 0; diff --git a/tests/ui/linkage-attr/common-linkage-non-zero-init.rs b/tests/ui/linkage-attr/common-linkage-non-zero-init.rs deleted file mode 100644 index 512616251c2f7..0000000000000 --- a/tests/ui/linkage-attr/common-linkage-non-zero-init.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ build-fail -//@ failure-status: 101 -//@ known-bug: #109681 -//@ ignore-wasm32 this appears to SIGABRT on wasm, not fail cleanly -//@ compile-flags: -Z verify-llvm-ir -//@ ignore-backends: gcc - -// This test verifies that we continue to hit the LLVM error for common linkage with non-zero -// initializers, since it generates invalid LLVM IR. -// Linkages are internal features marked as perma-unstable, so we don't need to fix the issue -// for now. -#![crate_type="lib"] -#![feature(linkage)] - -#[linkage = "common"] -#[no_mangle] -pub static TEST: bool = true; diff --git a/tests/ui/linkage-attr/common-linkage-non-zero-init.stderr b/tests/ui/linkage-attr/common-linkage-non-zero-init.stderr deleted file mode 100644 index 93015bb2bac12..0000000000000 --- a/tests/ui/linkage-attr/common-linkage-non-zero-init.stderr +++ /dev/null @@ -1,3 +0,0 @@ -'common' global must have a zero initializer! -ptr @TEST -rustc-LLVM ERROR: Broken module found, compilation aborted! diff --git a/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs b/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs index 0717a2d5a6c9e..e1ad2405b1df8 100644 --- a/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs +++ b/tests/ui/linkage-attr/linkage-attr-does-not-panic-llvm-issue-33992.rs @@ -1,15 +1,9 @@ //@ run-pass //@ ignore-apple -//@ ignore-wasm32 common linkage not implemented right now +//@ ignore-wasm32 linkonce linkage not working right now #![feature(linkage)] -#[linkage = "external"] -pub static TEST2: bool = true; - -#[linkage = "internal"] -pub static TEST3: bool = true; - #[cfg(not(target_env = "msvc"))] #[linkage = "linkonce"] pub static TEST4: bool = true; diff --git a/tests/ui/linkage-attr/linkage-import.rs b/tests/ui/linkage-attr/linkage-import.rs index 838d1fc29a238..427a487ef1905 100644 --- a/tests/ui/linkage-attr/linkage-import.rs +++ b/tests/ui/linkage-attr/linkage-import.rs @@ -1,8 +1,10 @@ //@ build-pass -//@ aux-build:def_external.rs +//@ aux-build:def_weak.rs +//@ ignore-i686-pc-windows-gnu weak symbols broken with MinGW linker +//@ ignore-x86_64-pc-windows-gnu weak symbols broken with MinGW linker -extern crate def_external as dep; +extern crate def_weak as dep; fn main() { - println!("{:p}", &dep::EXTERN); + println!("{:p}", &dep::WEAK); } diff --git a/tests/ui/linkage-attr/linkage3.stderr b/tests/ui/linkage-attr/linkage3.stderr index aa25cd39ba291..616f80df09c8b 100644 --- a/tests/ui/linkage-attr/linkage3.stderr +++ b/tests/ui/linkage-attr/linkage3.stderr @@ -4,7 +4,7 @@ error[E0539]: malformed `linkage` attribute input LL | #[linkage = "foo"] | ^^^^^^^^^^----- | | - | valid arguments are `available_externally`, `common`, `extern_weak`, `external`, `internal`, `linkonce`, `linkonce_odr`, `weak` or `weak_odr` + | valid arguments are `available_externally`, `extern_weak`, `linkonce`, `linkonce_odr`, `weak` or `weak_odr` error: aborting due to 1 previous error diff --git a/tests/ui/linkage-attr/linkage4.rs b/tests/ui/linkage-attr/linkage4.rs index 3b935f9723dc1..25df81189d8f5 100644 --- a/tests/ui/linkage-attr/linkage4.rs +++ b/tests/ui/linkage-attr/linkage4.rs @@ -1,4 +1,4 @@ -#[linkage = "external"] +#[linkage = "weak"] static foo: isize = 0; //~^^ ERROR: the `linkage` attribute is experimental and not portable diff --git a/tests/ui/linkage-attr/linkage4.stderr b/tests/ui/linkage-attr/linkage4.stderr index a5970d100581a..2f04ceee5199d 100644 --- a/tests/ui/linkage-attr/linkage4.stderr +++ b/tests/ui/linkage-attr/linkage4.stderr @@ -1,7 +1,7 @@ error[E0658]: the `linkage` attribute is experimental and not portable across platforms --> $DIR/linkage4.rs:1:3 | -LL | #[linkage = "external"] +LL | #[linkage = "weak"] | ^^^^^^^ | = note: see issue #29603 for more information diff --git a/tests/ui/lint/inline-exported.rs b/tests/ui/lint/inline-exported.rs index 6a23cd58236ff..25ca5f0633079 100644 --- a/tests/ui/lint/inline-exported.rs +++ b/tests/ui/lint/inline-exported.rs @@ -17,12 +17,8 @@ fn export_name() {} #[inline] //~^ ERROR: `#[inline]` is ignored on externally exported functions -#[linkage = "external"] -fn external_linkage() {} +#[linkage = "weak"] +fn weak_linkage() {} #[inline] fn normal() {} - -#[inline] -#[linkage = "internal"] // not exported -fn internal_linkage() {} diff --git a/tests/ui/pattern/deref-patterns/implicit-const-deref.stderr b/tests/ui/pattern/deref-patterns/implicit-const-deref.stderr index c03137fcc4151..7c176162ad184 100644 --- a/tests/ui/pattern/deref-patterns/implicit-const-deref.stderr +++ b/tests/ui/pattern/deref-patterns/implicit-const-deref.stderr @@ -8,7 +8,6 @@ LL | EMPTY => {} | ^^^^^ constant of non-structural type | --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - ::: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL | = note: `Vec<()>` is not usable in patterns | diff --git a/tests/ui/pattern/issue-115599.stderr b/tests/ui/pattern/issue-115599.stderr index 280516deba14b..f776623ff75b2 100644 --- a/tests/ui/pattern/issue-115599.stderr +++ b/tests/ui/pattern/issue-115599.stderr @@ -8,7 +8,6 @@ LL | if let CONST_STRING = empty_str {} | ^^^^^^^^^^^^ constant of non-structural type | --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - ::: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL | = note: `Vec` is not usable in patterns | diff --git a/tests/ui/pattern/pattern-tyvar-2.stderr b/tests/ui/pattern/pattern-tyvar-2.stderr index 4761a4e829b85..6676d5129872b 100644 --- a/tests/ui/pattern/pattern-tyvar-2.stderr +++ b/tests/ui/pattern/pattern-tyvar-2.stderr @@ -8,7 +8,6 @@ LL | fn foo(t: Bar) -> isize { match t { Bar::T1(_, Some(x)) => { return x * 3; | note: `Vec` does not implement `Mul<{integer}>` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - ::: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL | = note: `Vec` is defined in another crate diff --git a/tests/ui/reborrow/reborrow-drop.rs b/tests/ui/reborrow/reborrow-drop.rs new file mode 100644 index 0000000000000..bc88bb79b9b4b --- /dev/null +++ b/tests/ui/reborrow/reborrow-drop.rs @@ -0,0 +1,14 @@ +//@ compile-flags: --crate-type=lib + +#![feature(reborrow)] + +use std::marker::Reborrow; + +struct MyMut<'a>(&'a mut ()); + +impl Reborrow for MyMut<'_> {} +//~^ ERROR the trait `Reborrow` cannot be implemented for this type; the type has a destructor [E0184] + +impl Drop for MyMut<'_> { + fn drop(&mut self) {} +} diff --git a/tests/ui/reborrow/reborrow-drop.stderr b/tests/ui/reborrow/reborrow-drop.stderr new file mode 100644 index 0000000000000..d35b36530d588 --- /dev/null +++ b/tests/ui/reborrow/reborrow-drop.stderr @@ -0,0 +1,15 @@ +error[E0184]: the trait `Reborrow` cannot be implemented for this type; the type has a destructor + --> $DIR/reborrow-drop.rs:9:1 + | +LL | impl Reborrow for MyMut<'_> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Reborrow` not allowed on types with destructors + | +note: destructor declared here + --> $DIR/reborrow-drop.rs:13:5 + | +LL | fn drop(&mut self) {} + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0184`. diff --git a/tests/ui/sized-hierarchy/overflow.current.stderr b/tests/ui/sized-hierarchy/overflow.current.stderr index 9853be2a7f8e0..3573ee48db57c 100644 --- a/tests/ui/sized-hierarchy/overflow.current.stderr +++ b/tests/ui/sized-hierarchy/overflow.current.stderr @@ -1,11 +1,11 @@ error[E0275]: overflow evaluating the requirement `Element: MetaSized` - --> $DIR/overflow.rs:17:16 + --> $DIR/overflow.rs:15:16 | LL | struct Element(> as ParseTokens>::Output); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: required for `Box` to implement `ParseTokens` - --> $DIR/overflow.rs:13:31 + --> $DIR/overflow.rs:11:31 | LL | impl ParseTokens for Box { | ------ ^^^^^^^^^^^ ^^^^^^ @@ -15,25 +15,25 @@ LL | impl ParseTokens for Box { = note: required for `Box>` to implement `ParseTokens` error[E0275]: overflow evaluating the requirement `Box: ParseTokens` - --> $DIR/overflow.rs:19:22 + --> $DIR/overflow.rs:18:22 | LL | impl ParseTokens for Element { | ^^^^^^^ | note: required for `Box>` to implement `ParseTokens` - --> $DIR/overflow.rs:13:31 + --> $DIR/overflow.rs:11:31 | LL | impl ParseTokens for Box { | ----------- ^^^^^^^^^^^ ^^^^^^ | | | unsatisfied trait bound introduced here note: required because it appears within the type `Element` - --> $DIR/overflow.rs:17:8 + --> $DIR/overflow.rs:15:8 | LL | struct Element(> as ParseTokens>::Output); | ^^^^^^^ note: required by a bound in `ParseTokens` - --> $DIR/overflow.rs:10:1 + --> $DIR/overflow.rs:8:1 | LL | / trait ParseTokens { LL | | type Output; diff --git a/tests/ui/sized-hierarchy/overflow.next.stderr b/tests/ui/sized-hierarchy/overflow.next.stderr new file mode 100644 index 0000000000000..69842a298f87f --- /dev/null +++ b/tests/ui/sized-hierarchy/overflow.next.stderr @@ -0,0 +1,29 @@ +error[E0275]: overflow evaluating the requirement `> as ParseTokens>::Output == _` + --> $DIR/overflow.rs:15:16 + | +LL | struct Element(> as ParseTokens>::Output); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0275]: overflow evaluating whether `> as ParseTokens>::Output` is well-formed + --> $DIR/overflow.rs:15:16 + | +LL | struct Element(> as ParseTokens>::Output); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0275]: overflow evaluating the requirement `Element: MetaSized` + --> $DIR/overflow.rs:18:22 + | +LL | impl ParseTokens for Element { + | ^^^^^^^ + | +note: required by a bound in `ParseTokens` + --> $DIR/overflow.rs:8:1 + | +LL | / trait ParseTokens { +LL | | type Output; +LL | | } + | |_^ required by this bound in `ParseTokens` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/sized-hierarchy/overflow.rs b/tests/ui/sized-hierarchy/overflow.rs index 31c2ca8a49171..f69f56ef898e2 100644 --- a/tests/ui/sized-hierarchy/overflow.rs +++ b/tests/ui/sized-hierarchy/overflow.rs @@ -1,8 +1,6 @@ //@ compile-flags: --crate-type=lib //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) -//@[current] check-fail -//@[next] check-pass //@[next] compile-flags: -Znext-solver use std::marker::PhantomData; @@ -15,8 +13,9 @@ impl ParseTokens for Box { } struct Element(> as ParseTokens>::Output); -//[current]~^ ERROR: overflow +//~^ ERROR: overflow +//[next]~| ERROR: overflow impl ParseTokens for Element { -//[current]~^ ERROR: overflow +//~^ ERROR: overflow type Output = (); } diff --git a/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed-trait.current.stderr b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed-trait.current.stderr index 89b8b53c3f4d9..d6cd080cbfd0b 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed-trait.current.stderr +++ b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed-trait.current.stderr @@ -1,18 +1,18 @@ error[E0275]: overflow evaluating the requirement `u32: SendIndir>` - --> $DIR/only-one-coinductive-step-needed-trait.rs:24:5 + --> $DIR/only-one-coinductive-step-needed-trait.rs:25:5 | LL | is_send::>(); | ^^^^^^^^^^^^^^^^^^^^^ | note: required for `Foo` to implement `Send` - --> $DIR/only-one-coinductive-step-needed-trait.rs:17:35 + --> $DIR/only-one-coinductive-step-needed-trait.rs:18:35 | LL | unsafe impl>> Send for Foo {} | ----------------- ^^^^ ^^^^^^ | | | unsatisfied trait bound introduced here note: required by a bound in `is_send` - --> $DIR/only-one-coinductive-step-needed-trait.rs:22:15 + --> $DIR/only-one-coinductive-step-needed-trait.rs:23:15 | LL | fn is_send() {} | ^^^^ required by this bound in `is_send` diff --git a/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed-trait.next.stderr b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed-trait.next.stderr new file mode 100644 index 0000000000000..40ae37e495204 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed-trait.next.stderr @@ -0,0 +1,15 @@ +error[E0275]: overflow evaluating the requirement `Foo: Send` + --> $DIR/only-one-coinductive-step-needed-trait.rs:25:15 + | +LL | is_send::>(); + | ^^^^^^^^ + | +note: required by a bound in `is_send` + --> $DIR/only-one-coinductive-step-needed-trait.rs:23:15 + | +LL | fn is_send() {} + | ^^^^ required by this bound in `is_send` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed-trait.rs b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed-trait.rs index 294156869284a..a8d23129fb87c 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed-trait.rs +++ b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed-trait.rs @@ -1,7 +1,6 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[next] check-pass // #136824 changed cycles to be coinductive if they have at least // one productive step, causing this test to pass with the new solver. @@ -12,6 +11,8 @@ // - `Foo: Send` cycle // // The old solver treats this cycle as inductive due to the `T: SendIndir` step. +// We later changed the new solver to temporarily be closer to the old solver +// again, so this now errors with both solvers. struct Foo(T); unsafe impl>> Send for Foo {} @@ -23,4 +24,5 @@ fn is_send() {} fn main() { is_send::>(); //[current]~^ ERROR overflow evaluating the requirement `u32: SendIndir>` + //[next]~^^ ERROR overflow evaluating the requirement `Foo: Send` } diff --git a/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.current.stderr b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.current.stderr index ec21987805869..1d7916f32b1db 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.current.stderr +++ b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.current.stderr @@ -1,11 +1,11 @@ error[E0275]: overflow evaluating the requirement `Foo: SendIndir` - --> $DIR/only-one-coinductive-step-needed.rs:17:15 + --> $DIR/only-one-coinductive-step-needed.rs:18:15 | LL | struct Foo( as Trait>::Assoc); | ^^^^^^^^^^^^^^^^^^^^^^^^ | note: required for `Foo` to implement `Trait` - --> $DIR/only-one-coinductive-step-needed.rs:26:20 + --> $DIR/only-one-coinductive-step-needed.rs:29:20 | LL | impl Trait for T { | --------- ^^^^^ ^ diff --git a/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.next.stderr b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.next.stderr new file mode 100644 index 0000000000000..071945d760345 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.next.stderr @@ -0,0 +1,43 @@ +error[E0275]: overflow evaluating the requirement ` as Trait>::Assoc == _` + --> $DIR/only-one-coinductive-step-needed.rs:18:15 + | +LL | struct Foo( as Trait>::Assoc); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0275]: overflow evaluating whether ` as Trait>::Assoc` is well-formed + --> $DIR/only-one-coinductive-step-needed.rs:18:15 + | +LL | struct Foo( as Trait>::Assoc); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0275]: overflow evaluating the requirement `Foo: Send` + --> $DIR/only-one-coinductive-step-needed.rs:36:15 + | +LL | is_send::>(); + | ^^^^^^^^ + | +note: required by a bound in `is_send` + --> $DIR/only-one-coinductive-step-needed.rs:33:15 + | +LL | fn is_send() {} + | ^^^^ required by this bound in `is_send` + +error[E0275]: overflow evaluating the requirement `Foo: Sized` + --> $DIR/only-one-coinductive-step-needed.rs:36:15 + | +LL | is_send::>(); + | ^^^^^^^^ + | +note: required by an implicit `Sized` bound in `is_send` + --> $DIR/only-one-coinductive-step-needed.rs:33:12 + | +LL | fn is_send() {} + | ^ required by the implicit `Sized` requirement on this type parameter in `is_send` +help: consider relaxing the implicit `Sized` restriction + | +LL | fn is_send() {} + | ++++++++ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.rs b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.rs index e41f7d7f3ceb3..9a13c0e945339 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.rs +++ b/tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.rs @@ -1,7 +1,6 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[next] check-pass // #136824 changed cycles to be coinductive if they have at least // one productive step, causing this test to pass with the new solver. @@ -12,10 +11,14 @@ // - `Foo: SendIndir`, via impl requires // - `Foo: Send` cycle // -// The old solver treats this cycle as inductive due to the `Foo: SendIndir` step. +// The old solver treats this cycle as inductive due to the `Foo: SendIndir` step. We've +// since changed the new solver to more closely match the old one here, also +// resulting in an inductive cycle for now. struct Foo( as Trait>::Assoc); -//[current]~^ ERROR overflow evaluating the requirement `Foo: SendIndir` +//[current]~^ ERROR: overflow evaluating the requirement `Foo: SendIndir` +//[next]~^^ ERROR: overflow evaluating the requirement ` as Trait>::Assoc == _` +//[next]~| ERROR: overflow evaluating whether ` as Trait>::Assoc` is well-formed trait SendIndir {} impl SendIndir for T {} @@ -31,4 +34,6 @@ fn is_send() {} fn main() { is_send::>(); + //[next]~^ ERROR: overflow evaluating the requirement `Foo: Send` + //[next]~| ERROR: overflow evaluating the requirement `Foo: Sized` } diff --git a/tests/ui/traits/next-solver/cycles/cycle-requires-resolving-regions.current.stderr b/tests/ui/traits/next-solver/cycles/cycle-requires-resolving-regions.current.stderr new file mode 100644 index 0000000000000..477b0ba993104 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/cycle-requires-resolving-regions.current.stderr @@ -0,0 +1,26 @@ +error[E0275]: overflow evaluating the requirement `Foo<'_>: Send` + --> $DIR/cycle-requires-resolving-regions.rs:31:5 + | +LL | require::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`cycle_requires_resolving_regions`) +note: required for `Foo<'_>` to implement `Send` + --> $DIR/cycle-requires-resolving-regions.rs:23:17 + | +LL | unsafe impl<'a> Send for Foo<'a> + | ^^^^ ^^^^^^^ +LL | where +LL | Foo<'a>: Send, + | ---- unsatisfied trait bound introduced here + = note: 128 redundant requirements hidden + = note: required for `Foo<'static>` to implement `Send` +note: required by a bound in `require` + --> $DIR/cycle-requires-resolving-regions.rs:28:15 + | +LL | fn require() {} + | ^^^^ required by this bound in `require` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/cycles/cycle-requires-resolving-regions.rs b/tests/ui/traits/next-solver/cycles/cycle-requires-resolving-regions.rs new file mode 100644 index 0000000000000..2e1eaff4b9479 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/cycle-requires-resolving-regions.rs @@ -0,0 +1,33 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] check-pass + +// A test showcasing a behavior change in cycle detection between +// the old and new solver. The old solver detects cycles in both +// fulfill and in evaluate. The cycle detection in fulfillment +// does not resolve regions. Each occurance of the `Foo<'a>: Send` +// impl creates a fresh inference variable even if it is later +// constrainted to `'static`. This means we never detect a cycle. +// +// This is not an issue with builtin auto-trait impls as they don't +// create impl args instead, simply using the generic arguments of +// the self type directly. +// +// The new solver properly resolves regions. The old solver does resolve +// regions in `project`, so there we do detect cycles even if there are +// fresh region variables. + +struct Foo<'a>(&'a ()); + +unsafe impl<'a> Send for Foo<'a> +where + Foo<'a>: Send, +{} + +fn require() {} + +fn main() { + require::>(); + //[current]~^ ERROR: overflow evaluating the requirement `Foo<'_>: Send` +}