| author | bors <bors@rust-lang.org> 2026-07-01 21:43:13 UTC |
| committer | bors <bors@rust-lang.org> 2026-07-01 21:43:13 UTC |
| log | 2371d697abddba53be85137d5a68064066b4ae10 |
| tree | dea1819c1e18969ba79bcd3e60b0b3bdab0929b9 |
| parent | 4c9d2bfe4ad7a65669098754964aaebe0ec1ced2 |
| parent | a2f8a156675e4360c953f86c10572253914b2fed |
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 = [ |
| 3235 | 3235 | "ptr_meta", |
| 3236 | 3236 | ] |
| 3237 | 3237 | |
| 3238 | [[package]] | |
| 3239 | name = "rand" | |
| 3240 | version = "0.8.5" | |
| 3241 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 3242 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" | |
| 3243 | dependencies = [ | |
| 3244 | "libc", | |
| 3245 | "rand_chacha 0.3.1", | |
| 3246 | "rand_core 0.6.4", | |
| 3247 | ] | |
| 3248 | ||
| 3249 | 3238 | [[package]] |
| 3250 | 3239 | name = "rand" |
| 3251 | 3240 | version = "0.9.2" |
| 3252 | 3241 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 3253 | 3242 | checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" |
| 3254 | 3243 | dependencies = [ |
| 3255 | "rand_chacha 0.9.0", | |
| 3244 | "rand_chacha", | |
| 3256 | 3245 | "rand_core 0.9.3", |
| 3257 | 3246 | ] |
| 3258 | 3247 | |
| ... | ... | @@ -3267,16 +3256,6 @@ dependencies = [ |
| 3267 | 3256 | "rand_core 0.10.1", |
| 3268 | 3257 | ] |
| 3269 | 3258 | |
| 3270 | [[package]] | |
| 3271 | name = "rand_chacha" | |
| 3272 | version = "0.3.1" | |
| 3273 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 3274 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" | |
| 3275 | dependencies = [ | |
| 3276 | "ppv-lite86", | |
| 3277 | "rand_core 0.6.4", | |
| 3278 | ] | |
| 3279 | ||
| 3280 | 3259 | [[package]] |
| 3281 | 3260 | name = "rand_chacha" |
| 3282 | 3261 | version = "0.9.0" |
| ... | ... | @@ -3287,15 +3266,6 @@ dependencies = [ |
| 3287 | 3266 | "rand_core 0.9.3", |
| 3288 | 3267 | ] |
| 3289 | 3268 | |
| 3290 | [[package]] | |
| 3291 | name = "rand_core" | |
| 3292 | version = "0.6.4" | |
| 3293 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 3294 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" | |
| 3295 | dependencies = [ | |
| 3296 | "getrandom 0.2.16", | |
| 3297 | ] | |
| 3298 | ||
| 3299 | 3269 | [[package]] |
| 3300 | 3270 | name = "rand_core" |
| 3301 | 3271 | version = "0.9.3" |
| ... | ... | @@ -5550,7 +5520,7 @@ dependencies = [ |
| 5550 | 5520 | "indicatif", |
| 5551 | 5521 | "num", |
| 5552 | 5522 | "rand 0.9.2", |
| 5553 | "rand_chacha 0.9.0", | |
| 5523 | "rand_chacha", | |
| 5554 | 5524 | "rayon", |
| 5555 | 5525 | ] |
| 5556 | 5526 | |
| ... | ... | @@ -5924,7 +5894,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
| 5924 | 5894 | checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" |
| 5925 | 5895 | dependencies = [ |
| 5926 | 5896 | "cfg-if", |
| 5927 | "rand 0.8.5", | |
| 5928 | 5897 | "static_assertions", |
| 5929 | 5898 | ] |
| 5930 | 5899 |
compiler/rustc_codegen_gcc/src/asm.rs+25-2| ... | ... | @@ -706,7 +706,9 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str { |
| 706 | 706 | unreachable!("clobber-only") |
| 707 | 707 | } |
| 708 | 708 | 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", | |
| 710 | 712 | InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r", |
| 711 | 713 | InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => "a", |
| 712 | 714 | InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => "d", |
| ... | ... | @@ -815,6 +817,12 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl |
| 815 | 817 | } |
| 816 | 818 | InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(), |
| 817 | 819 | 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 | } | |
| 818 | 826 | InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(), |
| 819 | 827 | InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(), |
| 820 | 828 | InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => cx.type_i16(), |
| ... | ... | @@ -1013,7 +1021,22 @@ fn modifier_to_gcc( |
| 1013 | 1021 | } |
| 1014 | 1022 | } |
| 1015 | 1023 | 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 | } | |
| 1017 | 1040 | InlineAsmRegClass::Mips(_) => None, |
| 1018 | 1041 | InlineAsmRegClass::Nvptx(_) => None, |
| 1019 | 1042 | 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<'_>>) -> |
| 709 | 709 | Hexagon(HexagonInlineAsmRegClass::vreg_pair) => "v", |
| 710 | 710 | Hexagon(HexagonInlineAsmRegClass::qreg) => unreachable!("clobber-only"), |
| 711 | 711 | LoongArch(LoongArchInlineAsmRegClass::reg) => "r", |
| 712 | LoongArch(LoongArchInlineAsmRegClass::freg) => "f", | |
| 712 | LoongArch(LoongArchInlineAsmRegClass::freg) | |
| 713 | | LoongArch(LoongArchInlineAsmRegClass::vreg) | |
| 714 | | LoongArch(LoongArchInlineAsmRegClass::xreg) => "f", | |
| 713 | 715 | Mips(MipsInlineAsmRegClass::reg) => "r", |
| 714 | 716 | Mips(MipsInlineAsmRegClass::freg) => "f", |
| 715 | 717 | Nvptx(NvptxInlineAsmRegClass::reg16) => "h", |
| ... | ... | @@ -814,7 +816,22 @@ fn modifier_to_llvm( |
| 814 | 816 | } |
| 815 | 817 | Amdgpu(_) => None, |
| 816 | 818 | 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 | } | |
| 818 | 835 | Mips(_) => None, |
| 819 | 836 | Nvptx(_) => None, |
| 820 | 837 | PowerPC(PowerPCInlineAsmRegClass::vsreg) => { |
| ... | ... | @@ -917,6 +934,8 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &' |
| 917 | 934 | Hexagon(HexagonInlineAsmRegClass::qreg) => unreachable!("clobber-only"), |
| 918 | 935 | LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(), |
| 919 | 936 | 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), | |
| 920 | 939 | Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(), |
| 921 | 940 | Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(), |
| 922 | 941 | 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> + '_ { |
| 1707 | 1707 | .inherent_impls(adt_did) |
| 1708 | 1708 | .iter() |
| 1709 | 1709 | .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_)?; | |
| 1712 | 1711 | Some(InherentAssocCandidate { impl_, assoc_item: item.def_id, scope }) |
| 1713 | 1712 | }) |
| 1714 | 1713 | .collect(); |
| ... | ... | @@ -1784,7 +1783,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { |
| 1784 | 1783 | span: Span, |
| 1785 | 1784 | scope: DefId, |
| 1786 | 1785 | ) -> 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)?; | |
| 1788 | 1787 | self.check_assoc_item(item.def_id, ident, scope, block, span); |
| 1789 | 1788 | Some(item) |
| 1790 | 1789 | } |
| ... | ... | @@ -1797,12 +1796,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { |
| 1797 | 1796 | &self, |
| 1798 | 1797 | ident: Ident, |
| 1799 | 1798 | assoc_tag: ty::AssocTag, |
| 1800 | block: HirId, | |
| 1801 | 1799 | scope: DefId, |
| 1802 | 1800 | ) -> Option<(ty::AssocItem, /*scope*/ DefId)> { |
| 1803 | 1801 | let tcx = self.tcx(); |
| 1804 | 1802 | |
| 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()); | |
| 1806 | 1804 | // We have already adjusted the item name above, so compare with `.normalize_to_macros_2_0()` |
| 1807 | 1805 | // instead of calling `filter_by_name_and_kind` which would needlessly normalize the |
| 1808 | 1806 | // `ident` again and again. |
| ... | ... | @@ -3497,8 +3495,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { |
| 3497 | 3495 | } |
| 3498 | 3496 | (FIRST_VARIANT, def.non_enum_variant()) |
| 3499 | 3497 | }; |
| 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); | |
| 3502 | 3500 | if let Some((field_idx, field)) = variant |
| 3503 | 3501 | .fields |
| 3504 | 3502 | .iter_enumerated() |
compiler/rustc_hir_typeck/src/expr.rs+8-9| ... | ... | @@ -2764,9 +2764,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 2764 | 2764 | return Ty::new_error(self.tcx(), guar); |
| 2765 | 2765 | } |
| 2766 | 2766 | |
| 2767 | let fn_body_hir_id = self.tcx.local_def_id_to_hir_id(self.body_id); | |
| 2768 | 2767 | 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); | |
| 2770 | 2769 | |
| 2771 | 2770 | if let Some((idx, field)) = self.find_adt_field(*base_def, ident) { |
| 2772 | 2771 | self.write_field_index(expr.hir_id, idx); |
| ... | ... | @@ -3768,9 +3767,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 3768 | 3767 | |
| 3769 | 3768 | match container.kind() { |
| 3770 | 3769 | 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()); | |
| 3774 | 3771 | |
| 3775 | 3772 | if !self.tcx.features().offset_of_enum() { |
| 3776 | 3773 | rustc_session::errors::feature_err( |
| ... | ... | @@ -3806,7 +3803,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 3806 | 3803 | break; |
| 3807 | 3804 | }; |
| 3808 | 3805 | 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); | |
| 3810 | 3807 | |
| 3811 | 3808 | let Some((subindex, field)) = variant |
| 3812 | 3809 | .fields |
| ... | ... | @@ -3854,9 +3851,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 3854 | 3851 | continue; |
| 3855 | 3852 | } |
| 3856 | 3853 | 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 | ); | |
| 3860 | 3859 | |
| 3861 | 3860 | let fields = &container_def.non_enum_variant().fields; |
| 3862 | 3861 | 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> { |
| 810 | 810 | fn push_candidate(&mut self, candidate: Candidate<'tcx>, is_inherent: bool) { |
| 811 | 811 | let is_accessible = if let Some(name) = self.method_name { |
| 812 | 812 | 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; | |
| 816 | 815 | item.visibility(self.tcx).is_accessible_from(def_scope, self.tcx) |
| 817 | 816 | } else { |
| 818 | 817 | true |
compiler/rustc_middle/src/ty/mod.rs+2-3| ... | ... | @@ -2137,18 +2137,17 @@ impl<'tcx> TyCtxt<'tcx> { |
| 2137 | 2137 | ident |
| 2138 | 2138 | } |
| 2139 | 2139 | |
| 2140 | // FIXME(vincenzopalazzo): move the HirId to a LocalDefId | |
| 2141 | 2140 | pub fn adjust_ident_and_get_scope( |
| 2142 | 2141 | self, |
| 2143 | 2142 | mut ident: Ident, |
| 2144 | 2143 | scope: DefId, |
| 2145 | block: hir::HirId, | |
| 2144 | item_id: LocalDefId, | |
| 2146 | 2145 | ) -> (Ident, DefId) { |
| 2147 | 2146 | let scope = ident |
| 2148 | 2147 | .span |
| 2149 | 2148 | .normalize_to_macros_2_0_and_adjust(self.expn_that_defined(scope)) |
| 2150 | 2149 | .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()); | |
| 2152 | 2151 | (ident, scope) |
| 2153 | 2152 | } |
| 2154 | 2153 |
compiler/rustc_privacy/src/lib.rs+2-1| ... | ... | @@ -948,7 +948,8 @@ impl<'tcx> NamePrivacyVisitor<'tcx> { |
| 948 | 948 | |
| 949 | 949 | // definition of the field |
| 950 | 950 | 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); | |
| 952 | 953 | !field.vis.is_accessible_from(def_id, self.tcx) |
| 953 | 954 | } |
| 954 | 955 |
compiler/rustc_sanitizers/Cargo.toml+1-1| ... | ... | @@ -14,5 +14,5 @@ rustc_span = { path = "../rustc_span" } |
| 14 | 14 | rustc_target = { path = "../rustc_target" } |
| 15 | 15 | rustc_trait_selection = { path = "../rustc_trait_selection" } |
| 16 | 16 | tracing = "0.1" |
| 17 | twox-hash = "1.6.3" | |
| 17 | twox-hash = { version = "1.6.3", default-features = false } | |
| 18 | 18 | # tidy-alphabetical-end |
compiler/rustc_span/src/symbol.rs+3| ... | ... | @@ -1170,6 +1170,7 @@ symbols! { |
| 1170 | 1170 | lang_items, |
| 1171 | 1171 | large_assignments, |
| 1172 | 1172 | last, |
| 1173 | lasx, | |
| 1173 | 1174 | lateout, |
| 1174 | 1175 | lazy_normalization_consts, |
| 1175 | 1176 | lazy_type_alias, |
| ... | ... | @@ -1227,6 +1228,7 @@ symbols! { |
| 1227 | 1228 | loop_hints, |
| 1228 | 1229 | loop_match, |
| 1229 | 1230 | lr, |
| 1231 | lsx, | |
| 1230 | 1232 | lt, |
| 1231 | 1233 | m68k, |
| 1232 | 1234 | m68k_target_feature, |
| ... | ... | @@ -2374,6 +2376,7 @@ symbols! { |
| 2374 | 2376 | xloop, |
| 2375 | 2377 | xmm_reg, |
| 2376 | 2378 | xop_target_feature, |
| 2379 | xreg, | |
| 2377 | 2380 | xtensa, |
| 2378 | 2381 | xtensa_target_feature, |
| 2379 | 2382 | yeet_desugar_details, |
compiler/rustc_target/src/asm/loongarch.rs+150-1| ... | ... | @@ -8,12 +8,19 @@ def_reg_class! { |
| 8 | 8 | LoongArch LoongArchInlineAsmRegClass { |
| 9 | 9 | reg, |
| 10 | 10 | freg, |
| 11 | vreg, | |
| 12 | xreg, | |
| 11 | 13 | } |
| 12 | 14 | } |
| 13 | 15 | |
| 14 | 16 | impl LoongArchInlineAsmRegClass { |
| 15 | 17 | 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 | } | |
| 17 | 24 | } |
| 18 | 25 | |
| 19 | 26 | pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option<Self> { |
| ... | ... | @@ -35,6 +42,7 @@ impl LoongArchInlineAsmRegClass { |
| 35 | 42 | pub fn supported_types( |
| 36 | 43 | self, |
| 37 | 44 | arch: InlineAsmArch, |
| 45 | allow_experimental_reg: bool, | |
| 38 | 46 | ) -> &'static [(InlineAsmType, Option<Symbol>)] { |
| 39 | 47 | match (self, arch) { |
| 40 | 48 | (Self::reg, InlineAsmArch::LoongArch64) => { |
| ... | ... | @@ -42,6 +50,27 @@ impl LoongArchInlineAsmRegClass { |
| 42 | 50 | } |
| 43 | 51 | (Self::reg, InlineAsmArch::LoongArch32) => types! { _: I8, I16, I32, F16, F32; }, |
| 44 | 52 | (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 | } | |
| 45 | 74 | _ => unreachable!("unsupported register class"), |
| 46 | 75 | } |
| 47 | 76 | } |
| ... | ... | @@ -108,6 +137,70 @@ def_regs! { |
| 108 | 137 | f29: freg = ["$f29","$fs5"], |
| 109 | 138 | f30: freg = ["$f30","$fs6"], |
| 110 | 139 | 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"], | |
| 111 | 204 | #error = ["$r0","$zero"] => |
| 112 | 205 | "constant zero cannot be used as an operand for inline asm", |
| 113 | 206 | #error = ["$r2","$tp"] => |
| ... | ... | @@ -132,4 +225,60 @@ impl LoongArchInlineAsmReg { |
| 132 | 225 | ) -> fmt::Result { |
| 133 | 226 | out.write_str(self.name()) |
| 134 | 227 | } |
| 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 | } | |
| 135 | 284 | } |
compiler/rustc_target/src/asm/mod.rs+2-2| ... | ... | @@ -474,7 +474,7 @@ impl InlineAsmReg { |
| 474 | 474 | Self::RiscV(_) => cb(self), |
| 475 | 475 | Self::PowerPC(r) => r.overlapping_regs(|r| cb(Self::PowerPC(r))), |
| 476 | 476 | 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))), | |
| 478 | 478 | Self::Mips(_) => cb(self), |
| 479 | 479 | Self::S390x(r) => r.overlapping_regs(|r| cb(Self::S390x(r))), |
| 480 | 480 | Self::Sparc(_) => cb(self), |
| ... | ... | @@ -655,7 +655,7 @@ impl InlineAsmRegClass { |
| 655 | 655 | Self::Nvptx(r) => r.supported_types(arch).into(), |
| 656 | 656 | Self::PowerPC(r) => r.supported_types(arch).into(), |
| 657 | 657 | 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(), | |
| 659 | 659 | Self::Mips(r) => r.supported_types(arch).into(), |
| 660 | 660 | Self::S390x(r) => r.supported_types(arch).into(), |
| 661 | 661 | 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> { |
| 334 | 334 | return; |
| 335 | 335 | } |
| 336 | 336 | |
| 337 | let fn_body_hir_id = self.tcx.local_def_id_to_hir_id(typeck_results.hir_owner.def_id); | |
| 338 | 337 | let mut private_candidate: Option<(Ty<'tcx>, Ty<'tcx>, Span)> = None; |
| 339 | 338 | |
| 340 | 339 | for (deref_base_ty, _) in (self.autoderef_steps)(base_ty) { |
| ... | ... | @@ -346,8 +345,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { |
| 346 | 345 | continue; |
| 347 | 346 | } |
| 348 | 347 | |
| 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 | ); | |
| 351 | 353 | |
| 352 | 354 | let Some((_, field_def)) = |
| 353 | 355 | base_def.non_enum_variant().fields.iter_enumerated().find(|(_, field)| { |
library/alloc/src/lib.rs+1| ... | ... | @@ -144,6 +144,7 @@ |
| 144 | 144 | #![feature(legacy_receiver_trait)] |
| 145 | 145 | #![feature(likely_unlikely)] |
| 146 | 146 | #![feature(local_waker)] |
| 147 | #![feature(maybe_uninit_array_assume_init)] | |
| 147 | 148 | #![feature(maybe_uninit_uninit_array_transpose)] |
| 148 | 149 | #![feature(panic_internals)] |
| 149 | 150 | #![feature(pattern)] |
library/alloc/src/vec/into_iter.rs+41| ... | ... | @@ -445,6 +445,47 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> { |
| 445 | 445 | } |
| 446 | 446 | } |
| 447 | 447 | |
| 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 | ||
| 448 | 489 | #[inline] |
| 449 | 490 | fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> { |
| 450 | 491 | let step_size = self.len().min(n); |
library/alloctests/tests/vec.rs+17| ... | ... | @@ -1027,6 +1027,15 @@ fn test_into_iter_next_chunk() { |
| 1027 | 1027 | assert_eq!(iter.next_chunk::<4>().unwrap_err().as_slice(), &[]); // N is explicitly 4 |
| 1028 | 1028 | } |
| 1029 | 1029 | |
| 1030 | #[test] | |
| 1031 | fn 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 | ||
| 1030 | 1039 | #[test] |
| 1031 | 1040 | fn test_into_iter_clone() { |
| 1032 | 1041 | fn iter_equal<I: Iterator<Item = i32>>(it: I, slice: &[i32]) { |
| ... | ... | @@ -1131,6 +1140,14 @@ fn test_into_iter_zst() { |
| 1131 | 1140 | let mut it = vec![C, C].into_iter(); |
| 1132 | 1141 | it.next_chunk::<4>().unwrap_err(); |
| 1133 | 1142 | 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); | |
| 1134 | 1151 | } |
| 1135 | 1152 | |
| 1136 | 1153 | #[test] |
library/core/src/array/mod.rs+154| ... | ... | @@ -969,6 +969,54 @@ const impl<T: [const] Destruct> Drop for Guard<'_, T> { |
| 969 | 969 | } |
| 970 | 970 | } |
| 971 | 971 | |
| 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. | |
| 981 | struct 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 | ||
| 988 | impl<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 | ||
| 1008 | impl<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 | ||
| 972 | 1020 | /// Pulls `N` items from `iter` and returns them as an array. If the iterator |
| 973 | 1021 | /// yields fewer than `N` items, `Err` is returned containing an iterator over |
| 974 | 1022 | /// the already yielded items. |
| ... | ... | @@ -1076,3 +1124,109 @@ const fn iter_next_chunk_erased<T>( |
| 1076 | 1124 | mem::forget(guard); |
| 1077 | 1125 | Ok(()) |
| 1078 | 1126 | } |
| 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] | |
| 1141 | pub(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 | ||
| 1147 | pub(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 | ||
| 1153 | impl<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 | ||
| 1171 | impl<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. | |
| 1192 | unsafe 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] | |
| 1213 | fn 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 @@ |
| 1 | use crate::array; | |
| 1 | 2 | use crate::marker::Destruct; |
| 2 | 3 | use crate::num::NonZero; |
| 3 | 4 | use crate::ops::{ControlFlow, Try}; |
| ... | ... | @@ -95,6 +96,53 @@ pub const trait DoubleEndedIterator: [const] Iterator { |
| 95 | 96 | #[stable(feature = "rust1", since = "1.0.0")] |
| 96 | 97 | fn next_back(&mut self) -> Option<Self::Item>; |
| 97 | 98 | |
| 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 | ||
| 98 | 146 | /// Advances the iterator from the back by `n` elements. |
| 99 | 147 | /// |
| 100 | 148 | /// `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 { |
| 1810 | 1810 | #[track_caller] |
| 1811 | 1811 | #[rustc_diagnostic_item = "ptr_read_unaligned"] |
| 1812 | 1812 | pub 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>>(); | |
| 1814 | 1820 | // 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. | |
| 1817 | 1823 | // |
| 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. | |
| 1820 | 1827 | 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) | |
| 1823 | 1831 | } |
| 1824 | 1832 | } |
| 1825 | 1833 | |
| ... | ... | @@ -2012,14 +2020,18 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) { |
| 2012 | 2020 | #[rustc_diagnostic_item = "ptr_write_unaligned"] |
| 2013 | 2021 | #[track_caller] |
| 2014 | 2022 | pub 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>>()); | |
| 2022 | 2027 | } |
| 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) } | |
| 2023 | 2035 | } |
| 2024 | 2036 | |
| 2025 | 2037 | /// Performs a volatile read of the value from `src` without moving it. |
| ... | ... | @@ -2809,3 +2821,6 @@ pub macro addr_of($place:expr) { |
| 2809 | 2821 | pub macro addr_of_mut($place:expr) { |
| 2810 | 2822 | &raw mut $place |
| 2811 | 2823 | } |
| 2824 | ||
| 2825 | #[repr(C, packed)] | |
| 2826 | struct Packed<T>(T); |
library/coretests/tests/iter/adapters/filter.rs+12| ... | ... | @@ -63,3 +63,15 @@ fn test_next_chunk_does_not_leak() { |
| 63 | 63 | assert_eq!(Rc::strong_count(w), 1); |
| 64 | 64 | } |
| 65 | 65 | } |
| 66 | ||
| 67 | #[test] | |
| 68 | fn 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() { |
| 619 | 619 | assert_eq!(it.next_chunk::<0>().unwrap(), []); |
| 620 | 620 | } |
| 621 | 621 | |
| 622 | #[test] | |
| 623 | fn 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 | ||
| 622 | 634 | #[test] |
| 623 | 635 | fn test_next_chunk_untrusted() { |
| 624 | 636 | struct Untrusted<I: Iterator>(I); |
| ... | ... | @@ -636,6 +648,28 @@ fn test_next_chunk_untrusted() { |
| 636 | 648 | assert_eq!(it.next_chunk::<4>().unwrap_err().as_slice(), &[10, 11]); |
| 637 | 649 | } |
| 638 | 650 | |
| 651 | #[test] | |
| 652 | fn 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 | ||
| 639 | 673 | #[test] |
| 640 | 674 | fn test_collect_into_tuples() { |
| 641 | 675 | 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 @@ |
| 7 | 7 | use crate::ffi::OsStr; |
| 8 | 8 | use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; |
| 9 | 9 | use crate::path::Path; |
| 10 | #[cfg(doc)] | |
| 11 | use crate::process::{ExitStatus, ExitStatusError}; | |
| 10 | 12 | use crate::sys::process::ChildPipe; |
| 11 | 13 | use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner}; |
| 12 | 14 | use crate::{io, process, sys}; |
| ... | ... | @@ -272,35 +274,105 @@ impl CommandExt for process::Command { |
| 272 | 274 | } |
| 273 | 275 | } |
| 274 | 276 | |
| 275 | /// Unix-specific extensions to [`process::ExitStatus`] and | |
| 276 | /// [`ExitStatusError`](process::ExitStatusError). | |
| 277 | /// Unix-specific extensions to [`ExitStatus`] and [`ExitStatusError`]. | |
| 277 | 278 | /// |
| 278 | /// On Unix, `ExitStatus` **does not necessarily represent an exit status**, as | |
| 279 | /// On Unix, [`ExitStatus`] **does not necessarily represent an exit status**, as | |
| 279 | 280 | /// 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 | |
| 282 | 283 | /// calls. |
| 283 | 284 | /// |
| 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 | |
| 285 | 286 | /// represent other kinds of process event. |
| 287 | /// | |
| 288 | /// [`wait`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html | |
| 286 | 289 | #[stable(feature = "rust1", since = "1.0.0")] |
| 287 | 290 | pub 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`]. | |
| 290 | 293 | /// |
| 291 | 294 | /// The value should be a **wait status, not an exit status**. |
| 292 | 295 | /// |
| 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 | /// | |
| 293 | 338 | /// # Panics |
| 294 | 339 | /// |
| 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. | |
| 296 | 343 | /// |
| 297 | /// Making an `ExitStatus` always succeeds and never panics. | |
| 344 | /// [`wait`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html | |
| 298 | 345 | #[stable(feature = "exit_status_from", since = "1.12.0")] |
| 299 | 346 | fn from_raw(raw: i32) -> Self; |
| 300 | 347 | |
| 301 | 348 | /// If the process was terminated by a signal, returns that signal. |
| 302 | 349 | /// |
| 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 | |
| 304 | 376 | #[stable(feature = "rust1", since = "1.0.0")] |
| 305 | 377 | fn signal(&self) -> Option<i32>; |
| 306 | 378 | |
| ... | ... | @@ -310,21 +382,27 @@ pub impl(self) trait ExitStatusExt { |
| 310 | 382 | |
| 311 | 383 | /// If the process was stopped by a signal, returns that signal. |
| 312 | 384 | /// |
| 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 | |
| 315 | 389 | #[stable(feature = "unix_process_wait_more", since = "1.58.0")] |
| 316 | 390 | fn stopped_signal(&self) -> Option<i32>; |
| 317 | 391 | |
| 318 | 392 | /// Whether the process was continued from a stopped status. |
| 319 | 393 | /// |
| 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 | |
| 322 | 398 | #[stable(feature = "unix_process_wait_more", since = "1.58.0")] |
| 323 | 399 | fn continued(&self) -> bool; |
| 324 | 400 | |
| 325 | /// Returns the underlying raw `wait` status. | |
| 401 | /// Returns the underlying raw [`wait`] status. | |
| 326 | 402 | /// |
| 327 | 403 | /// The returned integer is a **wait status, not an exit status**. |
| 404 | /// | |
| 405 | /// [`wait`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html | |
| 328 | 406 | #[stable(feature = "unix_process_wait_more", since = "1.58.0")] |
| 329 | 407 | fn into_raw(self) -> i32; |
| 330 | 408 | } |
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 | ||
| 3 | 1 | pub use super::common::Env; |
| 4 | 2 | use crate::collections::HashMap; |
| 5 | 3 | use crate::ffi::{OsStr, OsString}; |
| 6 | 4 | use crate::io; |
| 7 | use crate::sync::atomic::{Atomic, AtomicUsize, Ordering}; | |
| 8 | use crate::sync::{Mutex, Once}; | |
| 5 | use crate::sync::{Mutex, OnceLock}; | |
| 6 | ||
| 7 | type EnvStore = Mutex<HashMap<OsString, OsString>>; | |
| 9 | 8 | |
| 10 | 9 | // Specifying linkage/symbol name is solely to ensure a single instance between this crate and its unit tests |
| 11 | 10 | #[cfg_attr(test, linkage = "available_externally")] |
| 12 | 11 | #[unsafe(export_name = "_ZN16__rust_internals3std3sys3pal3sgx2os3ENVE")] |
| 13 | static 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")] | |
| 17 | static ENV_INIT: Once = Once::new(); | |
| 18 | type EnvStore = Mutex<HashMap<OsString, OsString>>; | |
| 19 | ||
| 20 | fn get_env_store() -> Option<&'static EnvStore> { | |
| 21 | unsafe { (ENV.load(Ordering::Relaxed) as *const EnvStore).as_ref() } | |
| 22 | } | |
| 23 | ||
| 24 | fn 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 | } | |
| 12 | static ENV: OnceLock<EnvStore> = OnceLock::new(); | |
| 30 | 13 | |
| 31 | 14 | pub 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(); | |
| 37 | 19 | Env::new(env) |
| 38 | 20 | } |
| 39 | 21 | |
| 40 | 22 | pub 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()) | |
| 42 | 24 | } |
| 43 | 25 | |
| 44 | 26 | pub 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()); | |
| 47 | 28 | Ok(()) |
| 48 | 29 | } |
| 49 | 30 | |
| 50 | 31 | pub unsafe fn unsetenv(k: &OsStr) -> io::Result<()> { |
| 51 | if let Some(env) = get_env_store() { | |
| 32 | if let Some(env) = ENV.get() { | |
| 52 | 33 | env.lock().unwrap().remove(k); |
| 53 | 34 | } |
| 54 | 35 | 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 |
| 12 | 12 | |
| 13 | 13 | | Architecture | Register class | Registers | LLVM constraint code | |
| 14 | 14 | | ------------ | -------------- | --------- | -------------------- | |
| 15 | | LoongArch | `vreg` | `$vr[0-31]` | `f` | | |
| 16 | | LoongArch | `xreg` | `$xr[0-31]` | `f` | | |
| 15 | 17 | |
| 16 | 18 | ## Register class supported types |
| 17 | 19 | |
| ... | ... | @@ -20,11 +22,16 @@ This tracks support for additional registers in architectures where inline assem |
| 20 | 22 | | x86 | `xmm_reg` | `sse` | `i128` | |
| 21 | 23 | | x86 | `ymm_reg` | `avx` | `i128` | |
| 22 | 24 | | 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` | | |
| 23 | 27 | |
| 24 | 28 | ## Register aliases |
| 25 | 29 | |
| 26 | 30 | | Architecture | Base register | Aliases | |
| 27 | 31 | | ------------ | ------------- | ------- | |
| 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]` | | |
| 28 | 35 | |
| 29 | 36 | ## Unsupported registers |
| 30 | 37 | |
| ... | ... | @@ -35,3 +42,9 @@ This tracks support for additional registers in architectures where inline assem |
| 35 | 42 | |
| 36 | 43 | | Architecture | Register class | Modifier | Example output | LLVM modifier | |
| 37 | 44 | | ------------ | -------------- | -------- | -------------- | ------------- | |
| 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 { |
| 350 | 350 | |
| 351 | 351 | pub(crate) fn print_const(tcx: TyCtxt<'_>, n: ty::Const<'_>) -> String { |
| 352 | 352 | 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() | |
| 373 | 366 | } |
| 374 | }, | |
| 367 | } | |
| 375 | 368 | // array lengths are obviously usize |
| 376 | 369 | ty::ConstKind::Value(cv) if *cv.ty.kind() == ty::Uint(ty::UintTy::Usize) => { |
| 377 | 370 | 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 | ||
| 21 | extern crate minicore; | |
| 22 | use minicore::*; | |
| 23 | ||
| 24 | #[repr(simd)] | |
| 25 | pub struct i8x16([i8; 16]); | |
| 26 | #[repr(simd)] | |
| 27 | pub struct i16x8([i16; 8]); | |
| 28 | #[repr(simd)] | |
| 29 | pub struct i32x4([i32; 4]); | |
| 30 | #[repr(simd)] | |
| 31 | pub struct i64x2([i64; 2]); | |
| 32 | #[repr(simd)] | |
| 33 | pub struct f32x4([f32; 4]); | |
| 34 | #[repr(simd)] | |
| 35 | pub struct f64x2([f64; 2]); | |
| 36 | #[repr(simd)] | |
| 37 | pub struct i8x32([i8; 32]); | |
| 38 | #[repr(simd)] | |
| 39 | pub struct i16x16([i16; 16]); | |
| 40 | #[repr(simd)] | |
| 41 | pub struct i32x8([i32; 8]); | |
| 42 | #[repr(simd)] | |
| 43 | pub struct i64x4([i64; 4]); | |
| 44 | #[repr(simd)] | |
| 45 | pub struct f32x8([f32; 8]); | |
| 46 | #[repr(simd)] | |
| 47 | pub struct f64x4([f64; 4]); | |
| 48 | ||
| 49 | impl Copy for i8x16 {} | |
| 50 | impl Copy for i16x8 {} | |
| 51 | impl Copy for i32x4 {} | |
| 52 | impl Copy for i64x2 {} | |
| 53 | impl Copy for f32x4 {} | |
| 54 | impl Copy for f64x2 {} | |
| 55 | impl Copy for i8x32 {} | |
| 56 | impl Copy for i16x16 {} | |
| 57 | impl Copy for i32x8 {} | |
| 58 | impl Copy for i64x4 {} | |
| 59 | impl Copy for f32x8 {} | |
| 60 | impl Copy for f64x4 {} | |
| 61 | ||
| 62 | macro_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 | |
| 75 | check!(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 | |
| 81 | check!(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 | |
| 87 | check!(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 | |
| 93 | check!(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 | |
| 99 | check!(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 | |
| 105 | check!(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 | |
| 111 | check!(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 | |
| 117 | check!(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 | |
| 123 | check!(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 | |
| 129 | check!(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 | |
| 135 | check!(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 | |
| 141 | check!(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 | |
| 147 | check!(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 | |
| 153 | check!(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 | |
| 159 | check!(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 | |
| 165 | check!(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 | |
| 171 | check!(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 | |
| 177 | check!(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 | |
| 183 | check!(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 | |
| 189 | check!(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 | |
| 195 | check!(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 | |
| 201 | check!(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 | |
| 207 | check!(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 | |
| 213 | check!(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 | |
| 219 | check!(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 | |
| 225 | check!(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 | ||
| 6 | use std::num::NonZero; | |
| 7 | use std::ptr::NonNull; | |
| 8 | ||
| 9 | // CHECK-LABEL: nonnull ptr @read_unaligned_ptr(ptr{{.+}}%ptr) | |
| 10 | #[no_mangle] | |
| 11 | unsafe 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] | |
| 22 | unsafe 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] | |
| 33 | unsafe 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] | |
| 45 | unsafe 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))] | |
| 53 | struct HugeBuffer([u64; 1 << 10]); | |
| 54 | ||
| 55 | // CHECK-LABEL: void @read_unaligned_huge(ptr{{.+}}%_0, ptr{{.+}}%ptr) | |
| 56 | #[no_mangle] | |
| 57 | unsafe 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] | |
| 66 | unsafe 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 | |
| 7 | pub 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 | |
| 22 | pub 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 | ||
| 3 | fn 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 | ||
| 3 | fn 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 | ||
| 5 | type const N: usize = 2; | |
| 6 | ||
| 7 | //@ has 'foo/trait.CollectArray.html' | |
| 8 | //@ has - '//pre[@class="rust item-decl"]/code' '[A; N]' | |
| 9 | pub 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 | ||
| 5 | pub struct Foo; | |
| 6 | ||
| 7 | impl 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]' | |
| 13 | pub 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 @@ |
| 1 | 1 | error: 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 | |
| 3 | 3 | | |
| 4 | 4 | LL | asm!("", out("$r0") _); |
| 5 | 5 | | ^^^^^^^^^^^^ |
| 6 | 6 | |
| 7 | 7 | error: invalid register `$tp`: reserved for TLS |
| 8 | --> $DIR/bad-reg.rs:28:18 | |
| 8 | --> $DIR/bad-reg.rs:30:18 | |
| 9 | 9 | | |
| 10 | 10 | LL | asm!("", out("$tp") _); |
| 11 | 11 | | ^^^^^^^^^^^^ |
| 12 | 12 | |
| 13 | 13 | error: 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 | |
| 15 | 15 | | |
| 16 | 16 | LL | asm!("", out("$sp") _); |
| 17 | 17 | | ^^^^^^^^^^^^ |
| 18 | 18 | |
| 19 | 19 | error: invalid register `$r21`: reserved by the ABI |
| 20 | --> $DIR/bad-reg.rs:32:18 | |
| 20 | --> $DIR/bad-reg.rs:34:18 | |
| 21 | 21 | | |
| 22 | 22 | LL | asm!("", out("$r21") _); |
| 23 | 23 | | ^^^^^^^^^^^^^ |
| 24 | 24 | |
| 25 | 25 | error: 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 | |
| 27 | 27 | | |
| 28 | 28 | LL | asm!("", out("$fp") _); |
| 29 | 29 | | ^^^^^^^^^^^^ |
| 30 | 30 | |
| 31 | 31 | error: 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 | |
| 33 | 33 | | |
| 34 | 34 | LL | asm!("", out("$r31") _); |
| 35 | 35 | | ^^^^^^^^^^^^^ |
| 36 | 36 | |
| 37 | error: aborting due to 6 previous errors | |
| 37 | error[E0658]: register class `vreg` can only be used as a clobber in stable | |
| 38 | --> $DIR/bad-reg.rs:52:26 | |
| 39 | | | |
| 40 | LL | 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 | ||
| 47 | error[E0658]: register class `vreg` can only be used as a clobber in stable | |
| 48 | --> $DIR/bad-reg.rs:55:26 | |
| 49 | | | |
| 50 | LL | 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 | ||
| 57 | error[E0658]: register class `vreg` can only be used as a clobber in stable | |
| 58 | --> $DIR/bad-reg.rs:57:26 | |
| 59 | | | |
| 60 | LL | 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 | ||
| 67 | error[E0658]: register class `vreg` can only be used as a clobber in stable | |
| 68 | --> $DIR/bad-reg.rs:60:26 | |
| 69 | | | |
| 70 | LL | 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 | ||
| 77 | error[E0658]: register class `xreg` can only be used as a clobber in stable | |
| 78 | --> $DIR/bad-reg.rs:65:26 | |
| 79 | | | |
| 80 | LL | 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 | ||
| 87 | error[E0658]: register class `xreg` can only be used as a clobber in stable | |
| 88 | --> $DIR/bad-reg.rs:68:26 | |
| 89 | | | |
| 90 | LL | 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 | ||
| 97 | error[E0658]: register class `xreg` can only be used as a clobber in stable | |
| 98 | --> $DIR/bad-reg.rs:70:26 | |
| 99 | | | |
| 100 | LL | 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 | ||
| 107 | error[E0658]: register class `xreg` can only be used as a clobber in stable | |
| 108 | --> $DIR/bad-reg.rs:73:26 | |
| 109 | | | |
| 110 | LL | 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 | ||
| 117 | error[E0658]: register class `vreg` can only be used as a clobber in stable | |
| 118 | --> $DIR/bad-reg.rs:77:31 | |
| 119 | | | |
| 120 | LL | 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 | ||
| 127 | error[E0658]: register class `xreg` can only be used as a clobber in stable | |
| 128 | --> $DIR/bad-reg.rs:82:31 | |
| 129 | | | |
| 130 | LL | 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 | ||
| 137 | error[E0658]: register class `vreg` can only be used as a clobber in stable | |
| 138 | --> $DIR/bad-reg.rs:87:18 | |
| 139 | | | |
| 140 | LL | 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 | ||
| 147 | error[E0658]: register class `xreg` can only be used as a clobber in stable | |
| 148 | --> $DIR/bad-reg.rs:87:32 | |
| 149 | | | |
| 150 | LL | 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 | ||
| 157 | error[E0658]: type `f32` cannot be used with this register class in stable | |
| 158 | --> $DIR/bad-reg.rs:52:35 | |
| 159 | | | |
| 160 | LL | 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 | ||
| 167 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 168 | --> $DIR/bad-reg.rs:57:35 | |
| 169 | | | |
| 170 | LL | 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 | ||
| 177 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 178 | --> $DIR/bad-reg.rs:60:36 | |
| 179 | | | |
| 180 | LL | 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 | ||
| 187 | error[E0658]: type `f32` cannot be used with this register class in stable | |
| 188 | --> $DIR/bad-reg.rs:65:35 | |
| 189 | | | |
| 190 | LL | 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 | ||
| 197 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 198 | --> $DIR/bad-reg.rs:70:35 | |
| 199 | | | |
| 200 | LL | 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 | ||
| 207 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 208 | --> $DIR/bad-reg.rs:73:36 | |
| 209 | | | |
| 210 | LL | 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 | ||
| 217 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 218 | --> $DIR/bad-reg.rs:77:42 | |
| 219 | | | |
| 220 | LL | 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 | ||
| 227 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 228 | --> $DIR/bad-reg.rs:82:42 | |
| 229 | | | |
| 230 | LL | 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 | ||
| 237 | error[E0658]: type `f32` cannot be used with this register class in stable | |
| 238 | --> $DIR/bad-reg.rs:87:29 | |
| 239 | | | |
| 240 | LL | 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 | ||
| 247 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 248 | --> $DIR/bad-reg.rs:87:43 | |
| 249 | | | |
| 250 | LL | 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 | ||
| 257 | error: aborting due to 28 previous errors | |
| 38 | 258 | |
| 259 | For more information about this error, try `rustc --explain E0658`. |
tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32s.stderr+244-11| ... | ... | @@ -1,62 +1,295 @@ |
| 1 | 1 | error: 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 | |
| 3 | 3 | | |
| 4 | 4 | LL | asm!("", out("$r0") _); |
| 5 | 5 | | ^^^^^^^^^^^^ |
| 6 | 6 | |
| 7 | 7 | error: invalid register `$tp`: reserved for TLS |
| 8 | --> $DIR/bad-reg.rs:28:18 | |
| 8 | --> $DIR/bad-reg.rs:30:18 | |
| 9 | 9 | | |
| 10 | 10 | LL | asm!("", out("$tp") _); |
| 11 | 11 | | ^^^^^^^^^^^^ |
| 12 | 12 | |
| 13 | 13 | error: 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 | |
| 15 | 15 | | |
| 16 | 16 | LL | asm!("", out("$sp") _); |
| 17 | 17 | | ^^^^^^^^^^^^ |
| 18 | 18 | |
| 19 | 19 | error: invalid register `$r21`: reserved by the ABI |
| 20 | --> $DIR/bad-reg.rs:32:18 | |
| 20 | --> $DIR/bad-reg.rs:34:18 | |
| 21 | 21 | | |
| 22 | 22 | LL | asm!("", out("$r21") _); |
| 23 | 23 | | ^^^^^^^^^^^^^ |
| 24 | 24 | |
| 25 | 25 | error: 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 | |
| 27 | 27 | | |
| 28 | 28 | LL | asm!("", out("$fp") _); |
| 29 | 29 | | ^^^^^^^^^^^^ |
| 30 | 30 | |
| 31 | 31 | error: 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 | |
| 33 | 33 | | |
| 34 | 34 | LL | asm!("", out("$r31") _); |
| 35 | 35 | | ^^^^^^^^^^^^^ |
| 36 | 36 | |
| 37 | error[E0658]: register class `vreg` can only be used as a clobber in stable | |
| 38 | --> $DIR/bad-reg.rs:52:26 | |
| 39 | | | |
| 40 | LL | 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 | ||
| 47 | error[E0658]: register class `vreg` can only be used as a clobber in stable | |
| 48 | --> $DIR/bad-reg.rs:55:26 | |
| 49 | | | |
| 50 | LL | 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 | ||
| 57 | error[E0658]: register class `vreg` can only be used as a clobber in stable | |
| 58 | --> $DIR/bad-reg.rs:57:26 | |
| 59 | | | |
| 60 | LL | 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 | ||
| 67 | error[E0658]: register class `vreg` can only be used as a clobber in stable | |
| 68 | --> $DIR/bad-reg.rs:60:26 | |
| 69 | | | |
| 70 | LL | 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 | ||
| 77 | error[E0658]: register class `xreg` can only be used as a clobber in stable | |
| 78 | --> $DIR/bad-reg.rs:65:26 | |
| 79 | | | |
| 80 | LL | 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 | ||
| 87 | error[E0658]: register class `xreg` can only be used as a clobber in stable | |
| 88 | --> $DIR/bad-reg.rs:68:26 | |
| 89 | | | |
| 90 | LL | 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 | ||
| 97 | error[E0658]: register class `xreg` can only be used as a clobber in stable | |
| 98 | --> $DIR/bad-reg.rs:70:26 | |
| 99 | | | |
| 100 | LL | 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 | ||
| 107 | error[E0658]: register class `xreg` can only be used as a clobber in stable | |
| 108 | --> $DIR/bad-reg.rs:73:26 | |
| 109 | | | |
| 110 | LL | 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 | ||
| 117 | error[E0658]: register class `vreg` can only be used as a clobber in stable | |
| 118 | --> $DIR/bad-reg.rs:77:31 | |
| 119 | | | |
| 120 | LL | 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 | ||
| 127 | error[E0658]: register class `xreg` can only be used as a clobber in stable | |
| 128 | --> $DIR/bad-reg.rs:82:31 | |
| 129 | | | |
| 130 | LL | 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 | ||
| 137 | error[E0658]: register class `vreg` can only be used as a clobber in stable | |
| 138 | --> $DIR/bad-reg.rs:87:18 | |
| 139 | | | |
| 140 | LL | 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 | ||
| 147 | error[E0658]: register class `xreg` can only be used as a clobber in stable | |
| 148 | --> $DIR/bad-reg.rs:87:32 | |
| 149 | | | |
| 150 | LL | 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 | ||
| 37 | 157 | error: 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 | |
| 39 | 159 | | |
| 40 | 160 | LL | asm!("/* {} */", in(freg) f); |
| 41 | 161 | | ^^^^^^^^^^ |
| 42 | 162 | |
| 43 | 163 | error: 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 | |
| 45 | 165 | | |
| 46 | 166 | LL | asm!("/* {} */", out(freg) _); |
| 47 | 167 | | ^^^^^^^^^^^ |
| 48 | 168 | |
| 49 | 169 | error: 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 | |
| 51 | 171 | | |
| 52 | 172 | LL | asm!("/* {} */", in(freg) d); |
| 53 | 173 | | ^^^^^^^^^^ |
| 54 | 174 | |
| 55 | 175 | error: 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 | |
| 57 | 177 | | |
| 58 | 178 | LL | asm!("/* {} */", out(freg) d); |
| 59 | 179 | | ^^^^^^^^^^^ |
| 60 | 180 | |
| 61 | error: aborting due to 10 previous errors | |
| 181 | error[E0658]: type `f32` cannot be used with this register class in stable | |
| 182 | --> $DIR/bad-reg.rs:52:35 | |
| 183 | | | |
| 184 | LL | 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 | ||
| 191 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 192 | --> $DIR/bad-reg.rs:57:35 | |
| 193 | | | |
| 194 | LL | 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 | ||
| 201 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 202 | --> $DIR/bad-reg.rs:60:36 | |
| 203 | | | |
| 204 | LL | 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 | ||
| 211 | error[E0658]: type `f32` cannot be used with this register class in stable | |
| 212 | --> $DIR/bad-reg.rs:65:35 | |
| 213 | | | |
| 214 | LL | 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 | ||
| 221 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 222 | --> $DIR/bad-reg.rs:70:35 | |
| 223 | | | |
| 224 | LL | 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 | ||
| 231 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 232 | --> $DIR/bad-reg.rs:73:36 | |
| 233 | | | |
| 234 | LL | 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 | ||
| 241 | error: register class `freg` requires at least one of the following target features: d, f | |
| 242 | --> $DIR/bad-reg.rs:77:18 | |
| 243 | | | |
| 244 | LL | asm!("", in("$f0") f, in("$vr0") d); | |
| 245 | | ^^^^^^^^^^^ | |
| 246 | ||
| 247 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 248 | --> $DIR/bad-reg.rs:77:42 | |
| 249 | | | |
| 250 | LL | 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 | ||
| 257 | error: register class `freg` requires at least one of the following target features: d, f | |
| 258 | --> $DIR/bad-reg.rs:82:18 | |
| 259 | | | |
| 260 | LL | asm!("", in("$f0") f, in("$xr0") d); | |
| 261 | | ^^^^^^^^^^^ | |
| 262 | ||
| 263 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 264 | --> $DIR/bad-reg.rs:82:42 | |
| 265 | | | |
| 266 | LL | 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 | ||
| 273 | error[E0658]: type `f32` cannot be used with this register class in stable | |
| 274 | --> $DIR/bad-reg.rs:87:29 | |
| 275 | | | |
| 276 | LL | 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 | ||
| 283 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 284 | --> $DIR/bad-reg.rs:87:43 | |
| 285 | | | |
| 286 | LL | 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 | ||
| 293 | error: aborting due to 34 previous errors | |
| 62 | 294 | |
| 295 | For more information about this error, try `rustc --explain E0658`. |
tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr+31-7| ... | ... | @@ -1,38 +1,62 @@ |
| 1 | 1 | error: 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 | |
| 3 | 3 | | |
| 4 | 4 | LL | asm!("", out("$r0") _); |
| 5 | 5 | | ^^^^^^^^^^^^ |
| 6 | 6 | |
| 7 | 7 | error: invalid register `$tp`: reserved for TLS |
| 8 | --> $DIR/bad-reg.rs:28:18 | |
| 8 | --> $DIR/bad-reg.rs:30:18 | |
| 9 | 9 | | |
| 10 | 10 | LL | asm!("", out("$tp") _); |
| 11 | 11 | | ^^^^^^^^^^^^ |
| 12 | 12 | |
| 13 | 13 | error: 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 | |
| 15 | 15 | | |
| 16 | 16 | LL | asm!("", out("$sp") _); |
| 17 | 17 | | ^^^^^^^^^^^^ |
| 18 | 18 | |
| 19 | 19 | error: invalid register `$r21`: reserved by the ABI |
| 20 | --> $DIR/bad-reg.rs:32:18 | |
| 20 | --> $DIR/bad-reg.rs:34:18 | |
| 21 | 21 | | |
| 22 | 22 | LL | asm!("", out("$r21") _); |
| 23 | 23 | | ^^^^^^^^^^^^^ |
| 24 | 24 | |
| 25 | 25 | error: 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 | |
| 27 | 27 | | |
| 28 | 28 | LL | asm!("", out("$fp") _); |
| 29 | 29 | | ^^^^^^^^^^^^ |
| 30 | 30 | |
| 31 | 31 | error: 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 | |
| 33 | 33 | | |
| 34 | 34 | LL | asm!("", out("$r31") _); |
| 35 | 35 | | ^^^^^^^^^^^^^ |
| 36 | 36 | |
| 37 | error: aborting due to 6 previous errors | |
| 37 | error: register `$vr0` conflicts with register `$f0` | |
| 38 | --> $DIR/bad-reg.rs:77:31 | |
| 39 | | | |
| 40 | LL | asm!("", in("$f0") f, in("$vr0") d); | |
| 41 | | ----------- ^^^^^^^^^^^^ register `$vr0` | |
| 42 | | | | |
| 43 | | register `$f0` | |
| 44 | ||
| 45 | error: register `$xr0` conflicts with register `$f0` | |
| 46 | --> $DIR/bad-reg.rs:82:31 | |
| 47 | | | |
| 48 | LL | asm!("", in("$f0") f, in("$xr0") d); | |
| 49 | | ----------- ^^^^^^^^^^^^ register `$xr0` | |
| 50 | | | | |
| 51 | | register `$f0` | |
| 52 | ||
| 53 | error: register `$xr0` conflicts with register `$vr0` | |
| 54 | --> $DIR/bad-reg.rs:87:32 | |
| 55 | | | |
| 56 | LL | asm!("", in("$vr0") f, in("$xr0") d); | |
| 57 | | ------------ ^^^^^^^^^^^^ register `$xr0` | |
| 58 | | | | |
| 59 | | register `$vr0` | |
| 60 | ||
| 61 | error: aborting due to 9 previous errors | |
| 38 | 62 |
tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr+244-11| ... | ... | @@ -1,62 +1,295 @@ |
| 1 | 1 | error: 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 | |
| 3 | 3 | | |
| 4 | 4 | LL | asm!("", out("$r0") _); |
| 5 | 5 | | ^^^^^^^^^^^^ |
| 6 | 6 | |
| 7 | 7 | error: invalid register `$tp`: reserved for TLS |
| 8 | --> $DIR/bad-reg.rs:28:18 | |
| 8 | --> $DIR/bad-reg.rs:30:18 | |
| 9 | 9 | | |
| 10 | 10 | LL | asm!("", out("$tp") _); |
| 11 | 11 | | ^^^^^^^^^^^^ |
| 12 | 12 | |
| 13 | 13 | error: 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 | |
| 15 | 15 | | |
| 16 | 16 | LL | asm!("", out("$sp") _); |
| 17 | 17 | | ^^^^^^^^^^^^ |
| 18 | 18 | |
| 19 | 19 | error: invalid register `$r21`: reserved by the ABI |
| 20 | --> $DIR/bad-reg.rs:32:18 | |
| 20 | --> $DIR/bad-reg.rs:34:18 | |
| 21 | 21 | | |
| 22 | 22 | LL | asm!("", out("$r21") _); |
| 23 | 23 | | ^^^^^^^^^^^^^ |
| 24 | 24 | |
| 25 | 25 | error: 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 | |
| 27 | 27 | | |
| 28 | 28 | LL | asm!("", out("$fp") _); |
| 29 | 29 | | ^^^^^^^^^^^^ |
| 30 | 30 | |
| 31 | 31 | error: 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 | |
| 33 | 33 | | |
| 34 | 34 | LL | asm!("", out("$r31") _); |
| 35 | 35 | | ^^^^^^^^^^^^^ |
| 36 | 36 | |
| 37 | error[E0658]: register class `vreg` can only be used as a clobber in stable | |
| 38 | --> $DIR/bad-reg.rs:52:26 | |
| 39 | | | |
| 40 | LL | 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 | ||
| 47 | error[E0658]: register class `vreg` can only be used as a clobber in stable | |
| 48 | --> $DIR/bad-reg.rs:55:26 | |
| 49 | | | |
| 50 | LL | 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 | ||
| 57 | error[E0658]: register class `vreg` can only be used as a clobber in stable | |
| 58 | --> $DIR/bad-reg.rs:57:26 | |
| 59 | | | |
| 60 | LL | 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 | ||
| 67 | error[E0658]: register class `vreg` can only be used as a clobber in stable | |
| 68 | --> $DIR/bad-reg.rs:60:26 | |
| 69 | | | |
| 70 | LL | 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 | ||
| 77 | error[E0658]: register class `xreg` can only be used as a clobber in stable | |
| 78 | --> $DIR/bad-reg.rs:65:26 | |
| 79 | | | |
| 80 | LL | 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 | ||
| 87 | error[E0658]: register class `xreg` can only be used as a clobber in stable | |
| 88 | --> $DIR/bad-reg.rs:68:26 | |
| 89 | | | |
| 90 | LL | 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 | ||
| 97 | error[E0658]: register class `xreg` can only be used as a clobber in stable | |
| 98 | --> $DIR/bad-reg.rs:70:26 | |
| 99 | | | |
| 100 | LL | 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 | ||
| 107 | error[E0658]: register class `xreg` can only be used as a clobber in stable | |
| 108 | --> $DIR/bad-reg.rs:73:26 | |
| 109 | | | |
| 110 | LL | 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 | ||
| 117 | error[E0658]: register class `vreg` can only be used as a clobber in stable | |
| 118 | --> $DIR/bad-reg.rs:77:31 | |
| 119 | | | |
| 120 | LL | 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 | ||
| 127 | error[E0658]: register class `xreg` can only be used as a clobber in stable | |
| 128 | --> $DIR/bad-reg.rs:82:31 | |
| 129 | | | |
| 130 | LL | 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 | ||
| 137 | error[E0658]: register class `vreg` can only be used as a clobber in stable | |
| 138 | --> $DIR/bad-reg.rs:87:18 | |
| 139 | | | |
| 140 | LL | 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 | ||
| 147 | error[E0658]: register class `xreg` can only be used as a clobber in stable | |
| 148 | --> $DIR/bad-reg.rs:87:32 | |
| 149 | | | |
| 150 | LL | 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 | ||
| 37 | 157 | error: 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 | |
| 39 | 159 | | |
| 40 | 160 | LL | asm!("/* {} */", in(freg) f); |
| 41 | 161 | | ^^^^^^^^^^ |
| 42 | 162 | |
| 43 | 163 | error: 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 | |
| 45 | 165 | | |
| 46 | 166 | LL | asm!("/* {} */", out(freg) _); |
| 47 | 167 | | ^^^^^^^^^^^ |
| 48 | 168 | |
| 49 | 169 | error: 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 | |
| 51 | 171 | | |
| 52 | 172 | LL | asm!("/* {} */", in(freg) d); |
| 53 | 173 | | ^^^^^^^^^^ |
| 54 | 174 | |
| 55 | 175 | error: 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 | |
| 57 | 177 | | |
| 58 | 178 | LL | asm!("/* {} */", out(freg) d); |
| 59 | 179 | | ^^^^^^^^^^^ |
| 60 | 180 | |
| 61 | error: aborting due to 10 previous errors | |
| 181 | error[E0658]: type `f32` cannot be used with this register class in stable | |
| 182 | --> $DIR/bad-reg.rs:52:35 | |
| 183 | | | |
| 184 | LL | 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 | ||
| 191 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 192 | --> $DIR/bad-reg.rs:57:35 | |
| 193 | | | |
| 194 | LL | 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 | ||
| 201 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 202 | --> $DIR/bad-reg.rs:60:36 | |
| 203 | | | |
| 204 | LL | 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 | ||
| 211 | error[E0658]: type `f32` cannot be used with this register class in stable | |
| 212 | --> $DIR/bad-reg.rs:65:35 | |
| 213 | | | |
| 214 | LL | 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 | ||
| 221 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 222 | --> $DIR/bad-reg.rs:70:35 | |
| 223 | | | |
| 224 | LL | 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 | ||
| 231 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 232 | --> $DIR/bad-reg.rs:73:36 | |
| 233 | | | |
| 234 | LL | 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 | ||
| 241 | error: register class `freg` requires at least one of the following target features: d, f | |
| 242 | --> $DIR/bad-reg.rs:77:18 | |
| 243 | | | |
| 244 | LL | asm!("", in("$f0") f, in("$vr0") d); | |
| 245 | | ^^^^^^^^^^^ | |
| 246 | ||
| 247 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 248 | --> $DIR/bad-reg.rs:77:42 | |
| 249 | | | |
| 250 | LL | 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 | ||
| 257 | error: register class `freg` requires at least one of the following target features: d, f | |
| 258 | --> $DIR/bad-reg.rs:82:18 | |
| 259 | | | |
| 260 | LL | asm!("", in("$f0") f, in("$xr0") d); | |
| 261 | | ^^^^^^^^^^^ | |
| 262 | ||
| 263 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 264 | --> $DIR/bad-reg.rs:82:42 | |
| 265 | | | |
| 266 | LL | 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 | ||
| 273 | error[E0658]: type `f32` cannot be used with this register class in stable | |
| 274 | --> $DIR/bad-reg.rs:87:29 | |
| 275 | | | |
| 276 | LL | 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 | ||
| 283 | error[E0658]: type `f64` cannot be used with this register class in stable | |
| 284 | --> $DIR/bad-reg.rs:87:43 | |
| 285 | | | |
| 286 | LL | 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 | ||
| 293 | error: aborting due to 34 previous errors | |
| 62 | 294 | |
| 295 | For more information about this error, try `rustc --explain E0658`. |
tests/ui/asm/loongarch/bad-reg.rs+46-1| ... | ... | @@ -4,12 +4,14 @@ |
| 4 | 4 | //@[loongarch32_ilp32d] needs-llvm-components: loongarch |
| 5 | 5 | //@[loongarch32_ilp32s] compile-flags: --target loongarch32-unknown-none-softfloat |
| 6 | 6 | //@[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 | |
| 8 | 8 | //@[loongarch64_lp64d] needs-llvm-components: loongarch |
| 9 | 9 | //@[loongarch64_lp64s] compile-flags: --target loongarch64-unknown-none-softfloat |
| 10 | 10 | //@[loongarch64_lp64s] needs-llvm-components: loongarch |
| 11 | 11 | //@ ignore-backends: gcc |
| 12 | 12 | |
| 13 | #![cfg_attr(loongarch64_lp64d, feature(asm_experimental_reg))] | |
| 14 | ||
| 13 | 15 | #![crate_type = "lib"] |
| 14 | 16 | #![feature(no_core)] |
| 15 | 17 | #![no_core] |
| ... | ... | @@ -45,5 +47,48 @@ fn f() { |
| 45 | 47 | //[loongarch32_ilp32s,loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f |
| 46 | 48 | asm!("/* {} */", out(freg) d); |
| 47 | 49 | //[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` | |
| 48 | 93 | } |
| 49 | 94 | } |