authorbors <bors@rust-lang.org> 2026-07-01 21:43:13 UTC
committerbors <bors@rust-lang.org> 2026-07-01 21:43:13 UTC
log2371d697abddba53be85137d5a68064066b4ae10
treedea1819c1e18969ba79bcd3e60b0b3bdab0929b9
parent4c9d2bfe4ad7a65669098754964aaebe0ec1ced2
parenta2f8a156675e4360c953f86c10572253914b2fed

Auto merge of #158676 - jhpratt:rollup-oGLvd9H, r=jhpratt

Rollup of 8 pull requests Successful merges: - rust-lang/rust#156737 (Implement `DoubleEndedIterator::next_chunk_back`) - rust-lang/rust#158180 (std: use `OnceLock` for SGX environment variable storage) - rust-lang/rust#158427 (Implement `ptr::{read,write}_unaligned` via `repr(packed)`) - rust-lang/rust#158531 (Change `adjust_ident_and_get_scope` arg to `LocalDefId`) - rust-lang/rust#158574 (Clarify ExitStatusExt documentation) - rust-lang/rust#158334 (rustdoc: Show use-site paths for unevaluated const array lengths) - rust-lang/rust#158364 (rustc_target/asm: add LoongArch LSX/LASX inline asm register support) - rust-lang/rust#158667 (rustc_sanitizers: use twox-hash without default features)

37 files changed, 1941 insertions(+), 185 deletions(-)

