Auto merge of #146409 - matthiaskrgr:rollup-thju381, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - rust-lang/rust#144765 (inclusive `Range`s: change `end` to `last`) - rust-lang/rust#146178 (Implement `#[rustc_align_static(N)]` on `static`s) - rust-lang/rust#146368 (CI: rfl: move job forward to Linux v6.17-rc5 to remove temporary commits) - rust-lang/rust#146378 (Update wasm-component-ld to 0.5.17) - rust-lang/rust#146391 (Trim paths less in MIR dumping) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
565a9ca63e
49 changed files with 530 additions and 97 deletions
50
Cargo.lock
50
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]]
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -218,6 +218,7 @@ impl<S: Stage> AttributeParser<S> 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
|
||||
|
|
|
|||
|
|
@ -331,3 +331,30 @@ impl<S: Stage> AttributeParser<S> 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<S: Stage> AttributeParser<S> for AlignStaticParser {
|
||||
const ATTRIBUTES: AcceptMapping<Self, S> = &[(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<AttributeKind> {
|
||||
let (align, span) = self.0.0?;
|
||||
Some(AttributeKind::Align { align, span })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
..
|
||||
)
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -130,7 +130,22 @@ impl<I: Idx, T> IntoSliceIdx<I, [T]> for core::range::RangeFrom<I> {
|
|||
impl<I: Idx, T> IntoSliceIdx<I, [T]> for core::range::RangeInclusive<I> {
|
||||
type Output = core::range::RangeInclusive<usize>;
|
||||
#[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<I: Idx, T> IntoSliceIdx<I, [T]> for core::range::RangeToInclusive<I> {
|
||||
type Output = core::range::RangeToInclusive<usize>;
|
||||
#[inline]
|
||||
fn into_slice_idx(self) -> Self::Output {
|
||||
core::range::RangeToInclusive { last: self.last.index() }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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<Self> {
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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<T> const From<legacy::Range<T>> for Range<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// 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<Idx> {
|
|||
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<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
|
|||
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<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
|
|||
#[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<Idx: Step> RangeInclusive<Idx> {
|
|||
|
||||
impl RangeInclusive<usize> {
|
||||
/// 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<usize> {
|
||||
Range { start: self.start, end: self.end + 1 }
|
||||
Range { start: self.start, end: self.last + 1 }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -348,7 +346,7 @@ impl<T> RangeBounds<T> for RangeInclusive<T> {
|
|||
Included(&self.start)
|
||||
}
|
||||
fn end_bound(&self) -> Bound<&T> {
|
||||
Included(&self.end)
|
||||
Included(&self.last)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -364,7 +362,7 @@ impl<T> RangeBounds<T> for RangeInclusive<&T> {
|
|||
Included(self.start)
|
||||
}
|
||||
fn end_bound(&self) -> Bound<&T> {
|
||||
Included(self.end)
|
||||
Included(self.last)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -372,7 +370,7 @@ impl<T> RangeBounds<T> for RangeInclusive<&T> {
|
|||
#[unstable(feature = "new_range_api", issue = "125687")]
|
||||
impl<T> IntoBounds<T> for RangeInclusive<T> {
|
||||
fn into_bounds(self) -> (Bound<T>, Bound<T>) {
|
||||
(Included(self.start), Included(self.end))
|
||||
(Included(self.start), Included(self.last))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -381,7 +379,7 @@ impl<T> IntoBounds<T> for RangeInclusive<T> {
|
|||
impl<T> const From<RangeInclusive<T>> for legacy::RangeInclusive<T> {
|
||||
#[inline]
|
||||
fn from(value: RangeInclusive<T>) -> 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<T> const From<legacy::RangeInclusive<T>> for RangeInclusive<T> {
|
|||
"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<T> const From<legacy::RangeFrom<T>> for RangeFrom<T> {
|
|||
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<Idx> {
|
||||
/// 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<Idx: fmt::Debug> fmt::Debug for RangeToInclusive<Idx> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(fmt, "..=")?;
|
||||
self.last.fmt(fmt)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
|
||||
/// 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<U>(&self, item: &U) -> bool
|
||||
where
|
||||
Idx: PartialOrd<U>,
|
||||
U: ?Sized + PartialOrd<Idx>,
|
||||
{
|
||||
<Self as RangeBounds<Idx>>::contains(self, item)
|
||||
}
|
||||
}
|
||||
|
||||
// RangeToInclusive<Idx> cannot impl From<RangeTo<Idx>>
|
||||
// because underflow would be possible with (..0).into()
|
||||
|
||||
#[unstable(feature = "new_range_api", issue = "125687")]
|
||||
impl<T> RangeBounds<T> for RangeToInclusive<T> {
|
||||
fn start_bound(&self) -> Bound<&T> {
|
||||
Unbounded
|
||||
}
|
||||
fn end_bound(&self) -> Bound<&T> {
|
||||
Included(&self.last)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "range_into_bounds", issue = "136903")]
|
||||
impl<T> IntoBounds<T> for RangeToInclusive<T> {
|
||||
fn into_bounds(self) -> (Bound<T>, Bound<T>) {
|
||||
(Unbounded, Included(self.last))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ impl<A: Step> IterRangeInclusive<A> {
|
|||
return None;
|
||||
}
|
||||
|
||||
Some(RangeInclusive { start: self.0.start, end: self.0.end })
|
||||
Some(RangeInclusive { start: self.0.start, last: self.0.end })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -129,6 +129,8 @@ mod private_slice_index {
|
|||
#[unstable(feature = "new_range_api", issue = "125687")]
|
||||
impl Sealed for range::RangeInclusive<usize> {}
|
||||
#[unstable(feature = "new_range_api", issue = "125687")]
|
||||
impl Sealed for range::RangeToInclusive<usize> {}
|
||||
#[unstable(feature = "new_range_api", issue = "125687")]
|
||||
impl Sealed for range::RangeFrom<usize> {}
|
||||
|
||||
impl Sealed for ops::IndexRange {}
|
||||
|
|
@ -788,6 +790,45 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeToInclusive<usize> {
|
|||
}
|
||||
}
|
||||
|
||||
/// 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<T> const SliceIndex<[T]> for range::RangeToInclusive<usize> {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -677,11 +677,11 @@ unsafe impl const SliceIndex<str> for range::RangeInclusive<usize> {
|
|||
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<str> for range::RangeInclusive<usize> {
|
|||
}
|
||||
#[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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -194,7 +194,6 @@ generate! {
|
|||
itertools,
|
||||
join,
|
||||
kw,
|
||||
last,
|
||||
lazy_static,
|
||||
lint_vec,
|
||||
ln,
|
||||
|
|
|
|||
14
src/tools/miri/tests/pass/static_align.rs
Normal file
14
src/tools/miri/tests/pass/static_align.rs
Normal file
|
|
@ -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));
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
31
tests/codegen-llvm/align-static.rs
Normal file
31
tests/codegen-llvm/align-static.rs
Normal file
|
|
@ -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;
|
||||
|
|
@ -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: ();
|
||||
|
|
|
|||
|
|
@ -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: ();
|
||||
|
|
|
|||
|
|
@ -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: ();
|
||||
|
|
|
|||
|
|
@ -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: ();
|
||||
|
|
|
|||
|
|
@ -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<i32>) -> () {
|
||||
let mut _0: ();
|
||||
|
|
|
|||
17
tests/ui/attributes/malformed-static-align.rs
Normal file
17
tests/ui/attributes/malformed-static-align.rs
Normal file
|
|
@ -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;
|
||||
45
tests/ui/attributes/malformed-static-align.stderr
Normal file
45
tests/ui/attributes/malformed-static-align.stderr
Normal file
|
|
@ -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(<alignment in bytes>)]`
|
||||
|
||||
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`.
|
||||
|
|
@ -28,7 +28,7 @@ error[E0741]: `RangeTo<usize>` must implement `ConstParamTy` to be used as the t
|
|||
LL | struct _RangeTo<const R: std::ops::RangeTo<usize>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0741]: `RangeToInclusive<usize>` must implement `ConstParamTy` to be used as the type of a const generic parameter
|
||||
error[E0741]: `std::ops::RangeToInclusive<usize>` must implement `ConstParamTy` to be used as the type of a const generic parameter
|
||||
--> $DIR/const-generics-range.rs:34:35
|
||||
|
|
||||
LL | struct _RangeToInclusive<const R: std::ops::RangeToInclusive<usize>>;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ help: add `#![feature(adt_const_params)]` to the crate attributes to enable more
|
|||
LL + #![feature(adt_const_params)]
|
||||
|
|
||||
|
||||
error: `RangeToInclusive<usize>` is forbidden as the type of a const generic parameter
|
||||
error: `std::ops::RangeToInclusive<usize>` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/const-generics-range.rs:34:35
|
||||
|
|
||||
LL | struct _RangeToInclusive<const R: std::ops::RangeToInclusive<usize>>;
|
||||
|
|
|
|||
|
|
@ -7,32 +7,32 @@
|
|||
// `Range` should be usable within const generics:
|
||||
struct _Range<const R: std::ops::Range<usize>>;
|
||||
//[min]~^ ERROR `std::ops::Range<usize>` is forbidden
|
||||
const RANGE : _Range<{ 0 .. 1000 }> = _Range;
|
||||
const RANGE: _Range<{ 0..1000 }> = _Range;
|
||||
|
||||
// `RangeFrom` should be usable within const generics:
|
||||
struct _RangeFrom<const R: std::ops::RangeFrom<usize>>;
|
||||
//[min]~^ ERROR `std::ops::RangeFrom<usize>` is forbidden
|
||||
const RANGE_FROM : _RangeFrom<{ 0 .. }> = _RangeFrom;
|
||||
const RANGE_FROM: _RangeFrom<{ 0.. }> = _RangeFrom;
|
||||
|
||||
// `RangeFull` should be usable within const generics:
|
||||
struct _RangeFull<const R: std::ops::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<const R: std::ops::RangeInclusive<usize>>;
|
||||
//[min]~^ ERROR `std::ops::RangeInclusive<usize>` 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<const R: std::ops::RangeTo<usize>>;
|
||||
//[min]~^ ERROR `RangeTo<usize>` is forbidden
|
||||
const RANGE_TO : _RangeTo<{ .. 1000 }> = _RangeTo;
|
||||
const RANGE_TO: _RangeTo<{ ..1000 }> = _RangeTo;
|
||||
|
||||
// `RangeToInclusive` should be usable within const generics:
|
||||
struct _RangeToInclusive<const R: std::ops::RangeToInclusive<usize>>;
|
||||
//[min]~^ ERROR `RangeToInclusive<usize>` is forbidden
|
||||
const RANGE_TO_INCLUSIVE : _RangeToInclusive<{ ..= 999 }> = _RangeToInclusive;
|
||||
//[min]~^ ERROR `std::ops::RangeToInclusive<usize>` is forbidden
|
||||
const RANGE_TO_INCLUSIVE: _RangeToInclusive<{ ..=999 }> = _RangeToInclusive;
|
||||
|
||||
pub fn main() {}
|
||||
|
|
|
|||
11
tests/ui/feature-gates/feature-gate-static_align.rs
Normal file
11
tests/ui/feature-gates/feature-gate-static_align.rs
Normal file
|
|
@ -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;
|
||||
}
|
||||
23
tests/ui/feature-gates/feature-gate-static_align.stderr
Normal file
23
tests/ui/feature-gates/feature-gate-static_align.stderr
Normal file
|
|
@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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`.
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -6,20 +6,20 @@ fn main() {
|
|||
// Unchanged
|
||||
let a: core::range::RangeFull = ..;
|
||||
let b: core::range::RangeTo<u8> = ..2;
|
||||
let c: core::range::RangeToInclusive<u8> = ..=3;
|
||||
|
||||
let _: core::ops::RangeFull = a;
|
||||
let _: core::ops::RangeTo<u8> = b;
|
||||
let _: core::ops::RangeToInclusive<u8> = c;
|
||||
|
||||
// Changed
|
||||
let a: core::range::legacy::RangeFrom<u8> = 1..;
|
||||
let b: core::range::legacy::Range<u8> = 2..3;
|
||||
let c: core::range::legacy::RangeInclusive<u8> = 4..=5;
|
||||
let d: core::range::legacy::RangeToInclusive<u8> = ..=3;
|
||||
|
||||
let a: core::ops::RangeFrom<u8> = a;
|
||||
let b: core::ops::Range<u8> = b;
|
||||
let c: core::ops::RangeInclusive<u8> = c;
|
||||
let d: core::ops::RangeToInclusive<u8> = d;
|
||||
|
||||
let _: core::ops::RangeFrom<u8> = a.into_iter();
|
||||
let _: core::ops::Range<u8> = b.into_iter();
|
||||
|
|
|
|||
|
|
@ -7,18 +7,18 @@ fn main() {
|
|||
// Unchanged
|
||||
let a: core::range::RangeFull = ..;
|
||||
let b: core::range::RangeTo<u8> = ..2;
|
||||
let c: core::range::RangeToInclusive<u8> = ..=3;
|
||||
|
||||
let _: core::ops::RangeFull = a;
|
||||
let _: core::ops::RangeTo<u8> = b;
|
||||
let _: core::ops::RangeToInclusive<u8> = c;
|
||||
|
||||
// Changed
|
||||
let a: core::range::RangeFrom<u8> = 1..;
|
||||
let b: core::range::Range<u8> = 2..3;
|
||||
let c: core::range::RangeInclusive<u8> = 4..=5;
|
||||
let d: core::range::RangeToInclusive<u8> = ..=3;
|
||||
|
||||
let _: core::range::IterRangeFrom<u8> = a.into_iter();
|
||||
let _: core::range::IterRange<u8> = b.into_iter();
|
||||
let _: core::range::IterRangeInclusive<u8> = c.into_iter();
|
||||
// RangeToInclusive has no Iterator implementation
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
||||
|
|
|
|||
26
tests/ui/static/static-align.rs
Normal file
26
tests/ui/static/static-align.rs
Normal file
|
|
@ -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)) };
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue