diff --git a/Cargo.lock b/Cargo.lock index 24cd5b825b265..8be13e84596da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5984,9 +5984,9 @@ dependencies = [ [[package]] name = "wasm-component-ld" -version = "0.5.16" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14cd35d6cae91109a0ffd207b573cf3c741cab7e921dd376ea7aaf2c52a3408c" +checksum = "1c9208f87cac2332fd80dcf36d54e9163d3446e28301e0c6e424984425738984" dependencies = [ "anyhow", "clap", @@ -5994,9 +5994,9 @@ dependencies = [ "libc", "tempfile", "wasi-preview1-component-adapter-provider", - "wasmparser 0.237.0", + "wasmparser 0.239.0", "wat", - "windows-sys 0.59.0", + "windows-sys 0.60.2", "winsplit", "wit-component", "wit-parser", @@ -6021,24 +6021,24 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.237.0" +version = "0.239.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efe92d1321afa53ffc88a57c497bb7330c3cf84c98ffdba4a4caf6a0684fad3c" +checksum = "5be00faa2b4950c76fe618c409d2c3ea5a3c9422013e079482d78544bb2d184c" dependencies = [ "leb128fmt", - "wasmparser 0.237.0", + "wasmparser 0.239.0", ] [[package]] name = "wasm-metadata" -version = "0.237.0" +version = "0.239.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cc0b0a0c4f35ca6efa7a797671372915d4e9659dba2d59edc6fafc931d19997" +checksum = "20b3ec880a9ac69ccd92fbdbcf46ee833071cf09f82bb005b2327c7ae6025ae2" dependencies = [ "anyhow", "indexmap", - "wasm-encoder 0.237.0", - "wasmparser 0.237.0", + "wasm-encoder 0.239.0", + "wasmparser 0.239.0", ] [[package]] @@ -6063,9 +6063,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.237.0" +version = "0.239.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d2a40ca0d2bdf4b0bf36c13a737d0b2c58e4c8aaefe1c57f336dd75369ca250" +checksum = "8c9d90bb93e764f6beabf1d02028c70a2156a6583e63ac4218dd07ef733368b0" dependencies = [ "bitflags", "hashbrown", @@ -6076,22 +6076,22 @@ dependencies = [ [[package]] name = "wast" -version = "237.0.0" +version = "239.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf66f545acbd55082485cb9a6daab54579cb8628a027162253e8e9f5963c767" +checksum = "9139176fe8a2590e0fb174cdcaf373b224cb93c3dde08e4297c1361d2ba1ea5d" dependencies = [ "bumpalo", "leb128fmt", "memchr", "unicode-width 0.2.1", - "wasm-encoder 0.237.0", + "wasm-encoder 0.239.0", ] [[package]] name = "wat" -version = "1.237.0" +version = "1.239.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27975186f549e4b8d6878b627be732863883c72f7bf4dcf8f96e5f8242f73da9" +checksum = "3e1c941927d34709f255558166f8901a2005f8ab4a9650432e9281b7cc6f3b75" dependencies = [ "wast", ] @@ -6580,9 +6580,9 @@ dependencies = [ [[package]] name = "wit-component" -version = "0.237.0" +version = "0.239.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfb7674f76c10e82fe00b256a9d4ffb2b8d037d42ab8e9a83ebb3be35c9d0bf6" +checksum = "88a866b19dba2c94d706ec58c92a4c62ab63e482b4c935d2a085ac94caecb136" dependencies = [ "anyhow", "bitflags", @@ -6591,17 +6591,17 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "wasm-encoder 0.237.0", + "wasm-encoder 0.239.0", "wasm-metadata", - "wasmparser 0.237.0", + "wasmparser 0.239.0", "wit-parser", ] [[package]] name = "wit-parser" -version = "0.237.0" +version = "0.239.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce2596a5bc7c24cc965b56ad6ff9e32394c4e401764f89620a888519c6e849ab" +checksum = "55c92c939d667b7bf0c6bf2d1f67196529758f99a2a45a3355cc56964fd5315d" dependencies = [ "anyhow", "id-arena", @@ -6612,7 +6612,7 @@ dependencies = [ "serde_derive", "serde_json", "unicode-xid", - "wasmparser 0.237.0", + "wasmparser 0.239.0", ] [[package]] diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 3674814b796c2..bb6b25baf013d 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1536,7 +1536,13 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::LangItem::Range } } - (None, Some(..), Closed) => hir::LangItem::RangeToInclusive, + (None, Some(..), Closed) => { + if self.tcx.features().new_range() { + hir::LangItem::RangeToInclusiveCopy + } else { + hir::LangItem::RangeToInclusive + } + } (Some(e1), Some(e2), Closed) => { if self.tcx.features().new_range() { hir::LangItem::RangeInclusiveCopy @@ -1560,13 +1566,26 @@ impl<'hir> LoweringContext<'_, 'hir> { }; let fields = self.arena.alloc_from_iter( - e1.iter().map(|e| (sym::start, e)).chain(e2.iter().map(|e| (sym::end, e))).map( - |(s, e)| { + e1.iter() + .map(|e| (sym::start, e)) + .chain(e2.iter().map(|e| { + ( + if matches!( + lang_item, + hir::LangItem::RangeInclusiveCopy | hir::LangItem::RangeToInclusiveCopy + ) { + sym::last + } else { + sym::end + }, + e, + ) + })) + .map(|(s, e)| { let expr = self.lower_expr(e); let ident = Ident::new(s, self.lower_span(e.span)); self.expr_field(ident, expr, e.span) - }, - ), + }), ); hir::ExprKind::Struct( diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index ffdacff71521e..d5d51f2e79ab8 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -218,6 +218,7 @@ impl AttributeParser for NakedParser { sym::rustc_std_internal_symbol, // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity sym::rustc_align, + sym::rustc_align_static, // obviously compatible with self sym::naked, // documentation diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs index 23aabd1559762..0330e2515c7df 100644 --- a/compiler/rustc_attr_parsing/src/attributes/repr.rs +++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs @@ -331,3 +331,30 @@ impl AttributeParser for AlignParser { Some(AttributeKind::Align { align, span }) } } + +#[derive(Default)] +pub(crate) struct AlignStaticParser(AlignParser); + +impl AlignStaticParser { + const PATH: &'static [Symbol] = &[sym::rustc_align_static]; + const TEMPLATE: AttributeTemplate = AlignParser::TEMPLATE; + + fn parse<'c, S: Stage>( + &mut self, + cx: &'c mut AcceptContext<'_, '_, S>, + args: &'c ArgParser<'_>, + ) { + self.0.parse(cx, args) + } +} + +impl AttributeParser for AlignStaticParser { + const ATTRIBUTES: AcceptMapping = &[(Self::PATH, Self::TEMPLATE, Self::parse)]; + const ALLOWED_TARGETS: AllowedTargets = + AllowedTargets::AllowList(&[Allow(Target::Static), Allow(Target::ForeignStatic)]); + + fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option { + let (align, span) = self.0.0?; + Some(AttributeKind::Align { align, span }) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 98e86838a3a18..d2b35090135da 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -50,7 +50,7 @@ use crate::attributes::proc_macro_attrs::{ ProcMacroAttributeParser, ProcMacroDeriveParser, ProcMacroParser, RustcBuiltinMacroParser, }; use crate::attributes::prototype::CustomMirParser; -use crate::attributes::repr::{AlignParser, ReprParser}; +use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart, RustcObjectLifetimeDefaultParser, @@ -152,6 +152,7 @@ attribute_parsers!( pub(crate) static ATTRIBUTE_PARSERS = [ // tidy-alphabetical-start AlignParser, + AlignStaticParser, BodyStabilityParser, ConfusablesParser, ConstStabilityParser, diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index 619277eba8b83..7fe8fc122b3cc 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -81,6 +81,8 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> { if global.to_rvalue().get_type() != val_llty { global.to_rvalue().set_type(val_llty); } + + // NOTE: Alignment from attributes has already been applied to the allocation. set_global_alignment(self, global, alloc.align); global.global_set_initializer_rvalue(value); diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 9ec7b0f80aee7..dc9bb743560dd 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -452,6 +452,8 @@ impl<'ll> CodegenCx<'ll, '_> { self.statics_to_rauw.borrow_mut().push((g, new_g)); new_g }; + + // NOTE: Alignment from attributes has already been applied to the allocation. set_global_alignment(self, g, alloc.align); llvm::set_initializer(g, v); diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 6ec85648d6d88..ebcdb9461d024 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -953,6 +953,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // # Global allocations if let Some(global_alloc) = self.tcx.try_get_global_alloc(id) { + // NOTE: `static` alignment from attributes has already been applied to the allocation. let (size, align) = global_alloc.size_and_align(*self.tcx, self.typing_env); let mutbl = global_alloc.mutability(*self.tcx, self.typing_env); let kind = match global_alloc { diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index 72bee34540656..f667823723c0a 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -1,6 +1,6 @@ use rustc_hir::def_id::LocalDefId; use rustc_middle::mir; -use rustc_middle::mir::interpret::{AllocInit, Allocation, InterpResult, Pointer}; +use rustc_middle::mir::interpret::{AllocInit, Allocation, GlobalAlloc, InterpResult, Pointer}; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::{TyCtxt, TypeVisitable, TypeVisitableExt}; use tracing::debug; @@ -38,7 +38,14 @@ pub(crate) fn create_static_alloc<'tcx>( static_def_id: LocalDefId, layout: TyAndLayout<'tcx>, ) -> InterpResult<'tcx, MPlaceTy<'tcx>> { - let alloc = Allocation::try_new(layout.size, layout.align.abi, AllocInit::Uninit, ())?; + // Inherit size and align from the `GlobalAlloc::Static` so we can avoid duplicating + // the alignment attribute logic. + let (size, align) = + GlobalAlloc::Static(static_def_id.into()).size_and_align(*ecx.tcx, ecx.typing_env); + assert_eq!(size, layout.size); + assert!(align >= layout.align.abi); + + let alloc = Allocation::try_new(size, align, AllocInit::Uninit, ())?; let alloc_id = ecx.tcx.reserve_and_set_static_alloc(static_def_id.into()); assert_eq!(ecx.machine.static_root_ids, None); ecx.machine.static_root_ids = Some((alloc_id, static_def_id)); diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index e81003b18972a..129ab7eccb577 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -621,6 +621,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity gated!(rustc_align, Normal, template!(List: &["alignment"]), DuplicatesOk, EncodeCrossCrate::No, fn_align, experimental!(rustc_align)), + gated!(rustc_align_static, Normal, template!(List: &["alignment"]), DuplicatesOk, EncodeCrossCrate::No, static_align, experimental!(rustc_align_static)), ungated!( unsafe(Edition2024) export_name, Normal, template!(NameValueStr: "name", "https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute"), diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 4f35bf63a1a43..93e5588146e14 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -632,6 +632,8 @@ declare_features! ( (unstable, simd_ffi, "1.0.0", Some(27731)), /// Allows specialization of implementations (RFC 1210). (incomplete, specialization, "1.7.0", Some(31844)), + /// Allows using `#[rustc_align_static(...)]` on static items. + (unstable, static_align, "CURRENT_RUSTC_VERSION", Some(146177)), /// Allows attributes on expressions and non-item statements. (unstable, stmt_expr_attributes, "1.6.0", Some(15701)), /// Allows lints part of the strict provenance effort. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index ae03121e5f705..75551fe4c196a 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2614,6 +2614,18 @@ impl Expr<'_> { StructTailExpr::None, ), ) + | ( + ExprKind::Struct( + QPath::LangItem(LangItem::RangeToInclusiveCopy, _), + [val1], + StructTailExpr::None, + ), + ExprKind::Struct( + QPath::LangItem(LangItem::RangeToInclusiveCopy, _), + [val2], + StructTailExpr::None, + ), + ) | ( ExprKind::Struct( QPath::LangItem(LangItem::RangeFrom, _), @@ -2705,7 +2717,8 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool { | LangItem::RangeToInclusive | LangItem::RangeCopy | LangItem::RangeFromCopy - | LangItem::RangeInclusiveCopy, + | LangItem::RangeInclusiveCopy + | LangItem::RangeToInclusiveCopy, .. ) ), diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 0464665b41fc5..67d2f15d41472 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -422,6 +422,7 @@ language_item_table! { RangeFromCopy, sym::RangeFromCopy, range_from_copy_struct, Target::Struct, GenericRequirement::None; RangeCopy, sym::RangeCopy, range_copy_struct, Target::Struct, GenericRequirement::None; RangeInclusiveCopy, sym::RangeInclusiveCopy, range_inclusive_copy_struct, Target::Struct, GenericRequirement::None; + RangeToInclusiveCopy, sym::RangeToInclusiveCopy, range_to_inclusive_copy_struct, Target::Struct, GenericRequirement::None; String, sym::String, string, Target::Struct, GenericRequirement::None; CStr, sym::CStr, c_str, Target::Struct, GenericRequirement::None; diff --git a/compiler/rustc_index/src/idx.rs b/compiler/rustc_index/src/idx.rs index 33f406e21137d..9cd7134659c55 100644 --- a/compiler/rustc_index/src/idx.rs +++ b/compiler/rustc_index/src/idx.rs @@ -130,7 +130,22 @@ impl IntoSliceIdx for core::range::RangeFrom { impl IntoSliceIdx for core::range::RangeInclusive { type Output = core::range::RangeInclusive; #[inline] + #[cfg(bootstrap)] fn into_slice_idx(self) -> Self::Output { core::range::RangeInclusive { start: self.start.index(), end: self.end.index() } } + #[inline] + #[cfg(not(bootstrap))] + fn into_slice_idx(self) -> Self::Output { + core::range::RangeInclusive { start: self.start.index(), last: self.last.index() } + } +} + +#[cfg(all(feature = "nightly", not(bootstrap)))] +impl IntoSliceIdx for core::range::RangeToInclusive { + type Output = core::range::RangeToInclusive; + #[inline] + fn into_slice_idx(self) -> Self::Output { + core::range::RangeToInclusive { last: self.last.index() } + } } diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index bed99a4ff2ab2..9762e0f21da9f 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -386,7 +386,16 @@ impl<'tcx> GlobalAlloc<'tcx> { .expect("statics should not have generic parameters"); let layout = tcx.layout_of(typing_env.as_query_input(ty)).unwrap(); assert!(layout.is_sized()); - (layout.size, layout.align.abi) + + // Take over-alignment from attributes into account. + let align = match tcx.codegen_fn_attrs(def_id).alignment { + Some(align_from_attribute) => { + Ord::max(align_from_attribute, layout.align.abi) + } + None => layout.align.abi, + }; + + (layout.size, align) } } GlobalAlloc::Memory(alloc) => { diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index a7d99f513a12a..f9d0a5f0a3b66 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -78,8 +78,9 @@ impl<'dis, 'de, 'tcx> MirDumper<'dis, 'de, 'tcx> { pub fn new(tcx: TyCtxt<'tcx>, pass_name: &'static str, body: &Body<'tcx>) -> Option { let dump_enabled = if let Some(ref filters) = tcx.sess.opts.unstable_opts.dump_mir { // see notes on #41697 below - let node_path = - ty::print::with_forced_impl_filename_line!(tcx.def_path_str(body.source.def_id())); + let node_path = ty::print::with_no_trimmed_paths!( + ty::print::with_forced_impl_filename_line!(tcx.def_path_str(body.source.def_id())) + ); filters.split('|').any(|or_filter| { or_filter.split('&').all(|and_filter| { let and_filter_trimmed = and_filter.trim(); @@ -173,9 +174,10 @@ impl<'dis, 'de, 'tcx> MirDumper<'dis, 'de, 'tcx> { // trigger `type_of`, and this can run while we are already attempting to evaluate `type_of`. pub fn dump_mir_to_writer(&self, body: &Body<'tcx>, w: &mut dyn io::Write) -> io::Result<()> { // see notes on #41697 above - let def_path = ty::print::with_forced_impl_filename_line!( - self.tcx().def_path_str(body.source.def_id()) - ); + let def_path = + ty::print::with_no_trimmed_paths!(ty::print::with_forced_impl_filename_line!( + self.tcx().def_path_str(body.source.def_id()) + )); // ignore-tidy-odd-backticks the literal below is fine write!(w, "// MIR for `{def_path}")?; match body.source.promoted { diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index afd08319738df..ab7885905a6e7 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -501,6 +501,10 @@ passes_repr_align_should_be_align = `#[repr(align(...))]` is not supported on {$item} .help = use `#[rustc_align(...)]` instead +passes_repr_align_should_be_align_static = + `#[repr(align(...))]` is not supported on {$item} + .help = use `#[rustc_align_static(...)]` instead + passes_repr_conflicting = conflicting representation hints diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 487bdd2a888e7..38a6b4b16c938 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1606,12 +1606,18 @@ impl<'tcx> CheckAttrVisitor<'tcx> { ReprAttr::ReprAlign(align) => { match target { Target::Struct | Target::Union | Target::Enum => {} - Target::Fn | Target::Method(_) => { + Target::Fn | Target::Method(_) if self.tcx.features().fn_align() => { self.dcx().emit_err(errors::ReprAlignShouldBeAlign { span: *repr_span, item: target.plural_name(), }); } + Target::Static if self.tcx.features().static_align() => { + self.dcx().emit_err(errors::ReprAlignShouldBeAlignStatic { + span: *repr_span, + item: target.plural_name(), + }); + } _ => { self.dcx().emit_err(errors::AttrApplication::StructEnumUnion { hint_span: *repr_span, diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 23dcabef1a177..2da4b6f52cf2c 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1609,6 +1609,15 @@ pub(crate) struct ReprAlignShouldBeAlign { pub item: &'static str, } +#[derive(Diagnostic)] +#[diag(passes_repr_align_should_be_align_static)] +pub(crate) struct ReprAlignShouldBeAlignStatic { + #[primary_span] + #[help] + pub span: Span, + pub item: &'static str, +} + #[derive(Diagnostic)] #[diag(passes_custom_mir_phase_requires_dialect)] pub(crate) struct CustomMirPhaseRequiresDialect { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index e5108d8b7e921..e21ff83c4009f 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -326,6 +326,7 @@ symbols! { RangeSub, RangeTo, RangeToInclusive, + RangeToInclusiveCopy, Rc, RcWeak, Ready, @@ -1280,6 +1281,7 @@ symbols! { lang, lang_items, large_assignments, + last, lateout, lazy_normalization_consts, lazy_type_alias, @@ -1846,6 +1848,7 @@ symbols! { rustc_abi, // FIXME(#82232, #143834): temporary name to mitigate `#[align]` nameres ambiguity rustc_align, + rustc_align_static, rustc_allocator, rustc_allocator_zeroed, rustc_allocator_zeroed_variant, @@ -2097,6 +2100,7 @@ symbols! { staged_api, start, state, + static_align, static_in_const, static_nobundle, static_recursion, diff --git a/library/core/src/range.rs b/library/core/src/range.rs index 332ae51d8484e..8c49123fdaf56 100644 --- a/library/core/src/range.rs +++ b/library/core/src/range.rs @@ -31,9 +31,7 @@ pub use iter::{IterRange, IterRangeFrom, IterRangeInclusive}; #[doc(inline)] pub use crate::iter::Step; #[doc(inline)] -pub use crate::ops::{ - Bound, IntoBounds, OneSidedRange, RangeBounds, RangeFull, RangeTo, RangeToInclusive, -}; +pub use crate::ops::{Bound, IntoBounds, OneSidedRange, RangeBounds, RangeFull, RangeTo}; /// A (half-open) range bounded inclusively below and exclusively above /// (`start..end` in a future edition). @@ -209,20 +207,20 @@ impl const From> for Range { } } -/// A range bounded inclusively below and above (`start..=end`). +/// A range bounded inclusively below and above (`start..=last`). /// -/// The `RangeInclusive` `start..=end` contains all values with `x >= start` -/// and `x <= end`. It is empty unless `start <= end`. +/// The `RangeInclusive` `start..=last` contains all values with `x >= start` +/// and `x <= last`. It is empty unless `start <= last`. /// /// # Examples /// -/// The `start..=end` syntax is a `RangeInclusive`: +/// The `start..=last` syntax is a `RangeInclusive`: /// /// ``` /// #![feature(new_range_api)] /// use core::range::RangeInclusive; /// -/// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, end: 5 }); +/// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, last: 5 }); /// assert_eq!(3 + 4 + 5, RangeInclusive::from(3..=5).into_iter().sum()); /// ``` #[lang = "RangeInclusiveCopy"] @@ -234,7 +232,7 @@ pub struct RangeInclusive { pub start: Idx, /// The upper bound of the range (inclusive). #[unstable(feature = "new_range_api", issue = "125687")] - pub end: Idx, + pub last: Idx, } #[unstable(feature = "new_range_api", issue = "125687")] @@ -242,7 +240,7 @@ impl fmt::Debug for RangeInclusive { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { self.start.fmt(fmt)?; write!(fmt, "..=")?; - self.end.fmt(fmt)?; + self.last.fmt(fmt)?; Ok(()) } } @@ -306,7 +304,7 @@ impl> RangeInclusive { #[unstable(feature = "new_range_api", issue = "125687")] #[inline] pub fn is_empty(&self) -> bool { - !(self.start <= self.end) + !(self.start <= self.last) } } @@ -335,10 +333,10 @@ impl RangeInclusive { impl RangeInclusive { /// Converts to an exclusive `Range` for `SliceIndex` implementations. - /// The caller is responsible for dealing with `end == usize::MAX`. + /// The caller is responsible for dealing with `last == usize::MAX`. #[inline] pub(crate) const fn into_slice_range(self) -> Range { - Range { start: self.start, end: self.end + 1 } + Range { start: self.start, end: self.last + 1 } } } @@ -348,7 +346,7 @@ impl RangeBounds for RangeInclusive { Included(&self.start) } fn end_bound(&self) -> Bound<&T> { - Included(&self.end) + Included(&self.last) } } @@ -364,7 +362,7 @@ impl RangeBounds for RangeInclusive<&T> { Included(self.start) } fn end_bound(&self) -> Bound<&T> { - Included(self.end) + Included(self.last) } } @@ -372,7 +370,7 @@ impl RangeBounds for RangeInclusive<&T> { #[unstable(feature = "new_range_api", issue = "125687")] impl IntoBounds for RangeInclusive { fn into_bounds(self) -> (Bound, Bound) { - (Included(self.start), Included(self.end)) + (Included(self.start), Included(self.last)) } } @@ -381,7 +379,7 @@ impl IntoBounds for RangeInclusive { impl const From> for legacy::RangeInclusive { #[inline] fn from(value: RangeInclusive) -> Self { - Self::new(value.start, value.end) + Self::new(value.start, value.last) } } #[unstable(feature = "new_range_api", issue = "125687")] @@ -394,8 +392,8 @@ impl const From> for RangeInclusive { "attempted to convert from an exhausted `legacy::RangeInclusive` (unspecified behavior)" ); - let (start, end) = value.into_inner(); - RangeInclusive { start, end } + let (start, last) = value.into_inner(); + RangeInclusive { start, last } } } @@ -544,3 +542,107 @@ impl const From> for RangeFrom { Self { start: value.start } } } + +/// A range only bounded inclusively above (`..=last`). +/// +/// The `RangeToInclusive` `..=last` contains all values with `x <= last`. +/// It cannot serve as an [`Iterator`] because it doesn't have a starting point. +/// +/// # Examples +/// +/// The `..=last` syntax is a `RangeToInclusive`: +/// +/// ``` +/// #![feature(new_range_api)] +/// #![feature(new_range)] +/// assert_eq!((..=5), std::range::RangeToInclusive{ last: 5 }); +/// ``` +/// +/// It does not have an [`IntoIterator`] implementation, so you can't use it in a +/// `for` loop directly. This won't compile: +/// +/// ```compile_fail,E0277 +/// // error[E0277]: the trait bound `std::range::RangeToInclusive<{integer}>: +/// // std::iter::Iterator` is not satisfied +/// for i in ..=5 { +/// // ... +/// } +/// ``` +/// +/// When used as a [slicing index], `RangeToInclusive` produces a slice of all +/// array elements up to and including the index indicated by `last`. +/// +/// ``` +/// let arr = [0, 1, 2, 3, 4]; +/// assert_eq!(arr[ .. ], [0, 1, 2, 3, 4]); +/// assert_eq!(arr[ .. 3], [0, 1, 2 ]); +/// assert_eq!(arr[ ..=3], [0, 1, 2, 3 ]); // This is a `RangeToInclusive` +/// assert_eq!(arr[1.. ], [ 1, 2, 3, 4]); +/// assert_eq!(arr[1.. 3], [ 1, 2 ]); +/// assert_eq!(arr[1..=3], [ 1, 2, 3 ]); +/// ``` +/// +/// [slicing index]: crate::slice::SliceIndex +#[lang = "RangeToInclusiveCopy"] +#[doc(alias = "..=")] +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[unstable(feature = "new_range_api", issue = "125687")] +pub struct RangeToInclusive { + /// The upper bound of the range (inclusive) + #[unstable(feature = "new_range_api", issue = "125687")] + pub last: Idx, +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl fmt::Debug for RangeToInclusive { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(fmt, "..=")?; + self.last.fmt(fmt)?; + Ok(()) + } +} + +impl> RangeToInclusive { + /// Returns `true` if `item` is contained in the range. + /// + /// # Examples + /// + /// ``` + /// assert!( (..=5).contains(&-1_000_000_000)); + /// assert!( (..=5).contains(&5)); + /// assert!(!(..=5).contains(&6)); + /// + /// assert!( (..=1.0).contains(&1.0)); + /// assert!(!(..=1.0).contains(&f32::NAN)); + /// assert!(!(..=f32::NAN).contains(&0.5)); + /// ``` + #[inline] + #[unstable(feature = "new_range_api", issue = "125687")] + pub fn contains(&self, item: &U) -> bool + where + Idx: PartialOrd, + U: ?Sized + PartialOrd, + { + >::contains(self, item) + } +} + +// RangeToInclusive cannot impl From> +// because underflow would be possible with (..0).into() + +#[unstable(feature = "new_range_api", issue = "125687")] +impl RangeBounds for RangeToInclusive { + fn start_bound(&self) -> Bound<&T> { + Unbounded + } + fn end_bound(&self) -> Bound<&T> { + Included(&self.last) + } +} + +#[unstable(feature = "range_into_bounds", issue = "136903")] +impl IntoBounds for RangeToInclusive { + fn into_bounds(self) -> (Bound, Bound) { + (Unbounded, Included(self.last)) + } +} diff --git a/library/core/src/range/iter.rs b/library/core/src/range/iter.rs index 1e261d8c1d93a..24efd4a204a5f 100644 --- a/library/core/src/range/iter.rs +++ b/library/core/src/range/iter.rs @@ -164,7 +164,7 @@ impl IterRangeInclusive { return None; } - Some(RangeInclusive { start: self.0.start, end: self.0.end }) + Some(RangeInclusive { start: self.0.start, last: self.0.end }) } } diff --git a/library/core/src/range/legacy.rs b/library/core/src/range/legacy.rs index 6723c4903f756..aa11331382dd0 100644 --- a/library/core/src/range/legacy.rs +++ b/library/core/src/range/legacy.rs @@ -1,10 +1,10 @@ //! # Legacy range types //! //! The types within this module will be replaced by the types -//! [`Range`], [`RangeInclusive`], and [`RangeFrom`] in the parent +//! [`Range`], [`RangeInclusive`], [`RangeToInclusive`], and [`RangeFrom`] in the parent //! module, [`core::range`]. //! //! The types here are equivalent to those in [`core::ops`]. #[doc(inline)] -pub use crate::ops::{Range, RangeFrom, RangeInclusive}; +pub use crate::ops::{Range, RangeFrom, RangeInclusive, RangeToInclusive}; diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 8e1bc0bae70a4..a8147d745f3ab 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -129,6 +129,8 @@ mod private_slice_index { #[unstable(feature = "new_range_api", issue = "125687")] impl Sealed for range::RangeInclusive {} #[unstable(feature = "new_range_api", issue = "125687")] + impl Sealed for range::RangeToInclusive {} + #[unstable(feature = "new_range_api", issue = "125687")] impl Sealed for range::RangeFrom {} impl Sealed for ops::IndexRange {} @@ -788,6 +790,45 @@ unsafe impl const SliceIndex<[T]> for ops::RangeToInclusive { } } +/// The methods `index` and `index_mut` panic if the end of the range is out of bounds. +#[stable(feature = "inclusive_range", since = "1.26.0")] +#[rustc_const_unstable(feature = "const_index", issue = "143775")] +unsafe impl const SliceIndex<[T]> for range::RangeToInclusive { + type Output = [T]; + + #[inline] + fn get(self, slice: &[T]) -> Option<&[T]> { + (0..=self.last).get(slice) + } + + #[inline] + fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { + (0..=self.last).get_mut(slice) + } + + #[inline] + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { + // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. + unsafe { (0..=self.last).get_unchecked(slice) } + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { + // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. + unsafe { (0..=self.last).get_unchecked_mut(slice) } + } + + #[inline] + fn index(self, slice: &[T]) -> &[T] { + (0..=self.last).index(slice) + } + + #[inline] + fn index_mut(self, slice: &mut [T]) -> &mut [T] { + (0..=self.last).index_mut(slice) + } +} + /// Performs bounds checking of a range. /// /// This method is similar to [`Index::index`] for slices, but it returns a diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index 4f228edf78e46..5adae62b7e65d 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -677,11 +677,11 @@ unsafe impl const SliceIndex for range::RangeInclusive { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { - if self.end == usize::MAX { None } else { self.into_slice_range().get(slice) } + if self.last == usize::MAX { None } else { self.into_slice_range().get(slice) } } #[inline] fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { - if self.end == usize::MAX { None } else { self.into_slice_range().get_mut(slice) } + if self.last == usize::MAX { None } else { self.into_slice_range().get_mut(slice) } } #[inline] unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { @@ -695,14 +695,14 @@ unsafe impl const SliceIndex for range::RangeInclusive { } #[inline] fn index(self, slice: &str) -> &Self::Output { - if self.end == usize::MAX { + if self.last == usize::MAX { str_index_overflow_fail(); } self.into_slice_range().index(slice) } #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { - if self.end == usize::MAX { + if self.last == usize::MAX { str_index_overflow_fail(); } self.into_slice_range().index_mut(slice) diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh index 7e0fb5794f47c..b7d7151b171d5 100755 --- a/src/ci/docker/scripts/rfl-build.sh +++ b/src/ci/docker/scripts/rfl-build.sh @@ -2,9 +2,7 @@ set -euo pipefail -# https://github.com/rust-lang/rust/pull/144443 -# https://github.com/rust-lang/rust/pull/145928 -LINUX_VERSION=8851e27d2cb947ea8bbbe8e812068f7bf5cbd00b +LINUX_VERSION=v6.17-rc5 # Build rustc, rustdoc, cargo, clippy-driver and rustfmt ../x.py build --stage 2 library rustdoc clippy rustfmt diff --git a/src/tools/clippy/clippy_utils/src/sym.rs b/src/tools/clippy/clippy_utils/src/sym.rs index 278101ac27f96..8033b74a8d25c 100644 --- a/src/tools/clippy/clippy_utils/src/sym.rs +++ b/src/tools/clippy/clippy_utils/src/sym.rs @@ -194,7 +194,6 @@ generate! { itertools, join, kw, - last, lazy_static, lint_vec, ln, diff --git a/src/tools/miri/tests/pass/static_align.rs b/src/tools/miri/tests/pass/static_align.rs new file mode 100644 index 0000000000000..f292f028568b6 --- /dev/null +++ b/src/tools/miri/tests/pass/static_align.rs @@ -0,0 +1,14 @@ +#![feature(static_align)] + +// When a static uses `align(N)`, its address should be a multiple of `N`. + +#[rustc_align_static(256)] +static FOO: u64 = 0; + +#[rustc_align_static(512)] +static BAR: u64 = 0; + +fn main() { + assert!(core::ptr::from_ref(&FOO).addr().is_multiple_of(256)); + assert!(core::ptr::from_ref(&BAR).addr().is_multiple_of(512)); +} diff --git a/src/tools/wasm-component-ld/Cargo.toml b/src/tools/wasm-component-ld/Cargo.toml index 23dc86998e88f..3def2391a13f6 100644 --- a/src/tools/wasm-component-ld/Cargo.toml +++ b/src/tools/wasm-component-ld/Cargo.toml @@ -10,4 +10,4 @@ name = "wasm-component-ld" path = "src/main.rs" [dependencies] -wasm-component-ld = "0.5.16" +wasm-component-ld = "0.5.17" diff --git a/tests/codegen-llvm/align-static.rs b/tests/codegen-llvm/align-static.rs new file mode 100644 index 0000000000000..53db998919af3 --- /dev/null +++ b/tests/codegen-llvm/align-static.rs @@ -0,0 +1,31 @@ +//@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 + +#![crate_type = "lib"] +#![feature(static_align)] + +// CHECK: @STATIC_ALIGN = +// CHECK-SAME: align 16 +#[no_mangle] +#[rustc_align_static(16)] +pub static STATIC_ALIGN: u64 = 0; + +// CHECK: @ALIGN_SPECIFIED_TWICE_1 = +// CHECK-SAME: align 64 +#[no_mangle] +#[rustc_align_static(32)] +#[rustc_align_static(64)] +pub static ALIGN_SPECIFIED_TWICE_1: u64 = 0; + +// CHECK: @ALIGN_SPECIFIED_TWICE_2 = +// CHECK-SAME: align 128 +#[no_mangle] +#[rustc_align_static(128)] +#[rustc_align_static(32)] +pub static ALIGN_SPECIFIED_TWICE_2: u64 = 0; + +// CHECK: @ALIGN_SPECIFIED_TWICE_3 = +// CHECK-SAME: align 256 +#[no_mangle] +#[rustc_align_static(32)] +#[rustc_align_static(256)] +pub static ALIGN_SPECIFIED_TWICE_3: u64 = 0; diff --git a/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-abort.mir b/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-abort.mir index 7be3ab8cbae92..8e47aabb9b9f3 100644 --- a/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-abort.mir +++ b/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-abort.mir @@ -1,4 +1,4 @@ -// MIR for `drop_in_place` after SimplifyCfg-make_shim +// MIR for `std::ptr::drop_in_place` after SimplifyCfg-make_shim fn drop_in_place(_1: *mut Test) -> () { let mut _0: (); diff --git a/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-unwind.mir b/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-unwind.mir index 6c3c1aaa2bd2b..2457405d9969a 100644 --- a/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-unwind.mir +++ b/tests/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.panic-unwind.mir @@ -1,4 +1,4 @@ -// MIR for `drop_in_place` after SimplifyCfg-make_shim +// MIR for `std::ptr::drop_in_place` after SimplifyCfg-make_shim fn drop_in_place(_1: *mut Test) -> () { let mut _0: (); diff --git a/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String;42].AddMovesForPackedDrops.before.mir b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String;42].AddMovesForPackedDrops.before.mir index 9d5af8e84e4f1..ed3f4788cea7d 100644 --- a/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String;42].AddMovesForPackedDrops.before.mir +++ b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String;42].AddMovesForPackedDrops.before.mir @@ -1,4 +1,4 @@ -// MIR for `drop_in_place` before AddMovesForPackedDrops +// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops fn drop_in_place(_1: *mut [String; 42]) -> () { let mut _0: (); diff --git a/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir index 144880d15989c..bee671af6dfea 100644 --- a/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir +++ b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir @@ -1,4 +1,4 @@ -// MIR for `drop_in_place` before AddMovesForPackedDrops +// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops fn drop_in_place(_1: *mut [String]) -> () { let mut _0: (); diff --git a/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir b/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir index 51ef9f7c068ec..1bdb1c1debdbb 100644 --- a/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir +++ b/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir @@ -1,4 +1,4 @@ -// MIR for `drop_in_place` before AddMovesForPackedDrops +// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops fn drop_in_place(_1: *mut Vec) -> () { let mut _0: (); diff --git a/tests/ui/attributes/malformed-static-align.rs b/tests/ui/attributes/malformed-static-align.rs new file mode 100644 index 0000000000000..305d8acf8af24 --- /dev/null +++ b/tests/ui/attributes/malformed-static-align.rs @@ -0,0 +1,17 @@ +#![feature(static_align)] +#![crate_type = "lib"] + +#[rustc_align_static = 16] //~ ERROR malformed `rustc_align_static` attribute input +static S1: () = (); + +#[rustc_align_static("hello")] //~ ERROR invalid alignment value: not an unsuffixed integer +static S2: () = (); + +#[rustc_align_static(0)] //~ ERROR invalid alignment value: not a power of two +static S3: () = (); + +#[repr(align(16))] //~ ERROR `#[repr(align(...))]` is not supported on static +static S4: () = (); + +#[rustc_align_static(16)] //~ ERROR `#[rustc_align_static]` attribute cannot be used on structs +struct Struct1; diff --git a/tests/ui/attributes/malformed-static-align.stderr b/tests/ui/attributes/malformed-static-align.stderr new file mode 100644 index 0000000000000..35f654d3990f2 --- /dev/null +++ b/tests/ui/attributes/malformed-static-align.stderr @@ -0,0 +1,45 @@ +error[E0539]: malformed `rustc_align_static` attribute input + --> $DIR/malformed-static-align.rs:4:1 + | +LL | #[rustc_align_static = 16] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[rustc_align_static()]` + +error[E0589]: invalid alignment value: not an unsuffixed integer + --> $DIR/malformed-static-align.rs:7:22 + | +LL | #[rustc_align_static("hello")] + | ^^^^^^^ + +error[E0589]: invalid alignment value: not a power of two + --> $DIR/malformed-static-align.rs:10:22 + | +LL | #[rustc_align_static(0)] + | ^ + +error: `#[rustc_align_static]` attribute cannot be used on structs + --> $DIR/malformed-static-align.rs:16:1 + | +LL | #[rustc_align_static(16)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_align_static]` can be applied to statics and foreign statics + +error: `#[repr(align(...))]` is not supported on statics + --> $DIR/malformed-static-align.rs:13:8 + | +LL | #[repr(align(16))] + | ^^^^^^^^^ + | +help: use `#[rustc_align_static(...)]` instead + --> $DIR/malformed-static-align.rs:13:8 + | +LL | #[repr(align(16))] + | ^^^^^^^^^ + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0539, E0589. +For more information about an error, try `rustc --explain E0539`. diff --git a/tests/ui/const-generics/std/const-generics-range.full.stderr b/tests/ui/const-generics/std/const-generics-range.full.stderr index 2b5c63e6643d8..ccede2af9e553 100644 --- a/tests/ui/const-generics/std/const-generics-range.full.stderr +++ b/tests/ui/const-generics/std/const-generics-range.full.stderr @@ -28,7 +28,7 @@ error[E0741]: `RangeTo` must implement `ConstParamTy` to be used as the t LL | struct _RangeTo>; | ^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0741]: `RangeToInclusive` must implement `ConstParamTy` to be used as the type of a const generic parameter +error[E0741]: `std::ops::RangeToInclusive` must implement `ConstParamTy` to be used as the type of a const generic parameter --> $DIR/const-generics-range.rs:34:35 | LL | struct _RangeToInclusive>; diff --git a/tests/ui/const-generics/std/const-generics-range.min.stderr b/tests/ui/const-generics/std/const-generics-range.min.stderr index 04e3fe744534f..43a57c880d5d8 100644 --- a/tests/ui/const-generics/std/const-generics-range.min.stderr +++ b/tests/ui/const-generics/std/const-generics-range.min.stderr @@ -58,7 +58,7 @@ help: add `#![feature(adt_const_params)]` to the crate attributes to enable more LL + #![feature(adt_const_params)] | -error: `RangeToInclusive` is forbidden as the type of a const generic parameter +error: `std::ops::RangeToInclusive` is forbidden as the type of a const generic parameter --> $DIR/const-generics-range.rs:34:35 | LL | struct _RangeToInclusive>; diff --git a/tests/ui/const-generics/std/const-generics-range.rs b/tests/ui/const-generics/std/const-generics-range.rs index 3a238ed177e0f..391366dadba0a 100644 --- a/tests/ui/const-generics/std/const-generics-range.rs +++ b/tests/ui/const-generics/std/const-generics-range.rs @@ -7,32 +7,32 @@ // `Range` should be usable within const generics: struct _Range>; //[min]~^ ERROR `std::ops::Range` is forbidden -const RANGE : _Range<{ 0 .. 1000 }> = _Range; +const RANGE: _Range<{ 0..1000 }> = _Range; // `RangeFrom` should be usable within const generics: struct _RangeFrom>; //[min]~^ ERROR `std::ops::RangeFrom` is forbidden -const RANGE_FROM : _RangeFrom<{ 0 .. }> = _RangeFrom; +const RANGE_FROM: _RangeFrom<{ 0.. }> = _RangeFrom; // `RangeFull` should be usable within const generics: struct _RangeFull; //[min]~^ ERROR `RangeFull` is forbidden -const RANGE_FULL : _RangeFull<{ .. }> = _RangeFull; +const RANGE_FULL: _RangeFull<{ .. }> = _RangeFull; // Regression test for #70155 // `RangeInclusive` should be usable within const generics: struct _RangeInclusive>; //[min]~^ ERROR `std::ops::RangeInclusive` is forbidden -const RANGE_INCLUSIVE : _RangeInclusive<{ 0 ..= 999 }> = _RangeInclusive; +const RANGE_INCLUSIVE: _RangeInclusive<{ 0..=999 }> = _RangeInclusive; // `RangeTo` should be usable within const generics: struct _RangeTo>; //[min]~^ ERROR `RangeTo` is forbidden -const RANGE_TO : _RangeTo<{ .. 1000 }> = _RangeTo; +const RANGE_TO: _RangeTo<{ ..1000 }> = _RangeTo; // `RangeToInclusive` should be usable within const generics: struct _RangeToInclusive>; -//[min]~^ ERROR `RangeToInclusive` is forbidden -const RANGE_TO_INCLUSIVE : _RangeToInclusive<{ ..= 999 }> = _RangeToInclusive; +//[min]~^ ERROR `std::ops::RangeToInclusive` is forbidden +const RANGE_TO_INCLUSIVE: _RangeToInclusive<{ ..=999 }> = _RangeToInclusive; pub fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-static_align.rs b/tests/ui/feature-gates/feature-gate-static_align.rs new file mode 100644 index 0000000000000..4d8f0e18d94cb --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-static_align.rs @@ -0,0 +1,11 @@ +#![crate_type = "lib"] + +#[rustc_align_static(16)] +//~^ ERROR the `#[rustc_align_static]` attribute is an experimental feature +static REQUIRES_ALIGNMENT: u64 = 0; + +extern "C" { + #[rustc_align_static(16)] + //~^ ERROR the `#[rustc_align_static]` attribute is an experimental feature + static FOREIGN_STATIC: u32; +} diff --git a/tests/ui/feature-gates/feature-gate-static_align.stderr b/tests/ui/feature-gates/feature-gate-static_align.stderr new file mode 100644 index 0000000000000..b45fcdefc9cdf --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-static_align.stderr @@ -0,0 +1,23 @@ +error[E0658]: the `#[rustc_align_static]` attribute is an experimental feature + --> $DIR/feature-gate-static_align.rs:3:1 + | +LL | #[rustc_align_static(16)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #146177 for more information + = help: add `#![feature(static_align)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: the `#[rustc_align_static]` attribute is an experimental feature + --> $DIR/feature-gate-static_align.rs:8:5 + | +LL | #[rustc_align_static(16)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #146177 for more information + = help: add `#![feature(static_align)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/iterators/ranges.stderr b/tests/ui/iterators/ranges.stderr index b9fbcd5304b1f..f85ce644073ef 100644 --- a/tests/ui/iterators/ranges.stderr +++ b/tests/ui/iterators/ranges.stderr @@ -8,15 +8,15 @@ LL | for _ in ..10 {} = note: `..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a bounded `Range`: `0..end` = note: required for `RangeTo<{integer}>` to implement `IntoIterator` -error[E0277]: `RangeToInclusive<{integer}>` is not an iterator +error[E0277]: `std::ops::RangeToInclusive<{integer}>` is not an iterator --> $DIR/ranges.rs:4:14 | LL | for _ in ..=10 {} | ^^^^^ if you meant to iterate until a value (including it), add a starting value | - = help: the trait `Iterator` is not implemented for `RangeToInclusive<{integer}>` + = help: the trait `Iterator` is not implemented for `std::ops::RangeToInclusive<{integer}>` = note: `..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant to have a bounded `RangeInclusive`: `0..=end` - = note: required for `RangeToInclusive<{integer}>` to implement `IntoIterator` + = note: required for `std::ops::RangeToInclusive<{integer}>` to implement `IntoIterator` error: aborting due to 2 previous errors diff --git a/tests/ui/new-range/disabled.rs b/tests/ui/new-range/disabled.rs index 1a5fe3f974360..6ba29f5ca9a25 100644 --- a/tests/ui/new-range/disabled.rs +++ b/tests/ui/new-range/disabled.rs @@ -6,20 +6,20 @@ fn main() { // Unchanged let a: core::range::RangeFull = ..; let b: core::range::RangeTo = ..2; - let c: core::range::RangeToInclusive = ..=3; let _: core::ops::RangeFull = a; let _: core::ops::RangeTo = b; - let _: core::ops::RangeToInclusive = c; // Changed let a: core::range::legacy::RangeFrom = 1..; let b: core::range::legacy::Range = 2..3; let c: core::range::legacy::RangeInclusive = 4..=5; + let d: core::range::legacy::RangeToInclusive = ..=3; let a: core::ops::RangeFrom = a; let b: core::ops::Range = b; let c: core::ops::RangeInclusive = c; + let d: core::ops::RangeToInclusive = d; let _: core::ops::RangeFrom = a.into_iter(); let _: core::ops::Range = b.into_iter(); diff --git a/tests/ui/new-range/enabled.rs b/tests/ui/new-range/enabled.rs index a5fb76ad52b72..5ddbba492e763 100644 --- a/tests/ui/new-range/enabled.rs +++ b/tests/ui/new-range/enabled.rs @@ -7,18 +7,18 @@ fn main() { // Unchanged let a: core::range::RangeFull = ..; let b: core::range::RangeTo = ..2; - let c: core::range::RangeToInclusive = ..=3; let _: core::ops::RangeFull = a; let _: core::ops::RangeTo = b; - let _: core::ops::RangeToInclusive = c; // Changed let a: core::range::RangeFrom = 1..; let b: core::range::Range = 2..3; let c: core::range::RangeInclusive = 4..=5; + let d: core::range::RangeToInclusive = ..=3; let _: core::range::IterRangeFrom = a.into_iter(); let _: core::range::IterRange = b.into_iter(); let _: core::range::IterRangeInclusive = c.into_iter(); + // RangeToInclusive has no Iterator implementation } diff --git a/tests/ui/range/issue-54505-no-literals.stderr b/tests/ui/range/issue-54505-no-literals.stderr index c6d4384bcd33c..62e2fe4a83896 100644 --- a/tests/ui/range/issue-54505-no-literals.stderr +++ b/tests/ui/range/issue-54505-no-literals.stderr @@ -207,7 +207,7 @@ LL | take_range(std::ops::RangeToInclusive { end: 5 }); | arguments to this function are incorrect | = note: expected reference `&_` - found struct `RangeToInclusive<{integer}>` + found struct `std::ops::RangeToInclusive<{integer}>` note: function defined here --> $DIR/issue-54505-no-literals.rs:12:4 | @@ -227,7 +227,7 @@ LL | take_range(::std::ops::RangeToInclusive { end: 5 }); | arguments to this function are incorrect | = note: expected reference `&_` - found struct `RangeToInclusive<{integer}>` + found struct `std::ops::RangeToInclusive<{integer}>` note: function defined here --> $DIR/issue-54505-no-literals.rs:12:4 | diff --git a/tests/ui/range/issue-54505-no-std.stderr b/tests/ui/range/issue-54505-no-std.stderr index 2aa1d584046dd..866a82afb7e2f 100644 --- a/tests/ui/range/issue-54505-no-std.stderr +++ b/tests/ui/range/issue-54505-no-std.stderr @@ -112,7 +112,7 @@ LL | take_range(..=42); | arguments to this function are incorrect | = note: expected reference `&_` - found struct `RangeToInclusive<{integer}>` + found struct `core::ops::RangeToInclusive<{integer}>` note: function defined here --> $DIR/issue-54505-no-std.rs:25:4 | diff --git a/tests/ui/range/issue-54505.stderr b/tests/ui/range/issue-54505.stderr index 8b669b2910f6b..4d94c6c2d0942 100644 --- a/tests/ui/range/issue-54505.stderr +++ b/tests/ui/range/issue-54505.stderr @@ -112,7 +112,7 @@ LL | take_range(..=42); | arguments to this function are incorrect | = note: expected reference `&_` - found struct `RangeToInclusive<{integer}>` + found struct `std::ops::RangeToInclusive<{integer}>` note: function defined here --> $DIR/issue-54505.rs:10:4 | diff --git a/tests/ui/static/static-align.rs b/tests/ui/static/static-align.rs new file mode 100644 index 0000000000000..93241db09f949 --- /dev/null +++ b/tests/ui/static/static-align.rs @@ -0,0 +1,26 @@ +//@ run-pass +#![feature(static_align)] + +#[rustc_align_static(64)] +static A: u8 = 0; + +#[rustc_align_static(64)] +static B: u8 = 0; + +#[rustc_align_static(128)] +#[no_mangle] +static EXPORTED: u64 = 0; + +unsafe extern "C" { + #[rustc_align_static(128)] + #[link_name = "EXPORTED"] + static C: u64; +} + +fn main() { + assert!(core::ptr::from_ref(&A).addr().is_multiple_of(64)); + assert!(core::ptr::from_ref(&B).addr().is_multiple_of(64)); + + assert!(core::ptr::from_ref(&EXPORTED).addr().is_multiple_of(128)); + unsafe { assert!(core::ptr::from_ref(&C).addr().is_multiple_of(128)) }; +}