Cargo.lock+2-33
......@@ -3235,24 +3235,13 @@ dependencies = [
32353235 "ptr_meta",
32363236]
32373237
3238[[package]]
3239name = "rand"
3240version = "0.8.5"
3241source = "registry+https://github.com/rust-lang/crates.io-index"
3242checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
3243dependencies = [
3244 "libc",
3245 "rand_chacha 0.3.1",
3246 "rand_core 0.6.4",
3247]
3248
32493238[[package]]
32503239name = "rand"
32513240version = "0.9.2"
32523241source = "registry+https://github.com/rust-lang/crates.io-index"
32533242checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
32543243dependencies = [
3255 "rand_chacha 0.9.0",
3244 "rand_chacha",
32563245 "rand_core 0.9.3",
32573246]
32583247
......@@ -3267,16 +3256,6 @@ dependencies = [
32673256 "rand_core 0.10.1",
32683257]
32693258
3270[[package]]
3271name = "rand_chacha"
3272version = "0.3.1"
3273source = "registry+https://github.com/rust-lang/crates.io-index"
3274checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
3275dependencies = [
3276 "ppv-lite86",
3277 "rand_core 0.6.4",
3278]
3279
32803259[[package]]
32813260name = "rand_chacha"
32823261version = "0.9.0"
......@@ -3287,15 +3266,6 @@ dependencies = [
32873266 "rand_core 0.9.3",
32883267]
32893268
3290[[package]]
3291name = "rand_core"
3292version = "0.6.4"
3293source = "registry+https://github.com/rust-lang/crates.io-index"
3294checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
3295dependencies = [
3296 "getrandom 0.2.16",
3297]
3298
32993269[[package]]
33003270name = "rand_core"
33013271version = "0.9.3"
......@@ -5550,7 +5520,7 @@ dependencies = [
55505520 "indicatif",
55515521 "num",
55525522 "rand 0.9.2",
5553 "rand_chacha 0.9.0",
5523 "rand_chacha",
55545524 "rayon",
55555525]
55565526
......@@ -5924,7 +5894,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
59245894checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
59255895dependencies = [
59265896 "cfg-if",
5927 "rand 0.8.5",
59285897 "static_assertions",
59295898]
59305899
compiler/rustc_codegen_gcc/src/asm.rs+25-2
......@@ -706,7 +706,9 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str {
706706 unreachable!("clobber-only")
707707 }
708708 InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => "r",
709 InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => "f",
709 InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg)
710 | InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::vreg)
711 | InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::xreg) => "f",
710712 InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r",
711713 InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => "a",
712714 InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => "d",
......@@ -815,6 +817,12 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
815817 }
816818 InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(),
817819 InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(),
820 InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::vreg) => {
821 cx.type_vector(cx.type_i32(), 4)
822 }
823 InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::xreg) => {
824 cx.type_vector(cx.type_i32(), 8)
825 }
818826 InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(),
819827 InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(),
820828 InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => cx.type_i16(),
......@@ -1013,7 +1021,22 @@ fn modifier_to_gcc(
10131021 }
10141022 }
10151023 InlineAsmRegClass::Hexagon(_) => None,
1016 InlineAsmRegClass::LoongArch(_) => None,
1024 InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => None,
1025 InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => modifier,
1026 InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::vreg) => {
1027 if modifier.is_none() {
1028 Some('w')
1029 } else {
1030 modifier
1031 }
1032 }
1033 InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::xreg) => {
1034 if modifier.is_none() {
1035 Some('u')
1036 } else {
1037 modifier
1038 }
1039 }
10171040 InlineAsmRegClass::Mips(_) => None,
10181041 InlineAsmRegClass::Nvptx(_) => None,
10191042 InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vsreg) => {
compiler/rustc_codegen_llvm/src/asm.rs+21-2
......@@ -709,7 +709,9 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
709709 Hexagon(HexagonInlineAsmRegClass::vreg_pair) => "v",
710710 Hexagon(HexagonInlineAsmRegClass::qreg) => unreachable!("clobber-only"),
711711 LoongArch(LoongArchInlineAsmRegClass::reg) => "r",
712 LoongArch(LoongArchInlineAsmRegClass::freg) => "f",
712 LoongArch(LoongArchInlineAsmRegClass::freg)
713 | LoongArch(LoongArchInlineAsmRegClass::vreg)
714 | LoongArch(LoongArchInlineAsmRegClass::xreg) => "f",
713715 Mips(MipsInlineAsmRegClass::reg) => "r",
714716 Mips(MipsInlineAsmRegClass::freg) => "f",
715717 Nvptx(NvptxInlineAsmRegClass::reg16) => "h",
......@@ -814,7 +816,22 @@ fn modifier_to_llvm(
814816 }
815817 Amdgpu(_) => None,
816818 Hexagon(_) => None,
817 LoongArch(_) => None,
819 LoongArch(LoongArchInlineAsmRegClass::reg) => None,
820 LoongArch(LoongArchInlineAsmRegClass::freg) => modifier,
821 LoongArch(LoongArchInlineAsmRegClass::vreg) => {
822 if modifier.is_none() {
823 Some('w')
824 } else {
825 modifier
826 }
827 }
828 LoongArch(LoongArchInlineAsmRegClass::xreg) => {
829 if modifier.is_none() {
830 Some('u')
831 } else {
832 modifier
833 }
834 }
818835 Mips(_) => None,
819836 Nvptx(_) => None,
820837 PowerPC(PowerPCInlineAsmRegClass::vsreg) => {
......@@ -917,6 +934,8 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
917934 Hexagon(HexagonInlineAsmRegClass::qreg) => unreachable!("clobber-only"),
918935 LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(),
919936 LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(),
937 LoongArch(LoongArchInlineAsmRegClass::vreg) => cx.type_vector(cx.type_i32(), 4),
938 LoongArch(LoongArchInlineAsmRegClass::xreg) => cx.type_vector(cx.type_i32(), 8),
920939 Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(),
921940 Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(),
922941 Nvptx(NvptxInlineAsmRegClass::reg16) => cx.type_i16(),
compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs+5-7
......@@ -1707,8 +1707,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
17071707 .inherent_impls(adt_did)
17081708 .iter()
17091709 .filter_map(|&impl_| {
1710 let (item, scope) =
1711 self.probe_assoc_item_unchecked(name, assoc_tag, block, impl_)?;
1710 let (item, scope) = self.probe_assoc_item_unchecked(name, assoc_tag, impl_)?;
17121711 Some(InherentAssocCandidate { impl_, assoc_item: item.def_id, scope })
17131712 })
17141713 .collect();
......@@ -1784,7 +1783,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
17841783 span: Span,
17851784 scope: DefId,
17861785 ) -> Option<ty::AssocItem> {
1787 let (item, scope) = self.probe_assoc_item_unchecked(ident, assoc_tag, block, scope)?;
1786 let (item, scope) = self.probe_assoc_item_unchecked(ident, assoc_tag, scope)?;
17881787 self.check_assoc_item(item.def_id, ident, scope, block, span);
17891788 Some(item)
17901789 }
......@@ -1797,12 +1796,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
17971796 &self,
17981797 ident: Ident,
17991798 assoc_tag: ty::AssocTag,
1800 block: HirId,
18011799 scope: DefId,
18021800 ) -> Option<(ty::AssocItem, /*scope*/ DefId)> {
18031801 let tcx = self.tcx();
18041802
1805 let (ident, def_scope) = tcx.adjust_ident_and_get_scope(ident, scope, block);
1803 let (ident, def_scope) = tcx.adjust_ident_and_get_scope(ident, scope, self.item_def_id());
18061804 // We have already adjusted the item name above, so compare with `.normalize_to_macros_2_0()`
18071805 // instead of calling `filter_by_name_and_kind` which would needlessly normalize the
18081806 // `ident` again and again.
......@@ -3497,8 +3495,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
34973495 }
34983496 (FIRST_VARIANT, def.non_enum_variant())
34993497 };
3500 let block = tcx.local_def_id_to_hir_id(item_def_id);
3501 let (ident, def_scope) = tcx.adjust_ident_and_get_scope(field, def.did(), block);
3498 let (ident, def_scope) =
3499 tcx.adjust_ident_and_get_scope(field, def.did(), item_def_id);
35023500 if let Some((field_idx, field)) = variant
35033501 .fields
35043502 .iter_enumerated()
compiler/rustc_hir_typeck/src/expr.rs+8-9
......@@ -2764,9 +2764,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
27642764 return Ty::new_error(self.tcx(), guar);
27652765 }
27662766
2767 let fn_body_hir_id = self.tcx.local_def_id_to_hir_id(self.body_id);
27682767 let (ident, def_scope) =
2769 self.tcx.adjust_ident_and_get_scope(field, base_def.did(), fn_body_hir_id);
2768 self.tcx.adjust_ident_and_get_scope(field, base_def.did(), self.body_id);
27702769
27712770 if let Some((idx, field)) = self.find_adt_field(*base_def, ident) {
27722771 self.write_field_index(expr.hir_id, idx);
......@@ -3768,9 +3767,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
37683767
37693768 match container.kind() {
37703769 ty::Adt(container_def, args) if container_def.is_enum() => {
3771 let block = self.tcx.local_def_id_to_hir_id(self.body_id);
3772 let (ident, _def_scope) =
3773 self.tcx.adjust_ident_and_get_scope(field, container_def.did(), block);
3770 let ident = self.tcx.adjust_ident(field, container_def.did());
37743771
37753772 if !self.tcx.features().offset_of_enum() {
37763773 rustc_session::errors::feature_err(
......@@ -3806,7 +3803,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
38063803 break;
38073804 };
38083805 let (subident, sub_def_scope) =
3809 self.tcx.adjust_ident_and_get_scope(subfield, variant.def_id, block);
3806 self.tcx.adjust_ident_and_get_scope(subfield, variant.def_id, self.body_id);
38103807
38113808 let Some((subindex, field)) = variant
38123809 .fields
......@@ -3854,9 +3851,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
38543851 continue;
38553852 }
38563853 ty::Adt(container_def, args) => {
3857 let block = self.tcx.local_def_id_to_hir_id(self.body_id);
3858 let (ident, def_scope) =
3859 self.tcx.adjust_ident_and_get_scope(field, container_def.did(), block);
3854 let (ident, def_scope) = self.tcx.adjust_ident_and_get_scope(
3855 field,
3856 container_def.did(),
3857 self.body_id,
3858 );
38603859
38613860 let fields = &container_def.non_enum_variant().fields;
38623861 if let Some((index, field)) = fields
compiler/rustc_hir_typeck/src/method/probe.rs+2-3
......@@ -810,9 +810,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
810810 fn push_candidate(&mut self, candidate: Candidate<'tcx>, is_inherent: bool) {
811811 let is_accessible = if let Some(name) = self.method_name {
812812 let item = candidate.item;
813 let hir_id = self.tcx.local_def_id_to_hir_id(self.body_id);
814 let def_scope =
815 self.tcx.adjust_ident_and_get_scope(name, item.container_id(self.tcx), hir_id).1;
813 let container_id = item.container_id(self.tcx);
814 let def_scope = self.tcx.adjust_ident_and_get_scope(name, container_id, self.body_id).1;
816815 item.visibility(self.tcx).is_accessible_from(def_scope, self.tcx)
817816 } else {
818817 true
compiler/rustc_middle/src/ty/mod.rs+2-3
......@@ -2137,18 +2137,17 @@ impl<'tcx> TyCtxt<'tcx> {
21372137 ident
21382138 }
21392139
2140 // FIXME(vincenzopalazzo): move the HirId to a LocalDefId
21412140 pub fn adjust_ident_and_get_scope(
21422141 self,
21432142 mut ident: Ident,
21442143 scope: DefId,
2145 block: hir::HirId,
2144 item_id: LocalDefId,
21462145 ) -> (Ident, DefId) {
21472146 let scope = ident
21482147 .span
21492148 .normalize_to_macros_2_0_and_adjust(self.expn_that_defined(scope))
21502149 .and_then(|actual_expansion| actual_expansion.expn_data().parent_module)
2151 .unwrap_or_else(|| self.parent_module(block).to_def_id());
2150 .unwrap_or_else(|| self.parent_module_from_def_id(item_id).to_def_id());
21522151 (ident, scope)
21532152 }
21542153
compiler/rustc_privacy/src/lib.rs+2-1
......@@ -948,7 +948,8 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
948948
949949 // definition of the field
950950 let ident = Ident::new(sym::dummy, use_ctxt);
951 let (_, def_id) = self.tcx.adjust_ident_and_get_scope(ident, def.did(), hir_id);
951 let (_, def_id) =
952 self.tcx.adjust_ident_and_get_scope(ident, def.did(), hir_id.owner.def_id);
952953 !field.vis.is_accessible_from(def_id, self.tcx)
953954 }
954955
compiler/rustc_sanitizers/Cargo.toml+1-1
......@@ -14,5 +14,5 @@ rustc_span = { path = "../rustc_span" }
1414rustc_target = { path = "../rustc_target" }
1515rustc_trait_selection = { path = "../rustc_trait_selection" }
1616tracing = "0.1"
17twox-hash = "1.6.3"
17twox-hash = { version = "1.6.3", default-features = false }
1818# tidy-alphabetical-end
compiler/rustc_span/src/symbol.rs+3
......@@ -1170,6 +1170,7 @@ symbols! {
11701170 lang_items,
11711171 large_assignments,
11721172 last,
1173 lasx,
11731174 lateout,
11741175 lazy_normalization_consts,
11751176 lazy_type_alias,
......@@ -1227,6 +1228,7 @@ symbols! {
12271228 loop_hints,
12281229 loop_match,
12291230 lr,
1231 lsx,
12301232 lt,
12311233 m68k,
12321234 m68k_target_feature,
......@@ -2374,6 +2376,7 @@ symbols! {
23742376 xloop,
23752377 xmm_reg,
23762378 xop_target_feature,
2379 xreg,
23772380 xtensa,
23782381 xtensa_target_feature,
23792382 yeet_desugar_details,
compiler/rustc_target/src/asm/loongarch.rs+150-1
......@@ -8,12 +8,19 @@ def_reg_class! {
88 LoongArch LoongArchInlineAsmRegClass {
99 reg,
1010 freg,
11 vreg,
12 xreg,
1113 }
1214}
1315
1416impl LoongArchInlineAsmRegClass {
1517 pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] {
16 &[]
18 match self {
19 Self::freg => &['w', 'u'],
20 Self::vreg => &['u'],
21 Self::xreg => &['w'],
22 _ => &[],
23 }
1724 }
1825
1926 pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option<Self> {
......@@ -35,6 +42,7 @@ impl LoongArchInlineAsmRegClass {
3542 pub fn supported_types(
3643 self,
3744 arch: InlineAsmArch,
45 allow_experimental_reg: bool,
3846 ) -> &'static [(InlineAsmType, Option<Symbol>)] {
3947 match (self, arch) {
4048 (Self::reg, InlineAsmArch::LoongArch64) => {
......@@ -42,6 +50,27 @@ impl LoongArchInlineAsmRegClass {
4250 }
4351 (Self::reg, InlineAsmArch::LoongArch32) => types! { _: I8, I16, I32, F16, F32; },
4452 (Self::freg, _) => types! { f: F16, F32; d: F64; },
53 (Self::vreg, _) => {
54 if allow_experimental_reg {
55 types! {
56 lsx: F16, F32, F64,
57 VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2);
58 }
59 } else {
60 &[]
61 }
62 }
63 (Self::xreg, _) => {
64 if allow_experimental_reg {
65 types! {
66 lasx: F16, F32, F64,
67 VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2),
68 VecI8(32), VecI16(16), VecI32(8), VecI64(4), VecF32(8), VecF64(4);
69 }
70 } else {
71 &[]
72 }
73 }
4574 _ => unreachable!("unsupported register class"),
4675 }
4776 }
......@@ -108,6 +137,70 @@ def_regs! {
108137 f29: freg = ["$f29","$fs5"],
109138 f30: freg = ["$f30","$fs6"],
110139 f31: freg = ["$f31","$fs7"],
140 vr0: vreg = ["$vr0"],
141 vr1: vreg = ["$vr1"],
142 vr2: vreg = ["$vr2"],
143 vr3: vreg = ["$vr3"],
144 vr4: vreg = ["$vr4"],
145 vr5: vreg = ["$vr5"],
146 vr6: vreg = ["$vr6"],
147 vr7: vreg = ["$vr7"],
148 vr8: vreg = ["$vr8"],
149 vr9: vreg = ["$vr9"],
150 vr10: vreg = ["$vr10"],
151 vr11: vreg = ["$vr11"],
152 vr12: vreg = ["$vr12"],
153 vr13: vreg = ["$vr13"],
154 vr14: vreg = ["$vr14"],
155 vr15: vreg = ["$vr15"],
156 vr16: vreg = ["$vr16"],
157 vr17: vreg = ["$vr17"],
158 vr18: vreg = ["$vr18"],
159 vr19: vreg = ["$vr19"],
160 vr20: vreg = ["$vr20"],
161 vr21: vreg = ["$vr21"],
162 vr22: vreg = ["$vr22"],
163 vr23: vreg = ["$vr23"],
164 vr24: vreg = ["$vr24"],
165 vr25: vreg = ["$vr25"],
166 vr26: vreg = ["$vr26"],
167 vr27: vreg = ["$vr27"],
168 vr28: vreg = ["$vr28"],
169 vr29: vreg = ["$vr29"],
170 vr30: vreg = ["$vr30"],
171 vr31: vreg = ["$vr31"],
172 xr0: xreg = ["$xr0"],
173 xr1: xreg = ["$xr1"],
174 xr2: xreg = ["$xr2"],
175 xr3: xreg = ["$xr3"],
176 xr4: xreg = ["$xr4"],
177 xr5: xreg = ["$xr5"],
178 xr6: xreg = ["$xr6"],
179 xr7: xreg = ["$xr7"],
180 xr8: xreg = ["$xr8"],
181 xr9: xreg = ["$xr9"],
182 xr10: xreg = ["$xr10"],
183 xr11: xreg = ["$xr11"],
184 xr12: xreg = ["$xr12"],
185 xr13: xreg = ["$xr13"],
186 xr14: xreg = ["$xr14"],
187 xr15: xreg = ["$xr15"],
188 xr16: xreg = ["$xr16"],
189 xr17: xreg = ["$xr17"],
190 xr18: xreg = ["$xr18"],
191 xr19: xreg = ["$xr19"],
192 xr20: xreg = ["$xr20"],
193 xr21: xreg = ["$xr21"],
194 xr22: xreg = ["$xr22"],
195 xr23: xreg = ["$xr23"],
196 xr24: xreg = ["$xr24"],
197 xr25: xreg = ["$xr25"],
198 xr26: xreg = ["$xr26"],
199 xr27: xreg = ["$xr27"],
200 xr28: xreg = ["$xr28"],
201 xr29: xreg = ["$xr29"],
202 xr30: xreg = ["$xr30"],
203 xr31: xreg = ["$xr31"],
111204 #error = ["$r0","$zero"] =>
112205 "constant zero cannot be used as an operand for inline asm",
113206 #error = ["$r2","$tp"] =>
......@@ -132,4 +225,60 @@ impl LoongArchInlineAsmReg {
132225 ) -> fmt::Result {
133226 out.write_str(self.name())
134227 }
228
229 pub fn overlapping_regs(self, mut cb: impl FnMut(LoongArchInlineAsmReg)) {
230 macro_rules! reg_conflicts {
231 (
232 $(
233 $f:ident : $v:ident : $x:ident
234 ),*;
235 ) => {
236 match self {
237 $(
238 Self::$f | Self::$v | Self::$x => {
239 cb(Self::$f);
240 cb(Self::$v);
241 cb(Self::$x);
242 }
243 )*
244 r => cb(r),
245 }
246 };
247 }
248
249 reg_conflicts! {
250 f0 : vr0 : xr0,
251 f1 : vr1 : xr1,
252 f2 : vr2 : xr2,
253 f3 : vr3 : xr3,
254 f4 : vr4 : xr4,
255 f5 : vr5 : xr5,
256 f6 : vr6 : xr6,
257 f7 : vr7 : xr7,
258 f8 : vr8 : xr8,
259 f9 : vr9 : xr9,
260 f10 : vr10 : xr10,
261 f11 : vr11 : xr11,
262 f12 : vr12 : xr12,
263 f13 : vr13 : xr13,
264 f14 : vr14 : xr14,
265 f15 : vr15 : xr15,
266 f16 : vr16 : xr16,
267 f17 : vr17 : xr17,
268 f18 : vr18 : xr18,
269 f19 : vr19 : xr19,
270 f20 : vr20 : xr20,
271 f21 : vr21 : xr21,
272 f22 : vr22 : xr22,
273 f23 : vr23 : xr23,
274 f24 : vr24 : xr24,
275 f25 : vr25 : xr25,
276 f26 : vr26 : xr26,
277 f27 : vr27 : xr27,
278 f28 : vr28 : xr28,
279 f29 : vr29 : xr29,
280 f30 : vr30 : xr30,
281 f31 : vr31 : xr31;
282 }
283 }
135284}
compiler/rustc_target/src/asm/mod.rs+2-2
......@@ -474,7 +474,7 @@ impl InlineAsmReg {
474474 Self::RiscV(_) => cb(self),
475475 Self::PowerPC(r) => r.overlapping_regs(|r| cb(Self::PowerPC(r))),
476476 Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))),
477 Self::LoongArch(_) => cb(self),
477 Self::LoongArch(r) => r.overlapping_regs(|r| cb(Self::LoongArch(r))),
478478 Self::Mips(_) => cb(self),
479479 Self::S390x(r) => r.overlapping_regs(|r| cb(Self::S390x(r))),
480480 Self::Sparc(_) => cb(self),
......@@ -655,7 +655,7 @@ impl InlineAsmRegClass {
655655 Self::Nvptx(r) => r.supported_types(arch).into(),
656656 Self::PowerPC(r) => r.supported_types(arch).into(),
657657 Self::Hexagon(r) => r.supported_types(arch).into(),
658 Self::LoongArch(r) => r.supported_types(arch).into(),
658 Self::LoongArch(r) => r.supported_types(arch, allow_experimental_reg).into(),
659659 Self::Mips(r) => r.supported_types(arch).into(),
660660 Self::S390x(r) => r.supported_types(arch).into(),
661661 Self::Sparc(r) => r.supported_types(arch).into(),
compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs+5-3
......@@ -334,7 +334,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
334334 return;
335335 }
336336
337 let fn_body_hir_id = self.tcx.local_def_id_to_hir_id(typeck_results.hir_owner.def_id);
338337 let mut private_candidate: Option<(Ty<'tcx>, Ty<'tcx>, Span)> = None;
339338
340339 for (deref_base_ty, _) in (self.autoderef_steps)(base_ty) {
......@@ -346,8 +345,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
346345 continue;
347346 }
348347
349 let (adjusted_ident, def_scope) =
350 self.tcx.adjust_ident_and_get_scope(field_ident, base_def.did(), fn_body_hir_id);
348 let (adjusted_ident, def_scope) = self.tcx.adjust_ident_and_get_scope(
349 field_ident,
350 base_def.did(),
351 typeck_results.hir_owner.def_id,
352 );
351353
352354 let Some((_, field_def)) =
353355 base_def.non_enum_variant().fields.iter_enumerated().find(|(_, field)| {
library/alloc/src/lib.rs+1
......@@ -144,6 +144,7 @@
144144#![feature(legacy_receiver_trait)]
145145#![feature(likely_unlikely)]
146146#![feature(local_waker)]
147#![feature(maybe_uninit_array_assume_init)]
147148#![feature(maybe_uninit_uninit_array_transpose)]
148149#![feature(panic_internals)]
149150#![feature(pattern)]
library/alloc/src/vec/into_iter.rs+41
......@@ -445,6 +445,47 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
445445 }
446446 }
447447
448 #[inline]
449 fn next_chunk_back<const N: usize>(&mut self) -> Result<[T; N], core::array::IntoIter<T, N>> {
450 let mut raw_ary = [const { MaybeUninit::uninit() }; N];
451
452 let len = self.len();
453
454 if T::IS_ZST {
455 if len < N {
456 self.forget_remaining_elements();
457 // Safety: ZSTs can be conjured ex nihilo, only the amount has to be correct
458 return Err(unsafe { array::IntoIter::new_unchecked(raw_ary, N - len..N) });
459 }
460
461 self.end = self.end.wrapping_byte_sub(N);
462 // Safety: ditto
463 return Ok(unsafe { MaybeUninit::array_assume_init(raw_ary) });
464 }
465
466 if len < N {
467 // Safety: `len` indicates that this many elements are available and we just checked that
468 // it fits into the array.
469 unsafe {
470 ptr::copy_nonoverlapping(self.ptr.as_ptr(), raw_ary.as_mut_ptr() as *mut T, len);
471 self.forget_remaining_elements();
472 return Err(array::IntoIter::new_unchecked(raw_ary, 0..len));
473 }
474 }
475
476 // Safety: `len` is larger than the array size. Copy a fixed amount here to fully initialize
477 // the array.
478 unsafe {
479 ptr::copy_nonoverlapping(
480 self.ptr.add(len - N).as_ptr(),
481 raw_ary.as_mut_ptr() as *mut T,
482 N,
483 );
484 self.end = self.end.sub(N);
485 Ok(MaybeUninit::array_assume_init(raw_ary))
486 }
487 }
488
448489 #[inline]
449490 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
450491 let step_size = self.len().min(n);
library/alloctests/tests/vec.rs+17
......@@ -1027,6 +1027,15 @@ fn test_into_iter_next_chunk() {
10271027 assert_eq!(iter.next_chunk::<4>().unwrap_err().as_slice(), &[]); // N is explicitly 4
10281028}
10291029
1030#[test]
1031fn test_into_iter_next_chunk_back() {
1032 let mut iter = b"lorem".to_vec().into_iter();
1033
1034 assert_eq!(iter.next_chunk_back().unwrap(), [b'e', b'm']); // N is inferred as 2
1035 assert_eq!(iter.next_chunk_back().unwrap(), [b'l', b'o', b'r']); // N is inferred as 3
1036 assert_eq!(iter.next_chunk_back::<4>().unwrap_err().as_slice(), &[]); // N is explicitly 4
1037}
1038
10301039#[test]
10311040fn test_into_iter_clone() {
10321041 fn iter_equal<I: Iterator<Item = i32>>(it: I, slice: &[i32]) {
......@@ -1131,6 +1140,14 @@ fn test_into_iter_zst() {
11311140 let mut it = vec![C, C].into_iter();
11321141 it.next_chunk::<4>().unwrap_err();
11331142 drop(it);
1143
1144 let mut it = vec![C, C].into_iter();
1145 it.next_chunk_back::<1>().unwrap();
1146 drop(it);
1147
1148 let mut it = vec![C, C].into_iter();
1149 it.next_chunk_back::<4>().unwrap_err();
1150 drop(it);
11341151}
11351152
11361153#[test]
library/core/src/array/mod.rs+154
......@@ -969,6 +969,54 @@ const impl<T: [const] Destruct> Drop for Guard<'_, T> {
969969 }
970970}
971971
972/// Panic guard for incremental initialization of arrays from the back.
973///
974/// Elements of the array are populated starting from the end towards the beginning.
975/// Disarm the guard with `mem::forget` once the array has been fully initialized.
976///
977/// # Safety
978///
979/// All write accesses to this structure are unsafe and must maintain a correct
980/// count of `initialized` elements.
981struct GuardBack<'a, T> {
982 /// The array to be initialized (will be filled from the end).
983 pub array_mut: &'a mut [MaybeUninit<T>],
984 /// The number of items that have been initialized so far.
985 pub initialized: usize,
986}
987
988impl<T> GuardBack<'_, T> {
989 /// Adds an item to the array and updates the initialized item counter.
990 ///
991 /// # Safety
992 ///
993 /// No more than N elements must be initialized.
994 #[inline]
995 pub(crate) unsafe fn push_unchecked(&mut self, item: T) {
996 // SAFETY: If `initialized` was correct before and the caller does not
997 // invoke this method more than N times, then writes will be in-bounds
998 // and slots will not be initialized more than once.
999 unsafe {
1000 let offset = self.initialized.unchecked_add(1);
1001 let index = self.array_mut.len().unchecked_sub(offset);
1002 self.array_mut.get_unchecked_mut(index).write(item);
1003 self.initialized = offset;
1004 }
1005 }
1006}
1007
1008impl<T: Destruct> Drop for GuardBack<'_, T> {
1009 #[inline]
1010 fn drop(&mut self) {
1011 debug_assert!(self.initialized <= self.array_mut.len());
1012 let len = self.array_mut.len();
1013 // SAFETY: this slice will contain only initialized objects.
1014 unsafe {
1015 self.array_mut.get_unchecked_mut(len - self.initialized..len).assume_init_drop();
1016 }
1017 }
1018}
1019
9721020/// Pulls `N` items from `iter` and returns them as an array. If the iterator
9731021/// yields fewer than `N` items, `Err` is returned containing an iterator over
9741022/// the already yielded items.
......@@ -1076,3 +1124,109 @@ const fn iter_next_chunk_erased<T>(
10761124 mem::forget(guard);
10771125 Ok(())
10781126}
1127
1128/// Pulls `N` items from the back of `iter` and returns them as an array.
1129/// If the iterator yields fewer than `N` items, `Err` is returned containing
1130/// an iterator over the already yielded items.
1131///
1132/// Since the iterator is passed as a mutable reference and this function calls
1133/// `next_back` at most `N` times, the iterator can still be used afterwards to
1134/// retrieve the remaining items.
1135///
1136/// If `iter.next_back()` panics, all items already yielded by the iterator are
1137/// dropped.
1138///
1139/// Used for [`DoubleEndedIterator::next_chunk_back`].
1140#[inline]
1141pub(crate) fn iter_next_chunk_back<T, const N: usize>(
1142 iter: &mut impl DoubleEndedIterator<Item = T>,
1143) -> Result<[T; N], IntoIter<T, N>> {
1144 iter.spec_next_chunk_back()
1145}
1146
1147pub(crate) trait SpecNextChunkBack<T, const N: usize>:
1148 DoubleEndedIterator<Item = T>
1149{
1150 fn spec_next_chunk_back(&mut self) -> Result<[T; N], IntoIter<T, N>>;
1151}
1152
1153impl<I: DoubleEndedIterator<Item = T>, T, const N: usize> SpecNextChunkBack<T, N> for I {
1154 #[inline]
1155 default fn spec_next_chunk_back(&mut self) -> Result<[T; N], IntoIter<T, N>> {
1156 let mut array = [const { MaybeUninit::uninit() }; N];
1157 let r = iter_next_chunk_back_erased(&mut array, self);
1158 match r {
1159 Ok(()) => {
1160 // SAFETY: All elements of `array` were populated.
1161 Ok(unsafe { MaybeUninit::array_assume_init(array) })
1162 }
1163 Err(initialized) => {
1164 // SAFETY: Only the last `initialized` elements were populated
1165 Err(unsafe { IntoIter::new_unchecked(array, N - initialized..N) })
1166 }
1167 }
1168 }
1169}
1170
1171impl<I: DoubleEndedIterator<Item = T> + TrustedLen, T, const N: usize> SpecNextChunkBack<T, N>
1172 for I
1173{
1174 fn spec_next_chunk_back(&mut self) -> Result<[T; N], IntoIter<T, N>> {
1175 let len = (*self).size_hint().0;
1176 let mut array = [const { MaybeUninit::uninit() }; N];
1177 if len < N {
1178 // SAFETY: `TrustedLen`, an unsafe trait, requires that i can get len items out of it.
1179 unsafe { write_back(&mut array, self, len) };
1180 // SAFETY: Only the last `len` elements were populated
1181 Err(unsafe { IntoIter::new_unchecked(array, N - len..N) })
1182 } else {
1183 // SAFETY: `TrustedLen`, an unsafe trait, requires that i can get N items out of it.
1184 unsafe { write_back(&mut array, self, N) };
1185 // SAFETY: All N items were populated
1186 Ok(unsafe { MaybeUninit::array_assume_init(array) })
1187 }
1188 }
1189}
1190
1191// SAFETY: `from` must have len items, and len items must be < N.
1192unsafe fn write_back<T, const N: usize>(
1193 to: &mut [MaybeUninit<T>; N],
1194 from: &mut impl DoubleEndedIterator<Item = T>,
1195 len: usize,
1196) {
1197 let mut guard = GuardBack { array_mut: to, initialized: 0 };
1198 while guard.initialized < len {
1199 // SAFETY: caller has guaranteed, from has len items.
1200 let item = unsafe { from.next_back().unwrap_unchecked() };
1201 // SAFETY: guard.initialized < len < N
1202 unsafe { guard.push_unchecked(item) };
1203 }
1204 crate::mem::forget(guard);
1205}
1206
1207/// Version of [`iter_next_chunk_back`] using a passed-in slice
1208/// in order to avoid needing to monomorphize for every array length.
1209///
1210/// Unfortunately this loop has two exit conditions, the buffer filling up
1211/// or the iterator running out of items, making it tend to optimize poorly.
1212#[inline]
1213fn iter_next_chunk_back_erased<T>(
1214 buffer: &mut [MaybeUninit<T>],
1215 iter: &mut impl DoubleEndedIterator<Item = T>,
1216) -> Result<(), usize> {
1217 // if `Iterator::next_back` panics, this guard will drop already initialized items
1218 let mut guard = GuardBack { array_mut: buffer, initialized: 0 };
1219 while guard.initialized < guard.array_mut.len() {
1220 let Some(item) = iter.next_back() else {
1221 let initialized = guard.initialized;
1222 mem::forget(guard);
1223 return Err(initialized);
1224 };
1225
1226 // SAFETY: The loop condition ensures we have space to push the item
1227 unsafe { guard.push_unchecked(item) };
1228 }
1229
1230 mem::forget(guard);
1231 Ok(())
1232}
library/core/src/iter/traits/double_ended.rs+48
......@@ -1,3 +1,4 @@
1use crate::array;
12use crate::marker::Destruct;
23use crate::num::NonZero;
34use crate::ops::{ControlFlow, Try};
......@@ -95,6 +96,53 @@ pub const trait DoubleEndedIterator: [const] Iterator {
9596 #[stable(feature = "rust1", since = "1.0.0")]
9697 fn next_back(&mut self) -> Option<Self::Item>;
9798
99 /// Advances from the back of the iterator and returns an array containing the next
100 /// `N` values in sequence.
101 ///
102 /// If there are not enough elements to fill the array then `Err` is returned
103 /// containing an iterator over the remaining elements.
104 ///
105 /// Note: This is not equivalent to doing `iter.rev().next_chunk()` as this method
106 /// takes elements from the back of the iterator and preserves the order that the
107 /// elements were seen in the original iterator.
108 ///
109 /// # Examples
110 ///
111 /// Basic usage:
112 ///
113 /// ```
114 /// #![feature(iter_next_chunk)]
115 ///
116 /// let mut iter = "lorem".chars();
117 ///
118 /// assert_eq!(iter.next_chunk_back().unwrap(), ['e', 'm']); // N is inferred as 2
119 /// assert_eq!(iter.next_chunk_back().unwrap(), ['l', 'o', 'r']); // N is inferred as 3
120 /// assert_eq!(iter.next_chunk_back::<4>().unwrap_err().as_slice(), &[]); // N is explicitly 4
121 /// ```
122 ///
123 /// Split a string and get the last three items in sequence.
124 ///
125 /// ```
126 /// #![feature(iter_next_chunk)]
127 ///
128 /// let quote = "not all those who wander are lost";
129 /// let [first, second, third] = quote.split_whitespace().next_chunk_back().unwrap();
130 /// assert_eq!(first, "wander");
131 /// assert_eq!(second, "are");
132 /// assert_eq!(third, "lost");
133 /// ```
134 #[inline]
135 #[unstable(feature = "iter_next_chunk", issue = "98326")]
136 #[rustc_non_const_trait_method]
137 fn next_chunk_back<const N: usize>(
138 &mut self,
139 ) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>>
140 where
141 Self: Sized,
142 {
143 crate::array::iter_next_chunk_back(self)
144 }
145
98146 /// Advances the iterator from the back by `n` elements.
99147 ///
100148 /// `advance_back_by` is the reverse version of [`advance_by`]. This method will
library/core/src/ptr/mod.rs+29-14
......@@ -1810,16 +1810,24 @@ pub const unsafe fn read<T>(src: *const T) -> T {
18101810#[track_caller]
18111811#[rustc_diagnostic_item = "ptr_read_unaligned"]
18121812pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
1813 let mut tmp = MaybeUninit::<T>::uninit();
1813 // Always true thanks to the repr, but to demonstrate
1814 const {
1815 assert!(mem::offset_of!(Packed::<T>, 0) == 0);
1816 assert!(size_of::<T>() == size_of::<Packed<T>>());
1817 }
1818
1819 let src = src.cast::<Packed<T>>();
18141820 // SAFETY: the caller must guarantee that `src` is valid for reads.
1815 // `src` cannot overlap `tmp` because `tmp` was just allocated on
1816 // the stack as a separate allocation.
1821 // Reading it as `Packed<T>` instead of `T` reads those same bytes because
1822 // it's the same size (thus zero offset), but with alignment 1 instead.
18171823 //
1818 // Also, since we just wrote a valid value into `tmp`, it is guaranteed
1819 // to be properly initialized.
1824 // Similarly, because it's the same bytes it's sound to transmute from the
1825 // `Packed<T>` to `T`. Transmute is a value-based (not a place-based)
1826 // operation that doesn't care about alignment.
18201827 unsafe {
1821 copy_nonoverlapping(src as *const u8, tmp.as_mut_ptr() as *mut u8, size_of::<T>());
1822 tmp.assume_init()
1828 let packed = read(src);
1829 // Can't just destructure because that's not allowed in const fn
1830 mem::transmute_neo(packed)
18231831 }
18241832}
18251833
......@@ -2012,14 +2020,18 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
20122020#[rustc_diagnostic_item = "ptr_write_unaligned"]
20132021#[track_caller]
20142022pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
2015 // SAFETY: the caller must guarantee that `dst` is valid for writes.
2016 // `dst` cannot overlap `src` because the caller has mutable access
2017 // to `dst` while `src` is owned by this function.
2018 unsafe {
2019 copy_nonoverlapping((&raw const src) as *const u8, dst as *mut u8, size_of::<T>());
2020 // We are calling the intrinsic directly to avoid function calls in the generated code.
2021 intrinsics::forget(src);
2023 // Always true thanks to the repr, but to demonstrate
2024 const {
2025 assert!(mem::offset_of!(Packed::<T>, 0) == 0);
2026 assert!(size_of::<T>() == size_of::<Packed<T>>());
20222027 }
2028
2029 let dst = dst.cast::<Packed<T>>();
2030 let src = Packed(src);
2031 // SAFETY: the caller must guarantee that `dst` is valid for writes.
2032 // Writing it as `Packed<T>` instead of `T` writes those same bytes because
2033 // it's the same size (thus zero offset), but with alignment 1 instead.
2034 unsafe { write(dst, src) }
20232035}
20242036
20252037/// Performs a volatile read of the value from `src` without moving it.
......@@ -2809,3 +2821,6 @@ pub macro addr_of($place:expr) {
28092821pub macro addr_of_mut($place:expr) {
28102822 &raw mut $place
28112823}
2824
2825#[repr(C, packed)]
2826struct Packed<T>(T);
library/coretests/tests/iter/adapters/filter.rs+12
......@@ -63,3 +63,15 @@ fn test_next_chunk_does_not_leak() {
6363 assert_eq!(Rc::strong_count(w), 1);
6464 }
6565}
66
67#[test]
68fn test_next_chunk_back_does_not_leak() {
69 let drop_witness: [_; 5] = std::array::from_fn(|_| Rc::new(()));
70
71 let v = (0..5).map(|i| drop_witness[i].clone()).collect::<Vec<_>>();
72 let _ = v.into_iter().filter(|_| false).next_chunk_back::<1>();
73
74 for ref w in drop_witness {
75 assert_eq!(Rc::strong_count(w), 1);
76 }
77}
library/coretests/tests/iter/traits/iterator.rs+34
......@@ -619,6 +619,18 @@ fn test_next_chunk() {
619619 assert_eq!(it.next_chunk::<0>().unwrap(), []);
620620}
621621
622#[test]
623fn test_next_chunk_back() {
624 let mut it = 0..12;
625 assert_eq!(it.next_chunk_back().unwrap(), [8, 9, 10, 11]);
626 assert_eq!(it.next_chunk_back().unwrap(), []);
627 assert_eq!(it.next_chunk_back().unwrap(), [2, 3, 4, 5, 6, 7]);
628 assert_eq!(it.next_chunk_back::<4>().unwrap_err().as_slice(), &[0, 1]);
629
630 let mut it = std::iter::once_with(|| panic!());
631 assert_eq!(it.next_chunk_back::<0>().unwrap(), []);
632}
633
622634#[test]
623635fn test_next_chunk_untrusted() {
624636 struct Untrusted<I: Iterator>(I);
......@@ -636,6 +648,28 @@ fn test_next_chunk_untrusted() {
636648 assert_eq!(it.next_chunk::<4>().unwrap_err().as_slice(), &[10, 11]);
637649}
638650
651#[test]
652fn test_next_chunk_back_untrusted() {
653 struct Untrusted<I: Iterator>(I);
654 impl<I: Iterator> Iterator for Untrusted<I> {
655 type Item = I::Item;
656
657 fn next(&mut self) -> Option<Self::Item> {
658 self.0.next()
659 }
660 }
661 impl<I: DoubleEndedIterator> DoubleEndedIterator for Untrusted<I> {
662 fn next_back(&mut self) -> Option<Self::Item> {
663 self.0.next_back()
664 }
665 }
666 let mut it = Untrusted(0..12);
667 assert_eq!(it.next_chunk_back().unwrap(), [8, 9, 10, 11]);
668 assert_eq!(it.next_chunk_back().unwrap(), []);
669 assert_eq!(it.next_chunk_back().unwrap(), [2, 3, 4, 5, 6, 7]);
670 assert_eq!(it.next_chunk::<4>().unwrap_err().as_slice(), &[0, 1]);
671}
672
639673#[test]
640674fn test_collect_into_tuples() {
641675 let a = vec![(1, 2, 3), (4, 5, 6), (7, 8, 9)];
library/std/src/os/unix/process.rs+94-16
......@@ -7,6 +7,8 @@
77use crate::ffi::OsStr;
88use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
99use crate::path::Path;
10#[cfg(doc)]
11use crate::process::{ExitStatus, ExitStatusError};
1012use crate::sys::process::ChildPipe;
1113use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner};
1214use crate::{io, process, sys};
......@@ -272,35 +274,105 @@ impl CommandExt for process::Command {
272274 }
273275}
274276
275/// Unix-specific extensions to [`process::ExitStatus`] and
276/// [`ExitStatusError`](process::ExitStatusError).
277/// Unix-specific extensions to [`ExitStatus`] and [`ExitStatusError`].
277278///
278/// On Unix, `ExitStatus` **does not necessarily represent an exit status**, as
279/// On Unix, [`ExitStatus`] **does not necessarily represent an exit status**, as
279280/// passed to the `_exit` system call or returned by
280/// [`ExitStatus::code()`](crate::process::ExitStatus::code). It represents **any wait status**
281/// as returned by one of the `wait` family of system
281/// [`ExitStatus::code()`](ExitStatus::code). It represents **any wait status**
282/// as returned by one of the [`wait`] family of system
282283/// calls.
283284///
284/// A Unix wait status (a Rust `ExitStatus`) can represent a Unix exit status, but can also
285/// A Unix wait status (a Rust [`ExitStatus`]) can represent a Unix exit status, but can also
285286/// represent other kinds of process event.
287///
288/// [`wait`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html
286289#[stable(feature = "rust1", since = "1.0.0")]
287290pub impl(self) trait ExitStatusExt {
288 /// Creates a new `ExitStatus` or `ExitStatusError` from the raw underlying integer status
289 /// value from `wait`
291 /// Creates a new [`ExitStatus`] or [`ExitStatusError`] from the raw underlying integer status
292 /// value from [`wait`].
290293 ///
291294 /// The value should be a **wait status, not an exit status**.
292295 ///
296 /// # Example
297 ///
298 /// A signal-terminated [`wait`] status carries the signal number, which [`ExitStatus::signal`]
299 /// recovers using the platform's [`WTERMSIG`][`wait`] macro. Note that the bit layout of a
300 /// wait status is **not** specified by POSIX and is platform-specific. By convention on most
301 /// Unix platforms, the signal number occupies the low 7 bits with the exit-code byte left
302 /// zero, so a bare signal number between 1 and 126 is treated as a signal-terminated wait
303 /// status. The following example relies on that convention and is therefore not guaranteed to
304 /// hold on every target:
305 ///
306 /// ```
307 /// # if cfg!(target_os = "fuchsia") { return; }
308 /// use std::os::unix::process::ExitStatusExt;
309 /// use std::process::ExitStatus;
310 ///
311 /// let signal = 15; // SIGTERM
312 /// assert!(signal > 0 && signal < 0x7f, "not a valid Unix termination signal: {signal}");
313 ///
314 /// let status = ExitStatus::from_raw(signal);
315 /// assert!(!status.success());
316 /// assert_eq!(status.code(), None);
317 /// assert_eq!(status.signal(), Some(15));
318 /// ```
319 ///
320 /// Generating an [`ExitStatus`] with a given exit code (0-255) is system-dependent.
321 /// The value returned by [`ExitStatus::code`] is specified to come from applying the
322 /// [`WEXITSTATUS`][`wait`] macro, but there is no POSIX-specified constructor and the bit
323 /// layout is left unspecified. By near-universal convention every Unix libc stores the
324 /// 8-bit exit code in bits 8..16, so a status built with `(code & 0xff) << 8` will usually
325 /// round-trip back to the original exit code:
326 ///
327 /// ```
328 /// # if cfg!(target_os = "fuchsia") { return; }
329 /// use std::os::unix::process::ExitStatusExt;
330 /// use std::process::ExitStatus;
331 ///
332 /// let code = 41;
333 /// let status = ExitStatus::from_raw((code & 0xff) << 8);
334 /// assert_eq!(status.code(), Some(41));
335 /// assert!(!status.success());
336 /// ```
337 ///
293338 /// # Panics
294339 ///
295 /// Panics on an attempt to make an `ExitStatusError` from a wait status of `0`.
340 /// - `ExitStatusError::from_raw` panics on an attempt to make an [`ExitStatusError`] from a
341 /// [`wait`] status of `0`.
342 /// - `ExitStatus::from_raw` always succeeds and never panics.
296343 ///
297 /// Making an `ExitStatus` always succeeds and never panics.
344 /// [`wait`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html
298345 #[stable(feature = "exit_status_from", since = "1.12.0")]
299346 fn from_raw(raw: i32) -> Self;
300347
301348 /// If the process was terminated by a signal, returns that signal.
302349 ///
303 /// In other words, if `WIFSIGNALED`, this returns `WTERMSIG`.
350 /// In other words, if [`WIFSIGNALED`][`wait`], this returns [`WTERMSIG`][`wait`]. For such a status,
351 /// [`ExitStatus::code`] returns `None`:
352 ///
353 /// ```
354 /// # if cfg!(target_os = "fuchsia") { return; }
355 /// use std::os::unix::process::ExitStatusExt;
356 /// use std::process::ExitStatus;
357 ///
358 /// let sigterm = 15;
359 /// let status = ExitStatus::from_raw(sigterm);
360 /// assert_eq!(status.code(), None);
361 /// assert_eq!(status.signal(), Some(sigterm));
362 /// ```
363 ///
364 /// A process that receives a signal may catch and handle it, then exit normally with an
365 /// exit code. When that happens, `signal` returns `None`.
366 ///
367 /// Rust does not pass commands through a shell, such as `bash` and `sh`, but it
368 /// is possible to do so manually. When invoking a shell, the signal value indicates whether
369 /// the top-level shell itself received a terminating signal. If instead a command *within*
370 /// an invoked shell receives a terminating signal, many shells convert the signal number
371 /// into an exit code by adding 128. For example, a command run under `sh` that receives a
372 /// [`SIGTERM`] canonically causes the shell to report an exit code of `15 + 128`, i.e. `143`.
373 ///
374 /// [`SIGTERM`]: https://pubs.opengroup.org/onlinepubs/9799919799/utilities/kill.html
375 /// [`wait`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html
304376 #[stable(feature = "rust1", since = "1.0.0")]
305377 fn signal(&self) -> Option<i32>;
306378
......@@ -310,21 +382,27 @@ pub impl(self) trait ExitStatusExt {
310382
311383 /// If the process was stopped by a signal, returns that signal.
312384 ///
313 /// In other words, if `WIFSTOPPED`, this returns `WSTOPSIG`. This is only possible if the status came from
314 /// a `wait` system call which was passed `WUNTRACED`, and was then converted into an `ExitStatus`.
385 /// In other words, if [`WIFSTOPPED`][`wait`], this returns [`WSTOPSIG`][`wait`]. This is only possible if the status came from
386 /// a [`wait`] system call which was passed [`WUNTRACED`][`wait`], and was then converted into an [`ExitStatus`].
387 ///
388 /// [`wait`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html
315389 #[stable(feature = "unix_process_wait_more", since = "1.58.0")]
316390 fn stopped_signal(&self) -> Option<i32>;
317391
318392 /// Whether the process was continued from a stopped status.
319393 ///
320 /// Ie, `WIFCONTINUED`. This is only possible if the status came from a `wait` system call
321 /// which was passed `WCONTINUED`, and was then converted into an `ExitStatus`.
394 /// I.e. [`WIFCONTINUED`][`wait`]. This is only possible if the status came from a [`wait`] system call
395 /// which was passed [`WCONTINUED`][`wait`], and was then converted into an [`ExitStatus`].
396 ///
397 /// [`wait`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html
322398 #[stable(feature = "unix_process_wait_more", since = "1.58.0")]
323399 fn continued(&self) -> bool;
324400
325 /// Returns the underlying raw `wait` status.
401 /// Returns the underlying raw [`wait`] status.
326402 ///
327403 /// The returned integer is a **wait status, not an exit status**.
404 ///
405 /// [`wait`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html
328406 #[stable(feature = "unix_process_wait_more", since = "1.58.0")]
329407 fn into_raw(self) -> i32;
330408}
library/std/src/sys/env/sgx.rs+11-30
......@@ -1,54 +1,35 @@
1#![allow(implicit_provenance_casts)] // FIXME: this module systematically confuses pointers and integers
2
31pub use super::common::Env;
42use crate::collections::HashMap;
53use crate::ffi::{OsStr, OsString};
64use crate::io;
7use crate::sync::atomic::{Atomic, AtomicUsize, Ordering};
8use crate::sync::{Mutex, Once};
5use crate::sync::{Mutex, OnceLock};
6
7type EnvStore = Mutex<HashMap<OsString, OsString>>;
98
109// Specifying linkage/symbol name is solely to ensure a single instance between this crate and its unit tests
1110#[cfg_attr(test, linkage = "available_externally")]
1211#[unsafe(export_name = "_ZN16__rust_internals3std3sys3pal3sgx2os3ENVE")]
13static ENV: Atomic<usize> = AtomicUsize::new(0);
14// Specifying linkage/symbol name is solely to ensure a single instance between this crate and its unit tests
15#[cfg_attr(test, linkage = "available_externally")]
16#[unsafe(export_name = "_ZN16__rust_internals3std3sys3pal3sgx2os8ENV_INITE")]
17static ENV_INIT: Once = Once::new();
18type EnvStore = Mutex<HashMap<OsString, OsString>>;
19
20fn get_env_store() -> Option<&'static EnvStore> {
21 unsafe { (ENV.load(Ordering::Relaxed) as *const EnvStore).as_ref() }
22}
23
24fn create_env_store() -> &'static EnvStore {
25 ENV_INIT.call_once(|| {
26 ENV.store(Box::into_raw(Box::new(EnvStore::default())) as _, Ordering::Relaxed)
27 });
28 unsafe { &*(ENV.load(Ordering::Relaxed) as *const EnvStore) }
29}
12static ENV: OnceLock<EnvStore> = OnceLock::new();
3013
3114pub fn env() -> Env {
32 let clone_to_vec = |map: &HashMap<OsString, OsString>| -> Vec<_> {
33 map.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
34 };
35
36 let env = get_env_store().map(|env| clone_to_vec(&env.lock().unwrap())).unwrap_or_default();
15 let env = ENV
16 .get()
17 .map(|env| env.lock().unwrap().iter().map(|(k, v)| (k.clone(), v.clone())).collect())
18 .unwrap_or_default();
3719 Env::new(env)
3820}
3921
4022pub fn getenv(k: &OsStr) -> Option<OsString> {
41 get_env_store().and_then(|s| s.lock().unwrap().get(k).cloned())
23 ENV.get().and_then(|s| s.lock().unwrap().get(k).cloned())
4224}
4325
4426pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
45 let (k, v) = (k.to_owned(), v.to_owned());
46 create_env_store().lock().unwrap().insert(k, v);
27 ENV.get_or_init(|| EnvStore::default()).lock().unwrap().insert(k.to_owned(), v.to_owned());
4728 Ok(())
4829}
4930
5031pub unsafe fn unsetenv(k: &OsStr) -> io::Result<()> {
51 if let Some(env) = get_env_store() {
32 if let Some(env) = ENV.get() {
5233 env.lock().unwrap().remove(k);
5334 }
5435 Ok(())
src/doc/unstable-book/src/language-features/asm-experimental-reg.md+13
......@@ -12,6 +12,8 @@ This tracks support for additional registers in architectures where inline assem
1212
1313| Architecture | Register class | Registers | LLVM constraint code |
1414| ------------ | -------------- | --------- | -------------------- |
15| LoongArch | `vreg` | `$vr[0-31]` | `f` |
16| LoongArch | `xreg` | `$xr[0-31]` | `f` |
1517
1618## Register class supported types
1719
......@@ -20,11 +22,16 @@ This tracks support for additional registers in architectures where inline assem
2022| x86 | `xmm_reg` | `sse` | `i128` |
2123| x86 | `ymm_reg` | `avx` | `i128` |
2224| x86 | `zmm_reg` | `avx512f` | `i128` |
25| LoongArch | `vreg` | `lsx` | `f32`, `f64`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` |
26| LoongArch | `xreg` | `lasx` | `f32`, `f64`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2`, <br> `i8x32`, `i16x16`, `i32x8`, `i64x4`, `f32x8`, `f64x4` |
2327
2428## Register aliases
2529
2630| Architecture | Base register | Aliases |
2731| ------------ | ------------- | ------- |
32| LoongArch | `$f[0-7]` | `$fa[0-7]`, `$vr[0-7]`, `$xr[0-7]` |
33| LoongArch | `$f[8-23]` | `$ft[0-15]`, `$vr[8-23]`, `$xr[8-23]` |
34| LoongArch | `$f[24-31]` | `$fs[0-7]`, `$vr[24-31]`, `$xr[24-31]` |
2835
2936## Unsupported registers
3037
......@@ -35,3 +42,9 @@ This tracks support for additional registers in architectures where inline assem
3542
3643| Architecture | Register class | Modifier | Example output | LLVM modifier |
3744| ------------ | -------------- | -------- | -------------- | ------------- |
45| LoongArch | `freg` | `w` | `$vr0` | `w` |
46| LoongArch | `freg` | `u` | `$xr0` | `u` |
47| LoongArch | `vreg` | None | `$vr0` | `w` |
48| LoongArch | `vreg` | `u` | `$xr0` | `u` |
49| LoongArch | `xreg` | None | `$xr0` | `u` |
50| LoongArch | `xreg` | `w` | `$vr0` | `w` |
src/librustdoc/clean/utils.rs+14-21
......@@ -350,28 +350,21 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
350350
351351pub(crate) fn print_const(tcx: TyCtxt<'_>, n: ty::Const<'_>) -> String {
352352 match n.kind() {
353 ty::ConstKind::Alias(_, ty::AliasConst { kind, .. }) => match kind {
354 ty::AliasConstKind::Projection { def_id } => {
355 if let Some(local_def_id) = def_id.as_local()
356 && let Some(body_id) = tcx.hir_maybe_body_owned_by(local_def_id)
357 {
358 rendered_const(tcx, body_id, local_def_id)
359 } else {
360 n.to_string()
361 }
362 }
363 ty::AliasConstKind::Inherent { def_id }
364 | ty::AliasConstKind::Free { def_id }
365 | ty::AliasConstKind::Anon { def_id } => {
366 if let Some(local_def_id) = def_id.as_local()
367 && let Some(body_id) = tcx.hir_maybe_body_owned_by(local_def_id)
368 {
369 rendered_const(tcx, body_id, local_def_id)
370 } else {
371 inline::print_inlined_const(tcx, def_id)
372 }
353 ty::ConstKind::Alias(_, ty::AliasConst { kind, .. }) => {
354 let def_id: DefId = match kind {
355 ty::AliasConstKind::Projection { def_id } => def_id.into(),
356 ty::AliasConstKind::Inherent { def_id } => def_id.into(),
357 ty::AliasConstKind::Free { def_id } => def_id.into(),
358 ty::AliasConstKind::Anon { def_id } => def_id.into(),
359 };
360 if let Some(local_def_id) = def_id.as_local()
361 && let Some(body_id) = tcx.hir_maybe_body_owned_by(local_def_id)
362 {
363 rendered_const(tcx, body_id, local_def_id)
364 } else {
365 n.to_string()
373366 }
374 },
367 }
375368 // array lengths are obviously usize
376369 ty::ConstKind::Value(cv) if *cv.ty.kind() == ty::Uint(ty::UintTy::Usize) => {
377370 cv.to_leaf().to_string()
tests/assembly-llvm/asm/loongarch-modifiers.rs created+225
......@@ -0,0 +1,225 @@
1//@ add-minicore
2//@ revisions: loongarch32 loongarch64
3
4//@ assembly-output: emit-asm
5//@ needs-llvm-components: loongarch
6
7//@[loongarch32] compile-flags: --target loongarch32-unknown-none
8//@[loongarch32] compile-flags: -Ctarget-feature=+32s,+lasx
9
10//@[loongarch64] compile-flags: --target loongarch64-unknown-none
11//@[loongarch64] compile-flags: -Ctarget-feature=+lasx
12
13//@ compile-flags: -Ctarget-feature=+32s
14//@ compile-flags: -Zmerge-functions=disabled
15
16#![feature(asm_experimental_reg, no_core, repr_simd)]
17#![crate_type = "rlib"]
18#![no_core]
19#![allow(asm_sub_register)]
20
21extern crate minicore;
22use minicore::*;
23
24#[repr(simd)]
25pub struct i8x16([i8; 16]);
26#[repr(simd)]
27pub struct i16x8([i16; 8]);
28#[repr(simd)]
29pub struct i32x4([i32; 4]);
30#[repr(simd)]
31pub struct i64x2([i64; 2]);
32#[repr(simd)]
33pub struct f32x4([f32; 4]);
34#[repr(simd)]
35pub struct f64x2([f64; 2]);
36#[repr(simd)]
37pub struct i8x32([i8; 32]);
38#[repr(simd)]
39pub struct i16x16([i16; 16]);
40#[repr(simd)]
41pub struct i32x8([i32; 8]);
42#[repr(simd)]
43pub struct i64x4([i64; 4]);
44#[repr(simd)]
45pub struct f32x8([f32; 8]);
46#[repr(simd)]
47pub struct f64x4([f64; 4]);
48
49impl Copy for i8x16 {}
50impl Copy for i16x8 {}
51impl Copy for i32x4 {}
52impl Copy for i64x2 {}
53impl Copy for f32x4 {}
54impl Copy for f64x2 {}
55impl Copy for i8x32 {}
56impl Copy for i16x16 {}
57impl Copy for i32x8 {}
58impl Copy for i64x4 {}
59impl Copy for f32x8 {}
60impl Copy for f64x4 {}
61
62macro_rules! check { ($func:ident, $ty:ty, $class:ident, $code:literal) => {
63 #[no_mangle]
64 pub unsafe fn $func(x: $ty) -> $ty {
65 let y;
66 asm!($code, out($class) y, in($class) x);
67 y
68 }
69};}
70
71// CHECK-LABEL: freg_f32_lsx:
72// CHECK: #APP
73// CHECK: vfadd.s $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}
74// CHECK: #NO_APP
75check!(freg_f32_lsx, f32, freg, "vfadd.s {1:w}, {0:w}, {0:w}");
76
77// CHECK-LABEL: freg_f64_lasx:
78// CHECK: #APP
79// CHECK: xvfadd.d $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}
80// CHECK: #NO_APP
81check!(freg_f64_lasx, f64, freg, "xvfadd.d {1:u}, {0:u}, {0:u}");
82
83// CHECK-LABEL: vreg_i8x16_lsx:
84// CHECK: #APP
85// CHECK: vadd.b $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}
86// CHECK: #NO_APP
87check!(vreg_i8x16_lsx, i8x16, vreg, "vadd.b {1}, {0}, {0}");
88
89// CHECK-LABEL: vreg_i8x16_lasx:
90// CHECK: #APP
91// CHECK: xvadd.b $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}
92// CHECK: #NO_APP
93check!(vreg_i8x16_lasx, i8x16, vreg, "xvadd.b {1:u}, {0:u}, {0:u}");
94
95// CHECK-LABEL: vreg_i16x8_lsx:
96// CHECK: #APP
97// CHECK: vadd.h $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}
98// CHECK: #NO_APP
99check!(vreg_i16x8_lsx, i16x8, vreg, "vadd.h {1}, {0}, {0}");
100
101// CHECK-LABEL: vreg_i16x8_lasx:
102// CHECK: #APP
103// CHECK: xvadd.h $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}
104// CHECK: #NO_APP
105check!(vreg_i16x8_lasx, i16x8, vreg, "xvadd.h {1:u}, {0:u}, {0:u}");
106
107// CHECK-LABEL: vreg_i32x4_lsx:
108// CHECK: #APP
109// CHECK: vadd.w $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}
110// CHECK: #NO_APP
111check!(vreg_i32x4_lsx, i32x4, vreg, "vadd.w {1}, {0}, {0}");
112
113// CHECK-LABEL: vreg_i32x4_lasx:
114// CHECK: #APP
115// CHECK: xvadd.w $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}
116// CHECK: #NO_APP
117check!(vreg_i32x4_lasx, i32x4, vreg, "xvadd.w {1:u}, {0:u}, {0:u}");
118
119// CHECK-LABEL: vreg_i64x2_lsx:
120// CHECK: #APP
121// CHECK: vadd.d $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}
122// CHECK: #NO_APP
123check!(vreg_i64x2_lsx, i64x2, vreg, "vadd.d {1}, {0}, {0}");
124
125// CHECK-LABEL: vreg_i64x2_lasx:
126// CHECK: #APP
127// CHECK: xvadd.d $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}
128// CHECK: #NO_APP
129check!(vreg_i64x2_lasx, i64x2, vreg, "xvadd.d {1:u}, {0:u}, {0:u}");
130
131// CHECK-LABEL: vreg_f32x4_lsx:
132// CHECK: #APP
133// CHECK: vfadd.s $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}
134// CHECK: #NO_APP
135check!(vreg_f32x4_lsx, f32x4, vreg, "vfadd.s {1}, {0}, {0}");
136
137// CHECK-LABEL: vreg_f32x4_lasx:
138// CHECK: #APP
139// CHECK: xvfadd.s $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}
140// CHECK: #NO_APP
141check!(vreg_f32x4_lasx, f32x4, vreg, "xvfadd.s {1:u}, {0:u}, {0:u}");
142
143// CHECK-LABEL: vreg_f64x2_lsx:
144// CHECK: #APP
145// CHECK: vfadd.d $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}
146// CHECK: #NO_APP
147check!(vreg_f64x2_lsx, f64x2, vreg, "vfadd.d {1}, {0}, {0}");
148
149// CHECK-LABEL: vreg_f64x2_lasx:
150// CHECK: #APP
151// CHECK: xvfadd.d $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}
152// CHECK: #NO_APP
153check!(vreg_f64x2_lasx, f64x2, vreg, "xvfadd.d {1:u}, {0:u}, {0:u}");
154
155// CHECK-LABEL: xreg_i8x32_lasx:
156// CHECK: #APP
157// CHECK: xvadd.b $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}
158// CHECK: #NO_APP
159check!(xreg_i8x32_lasx, i8x32, xreg, "xvadd.b {1}, {0}, {0}");
160
161// CHECK-LABEL: xreg_i8x32_lsx:
162// CHECK: #APP
163// CHECK: vadd.b $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}
164// CHECK: #NO_APP
165check!(xreg_i8x32_lsx, i8x32, xreg, "vadd.b {1:w}, {0:w}, {0:w}");
166
167// CHECK-LABEL: xreg_i16x16_lasx:
168// CHECK: #APP
169// CHECK: xvadd.h $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}
170// CHECK: #NO_APP
171check!(xreg_i16x16_lasx, i16x16, xreg, "xvadd.h {1}, {0}, {0}");
172
173// CHECK-LABEL: xreg_i16x16_lsx:
174// CHECK: #APP
175// CHECK: vadd.h $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}
176// CHECK: #NO_APP
177check!(xreg_i16x16_lsx, i16x16, xreg, "vadd.h {1:w}, {0:w}, {0:w}");
178
179// CHECK-LABEL: xreg_i32x8_lasx:
180// CHECK: #APP
181// CHECK: xvadd.w $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}
182// CHECK: #NO_APP
183check!(xreg_i32x8_lasx, i32x8, xreg, "xvadd.w {1}, {0}, {0}");
184
185// CHECK-LABEL: xreg_i32x8_lsx:
186// CHECK: #APP
187// CHECK: vadd.w $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}
188// CHECK: #NO_APP
189check!(xreg_i32x8_lsx, i32x8, xreg, "vadd.w {1:w}, {0:w}, {0:w}");
190
191// CHECK-LABEL: xreg_i64x4_lasx:
192// CHECK: #APP
193// CHECK: xvadd.d $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}
194// CHECK: #NO_APP
195check!(xreg_i64x4_lasx, i64x4, xreg, "xvadd.d {1}, {0}, {0}");
196
197// CHECK-LABEL: xreg_i64x4_lsx:
198// CHECK: #APP
199// CHECK: vadd.d $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}
200// CHECK: #NO_APP
201check!(xreg_i64x4_lsx, i64x4, xreg, "vadd.d {1:w}, {0:w}, {0:w}");
202
203// CHECK-LABEL: xreg_f32x8_lasx:
204// CHECK: #APP
205// CHECK: xvfadd.s $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}
206// CHECK: #NO_APP
207check!(xreg_f32x8_lasx, f32x8, xreg, "xvfadd.s {1}, {0}, {0}");
208
209// CHECK-LABEL: xreg_f32x8_lsx:
210// CHECK: #APP
211// CHECK: vfadd.s $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}
212// CHECK: #NO_APP
213check!(xreg_f32x8_lsx, f32x8, xreg, "vfadd.s {1:w}, {0:w}, {0:w}");
214
215// CHECK-LABEL: xreg_f64x4_lasx:
216// CHECK: #APP
217// CHECK: xvfadd.d $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}, $xr{{[a-z0-9]+}}
218// CHECK: #NO_APP
219check!(xreg_f64x4_lasx, f64x4, xreg, "xvfadd.d {1}, {0}, {0}");
220
221// CHECK-LABEL: xreg_f64x4_lsx:
222// CHECK: #APP
223// CHECK: vfadd.d $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}, $vr{{[a-z0-9]+}}
224// CHECK: #NO_APP
225check!(xreg_f64x4_lsx, f64x4, xreg, "vfadd.d {1:w}, {0:w}, {0:w}");
tests/codegen-llvm/read_write_unaligned.rs created+71
......@@ -0,0 +1,71 @@
1//@ compile-flags: -Copt-level=3
2//@ only-64bit
3
4#![crate_type = "lib"]
5
6use std::num::NonZero;
7use std::ptr::NonNull;
8
9// CHECK-LABEL: nonnull ptr @read_unaligned_ptr(ptr{{.+}}%ptr)
10#[no_mangle]
11unsafe fn read_unaligned_ptr(ptr: *const NonNull<i16>) -> NonNull<i16> {
12 // CHECK: start:
13 // CHECK-NEXT: [[TEMP:%.+]] = load ptr, ptr %ptr, align 1
14 // CHECK-SAME: !nonnull
15 // CHECK-SAME: !noundef
16 // CHECK-NEXT: ret ptr [[TEMP]]
17 ptr.read_unaligned()
18}
19
20// CHECK-LABEL: range(i16 1, 0) i16 @read_unaligned_i16(ptr{{.+}}%ptr)
21#[no_mangle]
22unsafe fn read_unaligned_i16(ptr: *const NonZero<i16>) -> NonZero<i16> {
23 // CHECK: start:
24 // CHECK-NEXT: [[TEMP:%.+]] = load i16, ptr %ptr, align 1
25 // CHECK-NOT: !noundef
26 // CHECK-NOT: !range
27 // CHECK-NEXT: ret i16 [[TEMP]]
28 ptr.read_unaligned()
29}
30
31// CHECK-LABEL: void @typed_copy_unaligned_i32(ptr{{.+}}%src, ptr{{.+}}%dst)
32#[no_mangle]
33unsafe fn typed_copy_unaligned_i32(src: *const NonZero<i32>, dst: *mut NonZero<i32>) {
34 // CHECK: start:
35 // CHECK-NEXT: [[TEMP:%.+]] = load i32, ptr %src, align 1
36 // CHECK-NOT: !noundef
37 // CHECK-NOT: !range
38 // CHECK-NEXT: store i32 [[TEMP]], ptr %dst, align 1
39 // CHECK-NEXT: ret void
40 dst.write_unaligned(src.read_unaligned())
41}
42
43// CHECK-LABEL: void @write_unaligned_i64(ptr{{.+}}%ptr, i64{{.+}}%val)
44#[no_mangle]
45unsafe fn write_unaligned_i64(ptr: *mut NonZero<i64>, val: NonZero<i64>) {
46 // CHECK: start:
47 // CHECK-NEXT: store i64 %val, ptr %ptr, align 1
48 // CHECK-NEXT: ret void
49 ptr.write_unaligned(val)
50}
51
52#[repr(align(128))]
53struct HugeBuffer([u64; 1 << 10]);
54
55// CHECK-LABEL: void @read_unaligned_huge(ptr{{.+}}%_0, ptr{{.+}}%ptr)
56#[no_mangle]
57unsafe fn read_unaligned_huge(ptr: *const HugeBuffer) -> HugeBuffer {
58 // CHECK: start:
59 // CHECK-NEXT: call void @llvm.memcpy{{.+}} align 128 dereferenceable(8192) %_0, {{.+}} align 1 dereferenceable(8192) %ptr, i64 8192,
60 // CHECK-NEXT: ret void
61 ptr.read_unaligned()
62}
63
64// CHECK-LABEL: void @write_unaligned_huge(ptr{{.+}}%ptr, ptr{{.+}}%val)
65#[no_mangle]
66unsafe fn write_unaligned_huge(ptr: *mut HugeBuffer, val: HugeBuffer) {
67 // CHECK: start:
68 // CHECK-NEXT: call void @llvm.memcpy{{.+}} align 1 dereferenceable(8192) %ptr, {{.+}} align 128 dereferenceable(8192) %val, i64 8192,
69 // CHECK-NEXT: ret void
70 ptr.write_unaligned(val)
71}
tests/mir-opt/pre-codegen/unaligned.rs created+39
......@@ -0,0 +1,39 @@
1//@ compile-flags: -O -Zmir-opt-level=2
2//@ ignore-std-debug-assertions (there's one in `ptr::read`)
3
4#![crate_type = "lib"]
5
6// EMIT_MIR unaligned.unaligned_copy_manual.runtime-optimized.after.mir
7pub unsafe fn unaligned_copy_manual(src: *const u128, dst: *mut u128) {
8 #[repr(packed)]
9 struct Packed<T>(T);
10
11 // CHECK-LABEL: fn unaligned_copy_manual(_1: *const u128, _2: *mut u128) -> ()
12 // CHECK: [[SRCU:_.+]] = copy _1 as *const unaligned_copy_manual::Packed<u128> (PtrToPtr);
13 // CHECK: [[DSTU:_.+]] = copy _2 as *mut unaligned_copy_manual::Packed<u128> (PtrToPtr);
14 // CHECK: [[TEMP:_.+]] = copy ((*[[SRCU]]).0: u128);
15 // ((*[[DSTU]]).0: u128) = move [[TEMP]];
16 let src = src.cast::<Packed<u128>>();
17 let dst = dst.cast::<Packed<u128>>();
18 unsafe { (*dst).0 = (*src).0 };
19}
20
21// EMIT_MIR unaligned.unaligned_copy_generic.runtime-optimized.after.mir
22pub unsafe fn unaligned_copy_generic<T>(src: *const T, dst: *mut T) {
23 // CHECK-LABEL: fn unaligned_copy_generic(
24 // CHECK: debug src => _1;
25 // CHECK: debug dst => _2;
26 // CHECK: debug val => [[VAL:_.+]];
27 // CHECK: [[SRC_P:_.+]] = copy _1 as *const {{.+}}::Packed<T> (PtrToPtr);
28 // CHECK: [[PACKED1:_.+]] = copy (*[[SRC_P]]);
29 // CHECK: [[VAL]] = copy [[PACKED1]] as T (Transmute);
30 // CHECK: [[DST_P:_.+]] = copy _2 as *mut {{.+}}::Packed<T> (PtrToPtr);
31 // CHECK: [[PACKED2:_.+]] = {{.+}}::Packed::<T>(copy [[VAL]]);
32 // CHECK: (*[[DST_P]]) = copy [[PACKED2]];
33 // CHECK-NOT: copy_nonoverlapping
34 // CHECK-NOT: drop
35 unsafe {
36 let val = std::ptr::read_unaligned(src);
37 std::ptr::write_unaligned(dst, val);
38 }
39}
tests/mir-opt/pre-codegen/unaligned.unaligned_copy_generic.runtime-optimized.after.mir created+57
......@@ -0,0 +1,57 @@
1// MIR for `unaligned_copy_generic` after runtime-optimized
2
3fn unaligned_copy_generic(_1: *const T, _2: *mut T) -> () {
4 debug src => _1;
5 debug dst => _2;
6 let mut _0: ();
7 let _5: T;
8 scope 1 {
9 debug val => _5;
10 scope 8 (inlined #[track_caller] write_unaligned::<T>) {
11 let _6: *mut std::ptr::Packed<T>;
12 scope 9 {
13 let _7: std::ptr::Packed<T>;
14 scope 10 {
15 scope 12 (inlined #[track_caller] std::ptr::write::<std::ptr::Packed<T>>) {
16 }
17 }
18 }
19 scope 11 (inlined std::ptr::mut_ptr::<impl *mut T>::cast::<std::ptr::Packed<T>>) {
20 }
21 }
22 }
23 scope 2 (inlined #[track_caller] read_unaligned::<T>) {
24 let _3: *const std::ptr::Packed<T>;
25 scope 3 {
26 let _4: std::ptr::Packed<T>;
27 scope 4 {
28 scope 7 (inlined transmute_neo::<std::ptr::Packed<T>, T>) {
29 }
30 }
31 scope 6 (inlined #[track_caller] std::ptr::read::<std::ptr::Packed<T>>) {
32 }
33 }
34 scope 5 (inlined std::ptr::const_ptr::<impl *const T>::cast::<std::ptr::Packed<T>>) {
35 }
36 }
37
38 bb0: {
39 StorageLive(_5);
40 StorageLive(_3);
41 _3 = copy _1 as *const std::ptr::Packed<T> (PtrToPtr);
42 StorageLive(_4);
43 _4 = copy (*_3);
44 _5 = copy _4 as T (Transmute);
45 StorageDead(_4);
46 StorageDead(_3);
47 StorageLive(_6);
48 _6 = copy _2 as *mut std::ptr::Packed<T> (PtrToPtr);
49 StorageLive(_7);
50 _7 = std::ptr::Packed::<T>(copy _5);
51 (*_6) = copy _7;
52 StorageDead(_7);
53 StorageDead(_6);
54 StorageDead(_5);
55 return;
56 }
57}
tests/mir-opt/pre-codegen/unaligned.unaligned_copy_manual.runtime-optimized.after.mir created+34
......@@ -0,0 +1,34 @@
1// MIR for `unaligned_copy_manual` after runtime-optimized
2
3fn unaligned_copy_manual(_1: *const u128, _2: *mut u128) -> () {
4 debug src => _1;
5 debug dst => _2;
6 let mut _0: ();
7 let _3: *const unaligned_copy_manual::Packed<u128>;
8 let mut _5: u128;
9 scope 1 {
10 debug src => _3;
11 let _4: *mut unaligned_copy_manual::Packed<u128>;
12 scope 2 {
13 debug dst => _4;
14 }
15 scope 4 (inlined std::ptr::mut_ptr::<impl *mut u128>::cast::<Packed<u128>>) {
16 }
17 }
18 scope 3 (inlined std::ptr::const_ptr::<impl *const u128>::cast::<Packed<u128>>) {
19 }
20
21 bb0: {
22 StorageLive(_3);
23 _3 = copy _1 as *const unaligned_copy_manual::Packed<u128> (PtrToPtr);
24 StorageLive(_4);
25 _4 = copy _2 as *mut unaligned_copy_manual::Packed<u128> (PtrToPtr);
26 StorageLive(_5);
27 _5 = copy ((*_3).0: u128);
28 ((*_4).0: u128) = move _5;
29 StorageDead(_5);
30 StorageDead(_4);
31 StorageDead(_3);
32 return;
33 }
34}
tests/rustdoc-html/type-const-free-in-array.rs created+11
......@@ -0,0 +1,11 @@
1#![crate_name = "foo"]
2#![feature(min_generic_const_args)]
3#![expect(incomplete_features)]
4
5type const N: usize = 2;
6
7//@ has 'foo/trait.CollectArray.html'
8//@ has - '//pre[@class="rust item-decl"]/code' '[A; N]'
9pub trait CollectArray<A> {
10 fn inner_array(&mut self) -> [A; N];
11}
tests/rustdoc-html/type-const-inherent-with-body.rs created+15
......@@ -0,0 +1,15 @@
1#![crate_name = "foo"]
2#![feature(min_generic_const_args, inherent_associated_types)]
3#![expect(incomplete_features)]
4
5pub struct Foo;
6
7impl Foo {
8 type const LEN: usize = 4;
9}
10
11//@ has 'foo/fn.mk_array.html'
12//@ has - '//pre[@class="rust item-decl"]/code' '[u8; Foo::LEN]'
13pub fn mk_array() -> [u8; Foo::LEN] {
14 [0u8; Foo::LEN]
15}
tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32d.stderr+228-7
......@@ -1,38 +1,259 @@
11error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
2 --> $DIR/bad-reg.rs:26:18
2 --> $DIR/bad-reg.rs:28:18
33 |
44LL | asm!("", out("$r0") _);
55 | ^^^^^^^^^^^^
66
77error: invalid register `$tp`: reserved for TLS
8 --> $DIR/bad-reg.rs:28:18
8 --> $DIR/bad-reg.rs:30:18
99 |
1010LL | asm!("", out("$tp") _);
1111 | ^^^^^^^^^^^^
1212
1313error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
14 --> $DIR/bad-reg.rs:30:18
14 --> $DIR/bad-reg.rs:32:18
1515 |
1616LL | asm!("", out("$sp") _);
1717 | ^^^^^^^^^^^^
1818
1919error: invalid register `$r21`: reserved by the ABI
20 --> $DIR/bad-reg.rs:32:18
20 --> $DIR/bad-reg.rs:34:18
2121 |
2222LL | asm!("", out("$r21") _);
2323 | ^^^^^^^^^^^^^
2424
2525error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
26 --> $DIR/bad-reg.rs:34:18
26 --> $DIR/bad-reg.rs:36:18
2727 |
2828LL | asm!("", out("$fp") _);
2929 | ^^^^^^^^^^^^
3030
3131error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
32 --> $DIR/bad-reg.rs:36:18
32 --> $DIR/bad-reg.rs:38:18
3333 |
3434LL | asm!("", out("$r31") _);
3535 | ^^^^^^^^^^^^^
3636
37error: aborting due to 6 previous errors
37error[E0658]: register class `vreg` can only be used as a clobber in stable
38 --> $DIR/bad-reg.rs:52:26
39 |
40LL | asm!("/* {} */", in(vreg) f);
41 | ^^^^^^^^^^
42 |
43 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
44 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
45 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
46
47error[E0658]: register class `vreg` can only be used as a clobber in stable
48 --> $DIR/bad-reg.rs:55:26
49 |
50LL | asm!("/* {} */", out(vreg) _);
51 | ^^^^^^^^^^^
52 |
53 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
54 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
55 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
56
57error[E0658]: register class `vreg` can only be used as a clobber in stable
58 --> $DIR/bad-reg.rs:57:26
59 |
60LL | asm!("/* {} */", in(vreg) d);
61 | ^^^^^^^^^^
62 |
63 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
64 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
65 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
66
67error[E0658]: register class `vreg` can only be used as a clobber in stable
68 --> $DIR/bad-reg.rs:60:26
69 |
70LL | asm!("/* {} */", out(vreg) d);
71 | ^^^^^^^^^^^
72 |
73 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
74 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
75 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
76
77error[E0658]: register class `xreg` can only be used as a clobber in stable
78 --> $DIR/bad-reg.rs:65:26
79 |
80LL | asm!("/* {} */", in(xreg) f);
81 | ^^^^^^^^^^
82 |
83 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
84 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
85 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
86
87error[E0658]: register class `xreg` can only be used as a clobber in stable
88 --> $DIR/bad-reg.rs:68:26
89 |
90LL | asm!("/* {} */", out(xreg) _);
91 | ^^^^^^^^^^^
92 |
93 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
94 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
95 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
96
97error[E0658]: register class `xreg` can only be used as a clobber in stable
98 --> $DIR/bad-reg.rs:70:26
99 |
100LL | asm!("/* {} */", in(xreg) d);
101 | ^^^^^^^^^^
102 |
103 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
104 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
105 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
106
107error[E0658]: register class `xreg` can only be used as a clobber in stable
108 --> $DIR/bad-reg.rs:73:26
109 |
110LL | asm!("/* {} */", out(xreg) d);
111 | ^^^^^^^^^^^
112 |
113 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
114 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
115 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
116
117error[E0658]: register class `vreg` can only be used as a clobber in stable
118 --> $DIR/bad-reg.rs:77:31
119 |
120LL | asm!("", in("$f0") f, in("$vr0") d);
121 | ^^^^^^^^^^^^
122 |
123 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
124 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
125 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
126
127error[E0658]: register class `xreg` can only be used as a clobber in stable
128 --> $DIR/bad-reg.rs:82:31
129 |
130LL | asm!("", in("$f0") f, in("$xr0") d);
131 | ^^^^^^^^^^^^
132 |
133 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
134 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
135 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
136
137error[E0658]: register class `vreg` can only be used as a clobber in stable
138 --> $DIR/bad-reg.rs:87:18
139 |
140LL | asm!("", in("$vr0") f, in("$xr0") d);
141 | ^^^^^^^^^^^^
142 |
143 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
144 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
145 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
146
147error[E0658]: register class `xreg` can only be used as a clobber in stable
148 --> $DIR/bad-reg.rs:87:32
149 |
150LL | asm!("", in("$vr0") f, in("$xr0") d);
151 | ^^^^^^^^^^^^
152 |
153 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
154 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
155 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
156
157error[E0658]: type `f32` cannot be used with this register class in stable
158 --> $DIR/bad-reg.rs:52:35
159 |
160LL | asm!("/* {} */", in(vreg) f);
161 | ^
162 |
163 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
164 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
165 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
166
167error[E0658]: type `f64` cannot be used with this register class in stable
168 --> $DIR/bad-reg.rs:57:35
169 |
170LL | asm!("/* {} */", in(vreg) d);
171 | ^
172 |
173 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
174 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
175 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
176
177error[E0658]: type `f64` cannot be used with this register class in stable
178 --> $DIR/bad-reg.rs:60:36
179 |
180LL | asm!("/* {} */", out(vreg) d);
181 | ^
182 |
183 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
184 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
185 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
186
187error[E0658]: type `f32` cannot be used with this register class in stable
188 --> $DIR/bad-reg.rs:65:35
189 |
190LL | asm!("/* {} */", in(xreg) f);
191 | ^
192 |
193 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
194 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
195 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
196
197error[E0658]: type `f64` cannot be used with this register class in stable
198 --> $DIR/bad-reg.rs:70:35
199 |
200LL | asm!("/* {} */", in(xreg) d);
201 | ^
202 |
203 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
204 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
205 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
206
207error[E0658]: type `f64` cannot be used with this register class in stable
208 --> $DIR/bad-reg.rs:73:36
209 |
210LL | asm!("/* {} */", out(xreg) d);
211 | ^
212 |
213 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
214 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
215 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
216
217error[E0658]: type `f64` cannot be used with this register class in stable
218 --> $DIR/bad-reg.rs:77:42
219 |
220LL | asm!("", in("$f0") f, in("$vr0") d);
221 | ^
222 |
223 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
224 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
225 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
226
227error[E0658]: type `f64` cannot be used with this register class in stable
228 --> $DIR/bad-reg.rs:82:42
229 |
230LL | asm!("", in("$f0") f, in("$xr0") d);
231 | ^
232 |
233 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
234 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
235 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
236
237error[E0658]: type `f32` cannot be used with this register class in stable
238 --> $DIR/bad-reg.rs:87:29
239 |
240LL | asm!("", in("$vr0") f, in("$xr0") d);
241 | ^
242 |
243 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
244 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
245 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
246
247error[E0658]: type `f64` cannot be used with this register class in stable
248 --> $DIR/bad-reg.rs:87:43
249 |
250LL | asm!("", in("$vr0") f, in("$xr0") d);
251 | ^
252 |
253 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
254 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
255 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
256
257error: aborting due to 28 previous errors
38258
259For more information about this error, try `rustc --explain E0658`.
tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32s.stderr+244-11
......@@ -1,62 +1,295 @@
11error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
2 --> $DIR/bad-reg.rs:26:18
2 --> $DIR/bad-reg.rs:28:18
33 |
44LL | asm!("", out("$r0") _);
55 | ^^^^^^^^^^^^
66
77error: invalid register `$tp`: reserved for TLS
8 --> $DIR/bad-reg.rs:28:18
8 --> $DIR/bad-reg.rs:30:18
99 |
1010LL | asm!("", out("$tp") _);
1111 | ^^^^^^^^^^^^
1212
1313error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
14 --> $DIR/bad-reg.rs:30:18
14 --> $DIR/bad-reg.rs:32:18
1515 |
1616LL | asm!("", out("$sp") _);
1717 | ^^^^^^^^^^^^
1818
1919error: invalid register `$r21`: reserved by the ABI
20 --> $DIR/bad-reg.rs:32:18
20 --> $DIR/bad-reg.rs:34:18
2121 |
2222LL | asm!("", out("$r21") _);
2323 | ^^^^^^^^^^^^^
2424
2525error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
26 --> $DIR/bad-reg.rs:34:18
26 --> $DIR/bad-reg.rs:36:18
2727 |
2828LL | asm!("", out("$fp") _);
2929 | ^^^^^^^^^^^^
3030
3131error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
32 --> $DIR/bad-reg.rs:36:18
32 --> $DIR/bad-reg.rs:38:18
3333 |
3434LL | asm!("", out("$r31") _);
3535 | ^^^^^^^^^^^^^
3636
37error[E0658]: register class `vreg` can only be used as a clobber in stable
38 --> $DIR/bad-reg.rs:52:26
39 |
40LL | asm!("/* {} */", in(vreg) f);
41 | ^^^^^^^^^^
42 |
43 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
44 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
45 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
46
47error[E0658]: register class `vreg` can only be used as a clobber in stable
48 --> $DIR/bad-reg.rs:55:26
49 |
50LL | asm!("/* {} */", out(vreg) _);
51 | ^^^^^^^^^^^
52 |
53 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
54 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
55 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
56
57error[E0658]: register class `vreg` can only be used as a clobber in stable
58 --> $DIR/bad-reg.rs:57:26
59 |
60LL | asm!("/* {} */", in(vreg) d);
61 | ^^^^^^^^^^
62 |
63 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
64 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
65 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
66
67error[E0658]: register class `vreg` can only be used as a clobber in stable
68 --> $DIR/bad-reg.rs:60:26
69 |
70LL | asm!("/* {} */", out(vreg) d);
71 | ^^^^^^^^^^^
72 |
73 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
74 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
75 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
76
77error[E0658]: register class `xreg` can only be used as a clobber in stable
78 --> $DIR/bad-reg.rs:65:26
79 |
80LL | asm!("/* {} */", in(xreg) f);
81 | ^^^^^^^^^^
82 |
83 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
84 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
85 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
86
87error[E0658]: register class `xreg` can only be used as a clobber in stable
88 --> $DIR/bad-reg.rs:68:26
89 |
90LL | asm!("/* {} */", out(xreg) _);
91 | ^^^^^^^^^^^
92 |
93 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
94 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
95 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
96
97error[E0658]: register class `xreg` can only be used as a clobber in stable
98 --> $DIR/bad-reg.rs:70:26
99 |
100LL | asm!("/* {} */", in(xreg) d);
101 | ^^^^^^^^^^
102 |
103 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
104 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
105 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
106
107error[E0658]: register class `xreg` can only be used as a clobber in stable
108 --> $DIR/bad-reg.rs:73:26
109 |
110LL | asm!("/* {} */", out(xreg) d);
111 | ^^^^^^^^^^^
112 |
113 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
114 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
115 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
116
117error[E0658]: register class `vreg` can only be used as a clobber in stable
118 --> $DIR/bad-reg.rs:77:31
119 |
120LL | asm!("", in("$f0") f, in("$vr0") d);
121 | ^^^^^^^^^^^^
122 |
123 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
124 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
125 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
126
127error[E0658]: register class `xreg` can only be used as a clobber in stable
128 --> $DIR/bad-reg.rs:82:31
129 |
130LL | asm!("", in("$f0") f, in("$xr0") d);
131 | ^^^^^^^^^^^^
132 |
133 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
134 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
135 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
136
137error[E0658]: register class `vreg` can only be used as a clobber in stable
138 --> $DIR/bad-reg.rs:87:18
139 |
140LL | asm!("", in("$vr0") f, in("$xr0") d);
141 | ^^^^^^^^^^^^
142 |
143 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
144 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
145 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
146
147error[E0658]: register class `xreg` can only be used as a clobber in stable
148 --> $DIR/bad-reg.rs:87:32
149 |
150LL | asm!("", in("$vr0") f, in("$xr0") d);
151 | ^^^^^^^^^^^^
152 |
153 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
154 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
155 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
156
37157error: register class `freg` requires at least one of the following target features: d, f
38 --> $DIR/bad-reg.rs:40:26
158 --> $DIR/bad-reg.rs:42:26
39159 |
40160LL | asm!("/* {} */", in(freg) f);
41161 | ^^^^^^^^^^
42162
43163error: register class `freg` requires at least one of the following target features: d, f
44 --> $DIR/bad-reg.rs:42:26
164 --> $DIR/bad-reg.rs:44:26
45165 |
46166LL | asm!("/* {} */", out(freg) _);
47167 | ^^^^^^^^^^^
48168
49169error: register class `freg` requires at least one of the following target features: d, f
50 --> $DIR/bad-reg.rs:44:26
170 --> $DIR/bad-reg.rs:46:26
51171 |
52172LL | asm!("/* {} */", in(freg) d);
53173 | ^^^^^^^^^^
54174
55175error: register class `freg` requires at least one of the following target features: d, f
56 --> $DIR/bad-reg.rs:46:26
176 --> $DIR/bad-reg.rs:48:26
57177 |
58178LL | asm!("/* {} */", out(freg) d);
59179 | ^^^^^^^^^^^
60180
61error: aborting due to 10 previous errors
181error[E0658]: type `f32` cannot be used with this register class in stable
182 --> $DIR/bad-reg.rs:52:35
183 |
184LL | asm!("/* {} */", in(vreg) f);
185 | ^
186 |
187 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
188 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
189 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
190
191error[E0658]: type `f64` cannot be used with this register class in stable
192 --> $DIR/bad-reg.rs:57:35
193 |
194LL | asm!("/* {} */", in(vreg) d);
195 | ^
196 |
197 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
198 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
199 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
200
201error[E0658]: type `f64` cannot be used with this register class in stable
202 --> $DIR/bad-reg.rs:60:36
203 |
204LL | asm!("/* {} */", out(vreg) d);
205 | ^
206 |
207 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
208 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
209 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
210
211error[E0658]: type `f32` cannot be used with this register class in stable
212 --> $DIR/bad-reg.rs:65:35
213 |
214LL | asm!("/* {} */", in(xreg) f);
215 | ^
216 |
217 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
218 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
219 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
220
221error[E0658]: type `f64` cannot be used with this register class in stable
222 --> $DIR/bad-reg.rs:70:35
223 |
224LL | asm!("/* {} */", in(xreg) d);
225 | ^
226 |
227 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
228 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
229 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
230
231error[E0658]: type `f64` cannot be used with this register class in stable
232 --> $DIR/bad-reg.rs:73:36
233 |
234LL | asm!("/* {} */", out(xreg) d);
235 | ^
236 |
237 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
238 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
239 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
240
241error: register class `freg` requires at least one of the following target features: d, f
242 --> $DIR/bad-reg.rs:77:18
243 |
244LL | asm!("", in("$f0") f, in("$vr0") d);
245 | ^^^^^^^^^^^
246
247error[E0658]: type `f64` cannot be used with this register class in stable
248 --> $DIR/bad-reg.rs:77:42
249 |
250LL | asm!("", in("$f0") f, in("$vr0") d);
251 | ^
252 |
253 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
254 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
255 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
256
257error: register class `freg` requires at least one of the following target features: d, f
258 --> $DIR/bad-reg.rs:82:18
259 |
260LL | asm!("", in("$f0") f, in("$xr0") d);
261 | ^^^^^^^^^^^
262
263error[E0658]: type `f64` cannot be used with this register class in stable
264 --> $DIR/bad-reg.rs:82:42
265 |
266LL | asm!("", in("$f0") f, in("$xr0") d);
267 | ^
268 |
269 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
270 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
271 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
272
273error[E0658]: type `f32` cannot be used with this register class in stable
274 --> $DIR/bad-reg.rs:87:29
275 |
276LL | asm!("", in("$vr0") f, in("$xr0") d);
277 | ^
278 |
279 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
280 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
281 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
282
283error[E0658]: type `f64` cannot be used with this register class in stable
284 --> $DIR/bad-reg.rs:87:43
285 |
286LL | asm!("", in("$vr0") f, in("$xr0") d);
287 | ^
288 |
289 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
290 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
291 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
292
293error: aborting due to 34 previous errors
62294
295For more information about this error, try `rustc --explain E0658`.
tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr+31-7
......@@ -1,38 +1,62 @@
11error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
2 --> $DIR/bad-reg.rs:26:18
2 --> $DIR/bad-reg.rs:28:18
33 |
44LL | asm!("", out("$r0") _);
55 | ^^^^^^^^^^^^
66
77error: invalid register `$tp`: reserved for TLS
8 --> $DIR/bad-reg.rs:28:18
8 --> $DIR/bad-reg.rs:30:18
99 |
1010LL | asm!("", out("$tp") _);
1111 | ^^^^^^^^^^^^
1212
1313error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
14 --> $DIR/bad-reg.rs:30:18
14 --> $DIR/bad-reg.rs:32:18
1515 |
1616LL | asm!("", out("$sp") _);
1717 | ^^^^^^^^^^^^
1818
1919error: invalid register `$r21`: reserved by the ABI
20 --> $DIR/bad-reg.rs:32:18
20 --> $DIR/bad-reg.rs:34:18
2121 |
2222LL | asm!("", out("$r21") _);
2323 | ^^^^^^^^^^^^^
2424
2525error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
26 --> $DIR/bad-reg.rs:34:18
26 --> $DIR/bad-reg.rs:36:18
2727 |
2828LL | asm!("", out("$fp") _);
2929 | ^^^^^^^^^^^^
3030
3131error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
32 --> $DIR/bad-reg.rs:36:18
32 --> $DIR/bad-reg.rs:38:18
3333 |
3434LL | asm!("", out("$r31") _);
3535 | ^^^^^^^^^^^^^
3636
37error: aborting due to 6 previous errors
37error: register `$vr0` conflicts with register `$f0`
38 --> $DIR/bad-reg.rs:77:31
39 |
40LL | asm!("", in("$f0") f, in("$vr0") d);
41 | ----------- ^^^^^^^^^^^^ register `$vr0`
42 | |
43 | register `$f0`
44
45error: register `$xr0` conflicts with register `$f0`
46 --> $DIR/bad-reg.rs:82:31
47 |
48LL | asm!("", in("$f0") f, in("$xr0") d);
49 | ----------- ^^^^^^^^^^^^ register `$xr0`
50 | |
51 | register `$f0`
52
53error: register `$xr0` conflicts with register `$vr0`
54 --> $DIR/bad-reg.rs:87:32
55 |
56LL | asm!("", in("$vr0") f, in("$xr0") d);
57 | ------------ ^^^^^^^^^^^^ register `$xr0`
58 | |
59 | register `$vr0`
60
61error: aborting due to 9 previous errors
3862
tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr+244-11
......@@ -1,62 +1,295 @@
11error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
2 --> $DIR/bad-reg.rs:26:18
2 --> $DIR/bad-reg.rs:28:18
33 |
44LL | asm!("", out("$r0") _);
55 | ^^^^^^^^^^^^
66
77error: invalid register `$tp`: reserved for TLS
8 --> $DIR/bad-reg.rs:28:18
8 --> $DIR/bad-reg.rs:30:18
99 |
1010LL | asm!("", out("$tp") _);
1111 | ^^^^^^^^^^^^
1212
1313error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
14 --> $DIR/bad-reg.rs:30:18
14 --> $DIR/bad-reg.rs:32:18
1515 |
1616LL | asm!("", out("$sp") _);
1717 | ^^^^^^^^^^^^
1818
1919error: invalid register `$r21`: reserved by the ABI
20 --> $DIR/bad-reg.rs:32:18
20 --> $DIR/bad-reg.rs:34:18
2121 |
2222LL | asm!("", out("$r21") _);
2323 | ^^^^^^^^^^^^^
2424
2525error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
26 --> $DIR/bad-reg.rs:34:18
26 --> $DIR/bad-reg.rs:36:18
2727 |
2828LL | asm!("", out("$fp") _);
2929 | ^^^^^^^^^^^^
3030
3131error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
32 --> $DIR/bad-reg.rs:36:18
32 --> $DIR/bad-reg.rs:38:18
3333 |
3434LL | asm!("", out("$r31") _);
3535 | ^^^^^^^^^^^^^
3636
37error[E0658]: register class `vreg` can only be used as a clobber in stable
38 --> $DIR/bad-reg.rs:52:26
39 |
40LL | asm!("/* {} */", in(vreg) f);
41 | ^^^^^^^^^^
42 |
43 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
44 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
45 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
46
47error[E0658]: register class `vreg` can only be used as a clobber in stable
48 --> $DIR/bad-reg.rs:55:26
49 |
50LL | asm!("/* {} */", out(vreg) _);
51 | ^^^^^^^^^^^
52 |
53 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
54 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
55 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
56
57error[E0658]: register class `vreg` can only be used as a clobber in stable
58 --> $DIR/bad-reg.rs:57:26
59 |
60LL | asm!("/* {} */", in(vreg) d);
61 | ^^^^^^^^^^
62 |
63 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
64 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
65 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
66
67error[E0658]: register class `vreg` can only be used as a clobber in stable
68 --> $DIR/bad-reg.rs:60:26
69 |
70LL | asm!("/* {} */", out(vreg) d);
71 | ^^^^^^^^^^^
72 |
73 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
74 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
75 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
76
77error[E0658]: register class `xreg` can only be used as a clobber in stable
78 --> $DIR/bad-reg.rs:65:26
79 |
80LL | asm!("/* {} */", in(xreg) f);
81 | ^^^^^^^^^^
82 |
83 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
84 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
85 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
86
87error[E0658]: register class `xreg` can only be used as a clobber in stable
88 --> $DIR/bad-reg.rs:68:26
89 |
90LL | asm!("/* {} */", out(xreg) _);
91 | ^^^^^^^^^^^
92 |
93 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
94 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
95 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
96
97error[E0658]: register class `xreg` can only be used as a clobber in stable
98 --> $DIR/bad-reg.rs:70:26
99 |
100LL | asm!("/* {} */", in(xreg) d);
101 | ^^^^^^^^^^
102 |
103 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
104 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
105 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
106
107error[E0658]: register class `xreg` can only be used as a clobber in stable
108 --> $DIR/bad-reg.rs:73:26
109 |
110LL | asm!("/* {} */", out(xreg) d);
111 | ^^^^^^^^^^^
112 |
113 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
114 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
115 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
116
117error[E0658]: register class `vreg` can only be used as a clobber in stable
118 --> $DIR/bad-reg.rs:77:31
119 |
120LL | asm!("", in("$f0") f, in("$vr0") d);
121 | ^^^^^^^^^^^^
122 |
123 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
124 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
125 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
126
127error[E0658]: register class `xreg` can only be used as a clobber in stable
128 --> $DIR/bad-reg.rs:82:31
129 |
130LL | asm!("", in("$f0") f, in("$xr0") d);
131 | ^^^^^^^^^^^^
132 |
133 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
134 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
135 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
136
137error[E0658]: register class `vreg` can only be used as a clobber in stable
138 --> $DIR/bad-reg.rs:87:18
139 |
140LL | asm!("", in("$vr0") f, in("$xr0") d);
141 | ^^^^^^^^^^^^
142 |
143 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
144 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
145 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
146
147error[E0658]: register class `xreg` can only be used as a clobber in stable
148 --> $DIR/bad-reg.rs:87:32
149 |
150LL | asm!("", in("$vr0") f, in("$xr0") d);
151 | ^^^^^^^^^^^^
152 |
153 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
154 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
155 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
156
37157error: register class `freg` requires at least one of the following target features: d, f
38 --> $DIR/bad-reg.rs:40:26
158 --> $DIR/bad-reg.rs:42:26
39159 |
40160LL | asm!("/* {} */", in(freg) f);
41161 | ^^^^^^^^^^
42162
43163error: register class `freg` requires at least one of the following target features: d, f
44 --> $DIR/bad-reg.rs:42:26
164 --> $DIR/bad-reg.rs:44:26
45165 |
46166LL | asm!("/* {} */", out(freg) _);
47167 | ^^^^^^^^^^^
48168
49169error: register class `freg` requires at least one of the following target features: d, f
50 --> $DIR/bad-reg.rs:44:26
170 --> $DIR/bad-reg.rs:46:26
51171 |
52172LL | asm!("/* {} */", in(freg) d);
53173 | ^^^^^^^^^^
54174
55175error: register class `freg` requires at least one of the following target features: d, f
56 --> $DIR/bad-reg.rs:46:26
176 --> $DIR/bad-reg.rs:48:26
57177 |
58178LL | asm!("/* {} */", out(freg) d);
59179 | ^^^^^^^^^^^
60180
61error: aborting due to 10 previous errors
181error[E0658]: type `f32` cannot be used with this register class in stable
182 --> $DIR/bad-reg.rs:52:35
183 |
184LL | asm!("/* {} */", in(vreg) f);
185 | ^
186 |
187 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
188 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
189 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
190
191error[E0658]: type `f64` cannot be used with this register class in stable
192 --> $DIR/bad-reg.rs:57:35
193 |
194LL | asm!("/* {} */", in(vreg) d);
195 | ^
196 |
197 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
198 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
199 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
200
201error[E0658]: type `f64` cannot be used with this register class in stable
202 --> $DIR/bad-reg.rs:60:36
203 |
204LL | asm!("/* {} */", out(vreg) d);
205 | ^
206 |
207 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
208 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
209 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
210
211error[E0658]: type `f32` cannot be used with this register class in stable
212 --> $DIR/bad-reg.rs:65:35
213 |
214LL | asm!("/* {} */", in(xreg) f);
215 | ^
216 |
217 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
218 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
219 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
220
221error[E0658]: type `f64` cannot be used with this register class in stable
222 --> $DIR/bad-reg.rs:70:35
223 |
224LL | asm!("/* {} */", in(xreg) d);
225 | ^
226 |
227 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
228 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
229 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
230
231error[E0658]: type `f64` cannot be used with this register class in stable
232 --> $DIR/bad-reg.rs:73:36
233 |
234LL | asm!("/* {} */", out(xreg) d);
235 | ^
236 |
237 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
238 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
239 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
240
241error: register class `freg` requires at least one of the following target features: d, f
242 --> $DIR/bad-reg.rs:77:18
243 |
244LL | asm!("", in("$f0") f, in("$vr0") d);
245 | ^^^^^^^^^^^
246
247error[E0658]: type `f64` cannot be used with this register class in stable
248 --> $DIR/bad-reg.rs:77:42
249 |
250LL | asm!("", in("$f0") f, in("$vr0") d);
251 | ^
252 |
253 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
254 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
255 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
256
257error: register class `freg` requires at least one of the following target features: d, f
258 --> $DIR/bad-reg.rs:82:18
259 |
260LL | asm!("", in("$f0") f, in("$xr0") d);
261 | ^^^^^^^^^^^
262
263error[E0658]: type `f64` cannot be used with this register class in stable
264 --> $DIR/bad-reg.rs:82:42
265 |
266LL | asm!("", in("$f0") f, in("$xr0") d);
267 | ^
268 |
269 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
270 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
271 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
272
273error[E0658]: type `f32` cannot be used with this register class in stable
274 --> $DIR/bad-reg.rs:87:29
275 |
276LL | asm!("", in("$vr0") f, in("$xr0") d);
277 | ^
278 |
279 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
280 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
281 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
282
283error[E0658]: type `f64` cannot be used with this register class in stable
284 --> $DIR/bad-reg.rs:87:43
285 |
286LL | asm!("", in("$vr0") f, in("$xr0") d);
287 | ^
288 |
289 = note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
290 = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
291 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
292
293error: aborting due to 34 previous errors
62294
295For more information about this error, try `rustc --explain E0658`.
tests/ui/asm/loongarch/bad-reg.rs+46-1
......@@ -4,12 +4,14 @@
44//@[loongarch32_ilp32d] needs-llvm-components: loongarch
55//@[loongarch32_ilp32s] compile-flags: --target loongarch32-unknown-none-softfloat
66//@[loongarch32_ilp32s] needs-llvm-components: loongarch
7//@[loongarch64_lp64d] compile-flags: --target loongarch64-unknown-linux-gnu
7//@[loongarch64_lp64d] compile-flags: --target loongarch64-unknown-linux-gnu -Ctarget-feature=+lasx
88//@[loongarch64_lp64d] needs-llvm-components: loongarch
99//@[loongarch64_lp64s] compile-flags: --target loongarch64-unknown-none-softfloat
1010//@[loongarch64_lp64s] needs-llvm-components: loongarch
1111//@ ignore-backends: gcc
1212
13#![cfg_attr(loongarch64_lp64d, feature(asm_experimental_reg))]
14
1315#![crate_type = "lib"]
1416#![feature(no_core)]
1517#![no_core]
......@@ -45,5 +47,48 @@ fn f() {
4547 //[loongarch32_ilp32s,loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
4648 asm!("/* {} */", out(freg) d);
4749 //[loongarch32_ilp32s,loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
50
51 asm!("", out("$vr0") _); // ok
52 asm!("/* {} */", in(vreg) f);
53 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~^ ERROR register class `vreg` can only be used as a clobber in stable
54 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `f32` cannot be used with this register class in stable
55 asm!("/* {} */", out(vreg) _);
56 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~^ ERROR register class `vreg` can only be used as a clobber in stable
57 asm!("/* {} */", in(vreg) d);
58 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~^ ERROR register class `vreg` can only be used as a clobber in stable
59 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `f64` cannot be used with this register class in stable
60 asm!("/* {} */", out(vreg) d);
61 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~^ ERROR register class `vreg` can only be used as a clobber in stable
62 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `f64` cannot be used with this register class in stable
63
64 asm!("", out("$xr0") _); // ok
65 asm!("/* {} */", in(xreg) f);
66 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~^ ERROR register class `xreg` can only be used as a clobber in stable
67 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `f32` cannot be used with this register class in stable
68 asm!("/* {} */", out(xreg) _);
69 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~^ ERROR register class `xreg` can only be used as a clobber in stable
70 asm!("/* {} */", in(xreg) d);
71 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~^ ERROR register class `xreg` can only be used as a clobber in stable
72 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `f64` cannot be used with this register class in stable
73 asm!("/* {} */", out(xreg) d);
74 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~^ ERROR register class `xreg` can only be used as a clobber in stable
75 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `f64` cannot be used with this register class in stable
76
77 asm!("", in("$f0") f, in("$vr0") d);
78 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~^ ERROR register class `vreg` can only be used as a clobber in stable
79 //[loongarch32_ilp32s,loongarch64_lp64s]~| ERROR register class `freg` requires at least one of the following target features: d, f
80 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `f64` cannot be used with this register class in stable
81 //[loongarch64_lp64d]~^^^^ ERROR register `$vr0` conflicts with register `$f0`
82 asm!("", in("$f0") f, in("$xr0") d);
83 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~^ ERROR register class `xreg` can only be used as a clobber in stable
84 //[loongarch32_ilp32s,loongarch64_lp64s]~| ERROR register class `freg` requires at least one of the following target features: d, f
85 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `f64` cannot be used with this register class in stable
86 //[loongarch64_lp64d]~^^^^ ERROR register `$xr0` conflicts with register `$f0`
87 asm!("", in("$vr0") f, in("$xr0") d);
88 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~^ ERROR register class `vreg` can only be used as a clobber in stable
89 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR register class `xreg` can only be used as a clobber in stable
90 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `f32` cannot be used with this register class in stable
91 //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `f64` cannot be used with this register class in stable
92 //[loongarch64_lp64d]~^^^^^ ERROR register `$xr0` conflicts with register `$vr0`
4893 }
4994}