authorbors <bors@rust-lang.org> 2025-09-22 11:15:49 UTC
committerbors <bors@rust-lang.org> 2025-09-22 11:15:49 UTC
log29005cb128e6d447e6bd9c110c9a684665f95985
treea25020539ef1a6939c6298a4f77126720d2168d9
parent9f32ccf35fb877270bc44a86a126440f04d676d0
parent8f80707bc5fa74992bdc2dc201a6461860769f28

Auto merge of #146879 - Zalathar:rollup-vm97j8b, r=Zalathar

Rollup of 9 pull requests Successful merges: - rust-lang/rust#145411 (regression test for Cow<[u8]> layout) - rust-lang/rust#146397 (std_detect on Darwin AArch64: update features) - rust-lang/rust#146791 (emit attribute for readonly non-pure inline assembly) - rust-lang/rust#146831 (Support ctr and lr as clobber-only registers in PowerPC inline assembly) - rust-lang/rust#146838 (Introduce "wrapper" helpers to rustdoc) - rust-lang/rust#146845 (Add self-profile events for target-machine creation) - rust-lang/rust#146846 (btree InternalNode::new safety comments) - rust-lang/rust#146858 (Make mips64el-unknown-linux-muslabi64 link dynamically) - rust-lang/rust#146878 (assert_unsafe_precondition: fix some incorrect check_language_ub) r? `@ghost` `@rustbot` modify labels: rollup

30 files changed, 948 insertions(+), 462 deletions(-)

compiler/rustc_codegen_gcc/src/asm.rs+12-4
......@@ -698,8 +698,12 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str {
698698 InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
699699 InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
700700 InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => "v",
701 InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
702 | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
701 InlineAsmRegClass::PowerPC(
702 PowerPCInlineAsmRegClass::cr
703 | PowerPCInlineAsmRegClass::ctr
704 | PowerPCInlineAsmRegClass::lr
705 | PowerPCInlineAsmRegClass::xer,
706 ) => {
703707 unreachable!("clobber-only")
704708 }
705709 InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => "r",
......@@ -777,8 +781,12 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
777781 InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => {
778782 cx.type_vector(cx.type_i32(), 4)
779783 }
780 InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
781 | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
784 InlineAsmRegClass::PowerPC(
785 PowerPCInlineAsmRegClass::cr
786 | PowerPCInlineAsmRegClass::ctr
787 | PowerPCInlineAsmRegClass::lr
788 | PowerPCInlineAsmRegClass::xer,
789 ) => {
782790 unreachable!("clobber-only")
783791 }
784792 InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(),
compiler/rustc_codegen_llvm/src/asm.rs+14-4
......@@ -340,8 +340,8 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
340340 attrs.push(llvm::AttributeKind::WillReturn.create_attr(self.cx.llcx));
341341 } else if options.contains(InlineAsmOptions::NOMEM) {
342342 attrs.push(llvm::MemoryEffects::InaccessibleMemOnly.create_attr(self.cx.llcx));
343 } else {
344 // LLVM doesn't have an attribute to represent ReadOnly + SideEffect
343 } else if options.contains(InlineAsmOptions::READONLY) {
344 attrs.push(llvm::MemoryEffects::ReadOnlyNotPure.create_attr(self.cx.llcx));
345345 }
346346 attributes::apply_to_callsite(result, llvm::AttributePlace::Function, &{ attrs });
347347
......@@ -662,7 +662,12 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
662662 PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
663663 PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
664664 PowerPC(PowerPCInlineAsmRegClass::vreg) => "v",
665 PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => {
665 PowerPC(
666 PowerPCInlineAsmRegClass::cr
667 | PowerPCInlineAsmRegClass::ctr
668 | PowerPCInlineAsmRegClass::lr
669 | PowerPCInlineAsmRegClass::xer,
670 ) => {
666671 unreachable!("clobber-only")
667672 }
668673 RiscV(RiscVInlineAsmRegClass::reg) => "r",
......@@ -830,7 +835,12 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
830835 PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(),
831836 PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(),
832837 PowerPC(PowerPCInlineAsmRegClass::vreg) => cx.type_vector(cx.type_i32(), 4),
833 PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => {
838 PowerPC(
839 PowerPCInlineAsmRegClass::cr
840 | PowerPCInlineAsmRegClass::ctr
841 | PowerPCInlineAsmRegClass::lr
842 | PowerPCInlineAsmRegClass::xer,
843 ) => {
834844 unreachable!("clobber-only")
835845 }
836846 RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(),
compiler/rustc_codegen_llvm/src/back/write.rs+10
......@@ -204,6 +204,9 @@ pub(crate) fn target_machine_factory(
204204 optlvl: config::OptLevel,
205205 target_features: &[String],
206206) -> TargetMachineFactoryFn<LlvmCodegenBackend> {
207 // Self-profile timer for creating a _factory_.
208 let _prof_timer = sess.prof.generic_activity("target_machine_factory");
209
207210 let reloc_model = to_llvm_relocation_model(sess.relocation_model());
208211
209212 let (opt_level, _) = to_llvm_opt_settings(optlvl);
......@@ -259,6 +262,9 @@ pub(crate) fn target_machine_factory(
259262 .into_string()
260263 .unwrap_or_default();
261264 let command_line_args = quote_command_line_args(&sess.expanded_args);
265 // Self-profile counter for the number of bytes produced by command-line quoting.
266 // Values are summed, so the summary result is cumulative across all TM factories.
267 sess.prof.artifact_size("quoted_command_line_args", "-", command_line_args.len() as u64);
262268
263269 let debuginfo_compression = sess.opts.debuginfo_compression.to_string();
264270 match sess.opts.debuginfo_compression {
......@@ -281,7 +287,11 @@ pub(crate) fn target_machine_factory(
281287
282288 let use_wasm_eh = wants_wasm_eh(sess);
283289
290 let prof = SelfProfilerRef::clone(&sess.prof);
284291 Arc::new(move |config: TargetMachineFactoryConfig| {
292 // Self-profile timer for invoking a factory to create a target machine.
293 let _prof_timer = prof.generic_activity("target_machine_factory_inner");
294
285295 let path_to_cstring_helper = |path: Option<PathBuf>| -> CString {
286296 let path = path.unwrap_or_default();
287297 let path = path_mapping
compiler/rustc_codegen_llvm/src/llvm/ffi.rs+1
......@@ -710,6 +710,7 @@ pub(crate) enum MemoryEffects {
710710 None,
711711 ReadOnly,
712712 InaccessibleMemOnly,
713 ReadOnlyNotPure,
713714}
714715
715716/// LLVMOpcode
compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp+5
......@@ -553,6 +553,7 @@ enum class LLVMRustMemoryEffects {
553553 None,
554554 ReadOnly,
555555 InaccessibleMemOnly,
556 ReadOnlyNotPure,
556557};
557558
558559extern "C" LLVMAttributeRef
......@@ -568,6 +569,10 @@ LLVMRustCreateMemoryEffectsAttr(LLVMContextRef C,
568569 case LLVMRustMemoryEffects::InaccessibleMemOnly:
569570 return wrap(Attribute::getWithMemoryEffects(
570571 *unwrap(C), MemoryEffects::inaccessibleMemOnly()));
572 case LLVMRustMemoryEffects::ReadOnlyNotPure:
573 return wrap(Attribute::getWithMemoryEffects(
574 *unwrap(C),
575 MemoryEffects::readOnly() | MemoryEffects::inaccessibleMemOnly()));
571576 default:
572577 report_fatal_error("bad MemoryEffects.");
573578 }
compiler/rustc_span/src/symbol.rs+2
......@@ -794,6 +794,7 @@ symbols! {
794794 ctlz,
795795 ctlz_nonzero,
796796 ctpop,
797 ctr,
797798 cttz,
798799 cttz_nonzero,
799800 custom_attribute,
......@@ -1333,6 +1334,7 @@ symbols! {
13331334 loongarch_target_feature,
13341335 loop_break_value,
13351336 loop_match,
1337 lr,
13361338 lt,
13371339 m68k_target_feature,
13381340 macro_at_most_once_rep,
compiler/rustc_target/src/asm/mod.rs+3-2
......@@ -1260,11 +1260,12 @@ impl InlineAsmClobberAbi {
12601260 v8, v9, v10, v11, v12, v13, v14,
12611261 v15, v16, v17, v18, v19,
12621262
1263 // cr0-cr1, cr5-cr7, xer
1263 // cr0-cr1, cr5-cr7, ctr, lr, xer
12641264 cr0, cr1,
12651265 cr5, cr6, cr7,
1266 ctr,
1267 lr,
12661268 xer,
1267 // lr and ctr are reserved
12681269 }
12691270 },
12701271 InlineAsmClobberAbi::S390x => clobbered_regs! {
compiler/rustc_target/src/asm/powerpc.rs+7-5
......@@ -13,6 +13,8 @@ def_reg_class! {
1313 freg,
1414 vreg,
1515 cr,
16 ctr,
17 lr,
1618 xer,
1719 }
1820}
......@@ -56,7 +58,7 @@ impl PowerPCInlineAsmRegClass {
5658 altivec: VecI8(16), VecI16(8), VecI32(4), VecF32(4);
5759 vsx: F32, F64, VecI64(2), VecF64(2);
5860 },
59 Self::cr | Self::xer => &[],
61 Self::cr | Self::ctr | Self::lr | Self::xer => &[],
6062 }
6163 }
6264}
......@@ -195,6 +197,8 @@ def_regs! {
195197 cr5: cr = ["cr5"],
196198 cr6: cr = ["cr6"],
197199 cr7: cr = ["cr7"],
200 ctr: ctr = ["ctr"],
201 lr: lr = ["lr"],
198202 xer: xer = ["xer"],
199203 #error = ["r1", "1", "sp"] =>
200204 "the stack pointer cannot be used as an operand for inline asm",
......@@ -206,10 +210,6 @@ def_regs! {
206210 "r30 is used internally by LLVM and cannot be used as an operand for inline asm",
207211 #error = ["r31", "31", "fp"] =>
208212 "the frame pointer cannot be used as an operand for inline asm",
209 #error = ["lr"] =>
210 "the link register cannot be used as an operand for inline asm",
211 #error = ["ctr"] =>
212 "the counter register cannot be used as an operand for inline asm",
213213 #error = ["vrsave"] =>
214214 "the vrsave register cannot be used as an operand for inline asm",
215215 }
......@@ -247,6 +247,8 @@ impl PowerPCInlineAsmReg {
247247 (v24, "24"), (v25, "25"), (v26, "26"), (v27, "27"), (v28, "28"), (v29, "29"), (v30, "30"), (v31, "31");
248248 (cr, "cr");
249249 (cr0, "0"), (cr1, "1"), (cr2, "2"), (cr3, "3"), (cr4, "4"), (cr5, "5"), (cr6, "6"), (cr7, "7");
250 (ctr, "ctr");
251 (lr, "lr");
250252 (xer, "xer");
251253 }
252254 }
compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs-2
......@@ -5,8 +5,6 @@ pub(crate) fn target() -> Target {
55 base.cpu = "mips64r2".into();
66 base.features = "+mips64r2,+xgot".into();
77 base.max_atomic_width = Some(64);
8 // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
9 base.crt_static_default = true;
108 Target {
119 // LLVM doesn't recognize "muslabi64" yet.
1210 llvm_target: "mips64el-unknown-linux-musl".into(),
library/alloc/src/collections/btree/node.rs+3-2
......@@ -117,10 +117,11 @@ impl<K, V> InternalNode<K, V> {
117117 /// initialized and valid edge. This function does not set up
118118 /// such an edge.
119119 unsafe fn new<A: Allocator + Clone>(alloc: A) -> Box<Self, A> {
120 let mut node = Box::<Self, _>::new_uninit_in(alloc);
120121 unsafe {
121 let mut node = Box::<Self, _>::new_uninit_in(alloc);
122 // We only need to initialize the data; the edges are MaybeUninit.
122 // SAFETY: argument points to the `node.data` `LeafNode`
123123 LeafNode::init(&raw mut (*node.as_mut_ptr()).data);
124 // SAFETY: `node.data` was just initialized and `node.edges` is MaybeUninit.
124125 node.assume_init()
125126 }
126127 }
library/core/src/ascii/ascii_char.rs+1-1
......@@ -515,7 +515,7 @@ impl AsciiChar {
515515 #[track_caller]
516516 pub const unsafe fn digit_unchecked(d: u8) -> Self {
517517 assert_unsafe_precondition!(
518 check_language_ub,
518 check_library_ub,
519519 "`ascii::Char::digit_unchecked` input cannot exceed 9.",
520520 (d: u8 = d) => d < 10
521521 );
library/core/src/num/int_macros.rs+3-3
......@@ -1460,8 +1460,8 @@ macro_rules! int_impl {
14601460 #[inline]
14611461 pub const unsafe fn unchecked_exact_shl(self, rhs: u32) -> $SelfT {
14621462 assert_unsafe_precondition!(
1463 check_language_ub,
1464 concat!(stringify!($SelfT), "::unchecked_exact_shl cannot shift out non-zero bits"),
1463 check_library_ub,
1464 concat!(stringify!($SelfT), "::unchecked_exact_shl cannot shift out bits that would change the value of the first bit"),
14651465 (
14661466 zeros: u32 = self.leading_zeros(),
14671467 ones: u32 = self.leading_ones(),
......@@ -1638,7 +1638,7 @@ macro_rules! int_impl {
16381638 #[inline]
16391639 pub const unsafe fn unchecked_exact_shr(self, rhs: u32) -> $SelfT {
16401640 assert_unsafe_precondition!(
1641 check_language_ub,
1641 check_library_ub,
16421642 concat!(stringify!($SelfT), "::unchecked_exact_shr cannot shift out non-zero bits"),
16431643 (
16441644 zeros: u32 = self.trailing_zeros(),
library/core/src/num/uint_macros.rs+2-2
......@@ -1865,7 +1865,7 @@ macro_rules! uint_impl {
18651865 #[inline]
18661866 pub const unsafe fn unchecked_exact_shl(self, rhs: u32) -> $SelfT {
18671867 assert_unsafe_precondition!(
1868 check_language_ub,
1868 check_library_ub,
18691869 concat!(stringify!($SelfT), "::exact_shl_unchecked cannot shift out non-zero bits"),
18701870 (
18711871 zeros: u32 = self.leading_zeros(),
......@@ -2037,7 +2037,7 @@ macro_rules! uint_impl {
20372037 #[inline]
20382038 pub const unsafe fn unchecked_exact_shr(self, rhs: u32) -> $SelfT {
20392039 assert_unsafe_precondition!(
2040 check_language_ub,
2040 check_library_ub,
20412041 concat!(stringify!($SelfT), "::exact_shr_unchecked cannot shift out non-zero bits"),
20422042 (
20432043 zeros: u32 = self.trailing_zeros(),
library/core/src/slice/index.rs+1-1
......@@ -233,7 +233,7 @@ unsafe impl<T> const SliceIndex<[T]> for usize {
233233 #[track_caller]
234234 unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
235235 assert_unsafe_precondition!(
236 check_language_ub,
236 check_language_ub, // okay because of the `assume` below
237237 "slice::get_unchecked requires that the index is within the slice",
238238 (this: usize = self, len: usize = slice.len()) => this < len
239239 );
library/core/src/ub_checks.rs+3-2
......@@ -21,8 +21,9 @@ use crate::intrinsics::{self, const_eval_select};
2121/// slow down const-eval/Miri and we'll get the panic message instead of the interpreter's nice
2222/// diagnostic, but our ability to detect UB is unchanged.
2323/// But if `check_language_ub` is used when the check is actually for library UB, the check is
24/// omitted in const-eval/Miri and thus if we eventually execute language UB which relies on the
25/// library UB, the backtrace Miri reports may be far removed from original cause.
24/// omitted in const-eval/Miri and thus UB might occur undetected. Even if we eventually execute
25/// language UB which relies on the library UB, the backtrace Miri reports may be far removed from
26/// original cause.
2627///
2728/// These checks are behind a condition which is evaluated at codegen time, not expansion time like
2829/// [`debug_assert`]. This means that a standard library built with optimizations and debug
library/std_detect/src/detect/os/darwin/aarch64.rs+17-5
......@@ -37,24 +37,25 @@ pub(crate) fn detect_features() -> cache::Initializer {
3737 // Armv8.0 features not using the standard identifiers
3838 let fp = _sysctlbyname(c"hw.optional.floatingpoint");
3939 let asimd = _sysctlbyname(c"hw.optional.AdvSIMD");
40 let crc = _sysctlbyname(c"hw.optional.armv8_crc32");
40 let crc_old = _sysctlbyname(c"hw.optional.armv8_crc32");
4141
4242 // Armv8 and Armv9 features using the standard identifiers
4343 let aes = _sysctlbyname(c"hw.optional.arm.FEAT_AES");
4444 let bf16 = _sysctlbyname(c"hw.optional.arm.FEAT_BF16");
4545 let bti = _sysctlbyname(c"hw.optional.arm.FEAT_BTI");
46 let crc = _sysctlbyname(c"hw.optional.arm.FEAT_CRC32");
4647 let cssc = _sysctlbyname(c"hw.optional.arm.FEAT_CSSC");
4748 let dit = _sysctlbyname(c"hw.optional.arm.FEAT_DIT");
49 let dotprod = _sysctlbyname(c"hw.optional.arm.FEAT_DotProd");
4850 let dpb = _sysctlbyname(c"hw.optional.arm.FEAT_DPB");
4951 let dpb2 = _sysctlbyname(c"hw.optional.arm.FEAT_DPB2");
50 let dotprod = _sysctlbyname(c"hw.optional.arm.FEAT_DotProd");
5152 let ecv = _sysctlbyname(c"hw.optional.arm.FEAT_ECV");
5253 let fcma = _sysctlbyname(c"hw.optional.arm.FEAT_FCMA");
5354 let fhm = _sysctlbyname(c"hw.optional.arm.FEAT_FHM");
54 let fp16 = _sysctlbyname(c"hw.optional.arm.FEAT_FP16");
55 let frintts = _sysctlbyname(c"hw.optional.arm.FEAT_FRINTTS");
5655 let flagm = _sysctlbyname(c"hw.optional.arm.FEAT_FlagM");
5756 let flagm2 = _sysctlbyname(c"hw.optional.arm.FEAT_FlagM2");
57 let fp16 = _sysctlbyname(c"hw.optional.arm.FEAT_FP16");
58 let frintts = _sysctlbyname(c"hw.optional.arm.FEAT_FRINTTS");
5859 let hbc = _sysctlbyname(c"hw.optional.arm.FEAT_HBC");
5960 let i8mm = _sysctlbyname(c"hw.optional.arm.FEAT_I8MM");
6061 let jsconv = _sysctlbyname(c"hw.optional.arm.FEAT_JSCVT");
......@@ -62,6 +63,8 @@ pub(crate) fn detect_features() -> cache::Initializer {
6263 let rcpc2 = _sysctlbyname(c"hw.optional.arm.FEAT_LRCPC2");
6364 let lse = _sysctlbyname(c"hw.optional.arm.FEAT_LSE");
6465 let lse2 = _sysctlbyname(c"hw.optional.arm.FEAT_LSE2");
66 let mte = _sysctlbyname(c"hw.optional.arm.FEAT_MTE");
67 let mte2 = _sysctlbyname(c"hw.optional.arm.FEAT_MTE2");
6568 let pauth = _sysctlbyname(c"hw.optional.arm.FEAT_PAuth");
6669 let pmull = _sysctlbyname(c"hw.optional.arm.FEAT_PMULL");
6770 let rdm = _sysctlbyname(c"hw.optional.arm.FEAT_RDM");
......@@ -72,6 +75,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
7275 let sha512 = _sysctlbyname(c"hw.optional.arm.FEAT_SHA512");
7376 let sme = _sysctlbyname(c"hw.optional.arm.FEAT_SME");
7477 let sme2 = _sysctlbyname(c"hw.optional.arm.FEAT_SME2");
78 let sme2p1 = _sysctlbyname(c"hw.optional.arm.FEAT_SME2p1");
7579 let sme_f64f64 = _sysctlbyname(c"hw.optional.arm.FEAT_SME_F64F64");
7680 let sme_i16i64 = _sysctlbyname(c"hw.optional.arm.FEAT_SME_I16I64");
7781 let ssbs = _sysctlbyname(c"hw.optional.arm.FEAT_SSBS");
......@@ -87,6 +91,12 @@ pub(crate) fn detect_features() -> cache::Initializer {
8791 let ebf16 = _sysctlbyname(c"hw.optional.arm.FEAT_EBF16");
8892 let fpac = _sysctlbyname(c"hw.optional.arm.FEAT_FPAC");
8993 let fpaccombine = _sysctlbyname(c"hw.optional.arm.FEAT_FPACCOMBINE");
94 let mte_async = _sysctlbyname(c"hw.optional.arm.FEAT_MTE_ASYNC");
95 let mte_canonical_tags = _sysctlbyname(c"hw.optional.arm.FEAT_MTE_CANONICAL_TAGS");
96 let mte_no_address_tags = _sysctlbyname(c"hw.optional.arm.FEAT_MTE_NO_ADDRESS_TAGS");
97 let mte_store_only = _sysctlbyname(c"hw.optional.arm.FEAT_MTE_STORE_ONLY");
98 let mte3 = _sysctlbyname(c"hw.optional.arm.FEAT_MTE3");
99 let mte4 = _sysctlbyname(c"hw.optional.arm.FEAT_MTE4");
90100 let pacimp = _sysctlbyname(c"hw.optional.arm.FEAT_PACIMP");
91101 let pauth2 = _sysctlbyname(c"hw.optional.arm.FEAT_PAuth2");
92102 let rpres = _sysctlbyname(c"hw.optional.arm.FEAT_RPRES");
......@@ -111,7 +121,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
111121 enable_feature(Feature::asimd, asimd);
112122 enable_feature(Feature::bf16, bf16);
113123 enable_feature(Feature::bti, bti);
114 enable_feature(Feature::crc, crc);
124 enable_feature(Feature::crc, crc_old || crc);
115125 enable_feature(Feature::cssc, cssc);
116126 enable_feature(Feature::dit, dit);
117127 enable_feature(Feature::dotprod, dotprod);
......@@ -130,6 +140,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
130140 enable_feature(Feature::jsconv, jsconv);
131141 enable_feature(Feature::lse, lse);
132142 enable_feature(Feature::lse2, lse2);
143 enable_feature(Feature::mte, mte && mte2);
133144 enable_feature(Feature::paca, pauth);
134145 enable_feature(Feature::pacg, pauth);
135146 enable_feature(Feature::pmull, aes && pmull);
......@@ -141,6 +152,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
141152 enable_feature(Feature::sha3, sha512 && sha3 && asimd);
142153 enable_feature(Feature::sme, sme);
143154 enable_feature(Feature::sme2, sme2);
155 enable_feature(Feature::sme2p1, sme2p1);
144156 enable_feature(Feature::sme_f64f64, sme_f64f64);
145157 enable_feature(Feature::sme_i16i64, sme_i16i64);
146158 enable_feature(Feature::ssbs, ssbs);
src/doc/unstable-book/src/language-features/asm-experimental-arch.md+4-2
......@@ -36,6 +36,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
3636| PowerPC | `freg` | `f[0-31]` | `f` |
3737| PowerPC | `vreg` | `v[0-31]` | `v` |
3838| PowerPC | `cr` | `cr[0-7]`, `cr` | Only clobbers |
39| PowerPC | `ctr` | `ctr` | Only clobbers |
40| PowerPC | `lr` | `lr` | Only clobbers |
3941| PowerPC | `xer` | `xer` | Only clobbers |
4042| wasm32 | `local` | None\* | `r` |
4143| BPF | `reg` | `r[0-10]` | `r` |
......@@ -78,6 +80,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
7880| PowerPC | `vreg` | `altivec` | `i8x16`, `i16x8`, `i32x4`, `f32x4` |
7981| PowerPC | `vreg` | `vsx` | `f32`, `f64`, `i64x2`, `f64x2` |
8082| PowerPC | `cr` | N/A | Only clobbers |
83| PowerPC | `ctr` | N/A | Only clobbers |
84| PowerPC | `lr` | N/A | Only clobbers |
8185| PowerPC | `xer` | N/A | Only clobbers |
8286| wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64` |
8387| BPF | `reg` | None | `i8` `i16` `i32` `i64` |
......@@ -150,8 +154,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
150154| MIPS | `$ra` | Return address cannot be used as inputs or outputs. |
151155| Hexagon | `lr` | This is the link register which cannot be used as an input or output. |
152156| PowerPC | `r2`, `r13` | These are system reserved registers. |
153| PowerPC | `lr` | The link register cannot be used as an input or output. |
154| PowerPC | `ctr` | The counter register cannot be used as an input or output. |
155157| PowerPC | `vrsave` | The vrsave register cannot be used as an input or output. |
156158| AVR | `r0`, `r1`, `r1r0` | Due to an issue in LLVM, the `r0` and `r1` registers cannot be used as inputs or outputs. If modified, they must be restored to their original values before the end of the block. |
157159|MSP430 | `r0`, `r2`, `r3` | These are the program counter, status register, and constant generator respectively. Neither the status register nor constant generator can be written to. |
src/librustdoc/clean/cfg.rs+30-48
......@@ -3,16 +3,16 @@
33// FIXME: Once the portability lint RFC is implemented (see tracking issue #41619),
44// switch to use those structures instead.
55
6use std::fmt::{self, Write};
7use std::{mem, ops};
6use std::{fmt, mem, ops};
87
8use itertools::Either;
99use rustc_ast::{LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit};
1010use rustc_data_structures::fx::FxHashSet;
1111use rustc_session::parse::ParseSess;
1212use rustc_span::Span;
1313use rustc_span::symbol::{Symbol, sym};
1414
15use crate::display::Joined as _;
15use crate::display::{Joined as _, MaybeDisplay, Wrapped};
1616use crate::html::escape::Escape;
1717
1818#[cfg(test)]
......@@ -376,27 +376,20 @@ impl Format {
376376 Format::LongPlain => false,
377377 }
378378 }
379
380 fn escape(self, s: &str) -> impl fmt::Display {
381 if self.is_html() { Either::Left(Escape(s)) } else { Either::Right(s) }
382 }
379383}
380384
381385/// Pretty-print wrapper for a `Cfg`. Also indicates what form of rendering should be used.
382386struct Display<'a>(&'a Cfg, Format);
383387
384fn write_with_opt_paren<T: fmt::Display>(
385 fmt: &mut fmt::Formatter<'_>,
386 has_paren: bool,
387 obj: T,
388) -> fmt::Result {
389 if has_paren {
390 fmt.write_char('(')?;
391 }
392 obj.fmt(fmt)?;
393 if has_paren {
394 fmt.write_char(')')?;
388impl Display<'_> {
389 fn code_wrappers(&self) -> Wrapped<&'static str> {
390 if self.1.is_html() { Wrapped::with("<code>", "</code>") } else { Wrapped::with("`", "`") }
395391 }
396 Ok(())
397}
398392
399impl Display<'_> {
400393 fn display_sub_cfgs(
401394 &self,
402395 fmt: &mut fmt::Formatter<'_>,
......@@ -427,20 +420,17 @@ impl Display<'_> {
427420 sub_cfgs
428421 .iter()
429422 .map(|sub_cfg| {
430 fmt::from_fn(move |fmt| {
431 if let Cfg::Cfg(_, Some(feat)) = sub_cfg
432 && short_longhand
433 {
434 if self.1.is_html() {
435 write!(fmt, "<code>{feat}</code>")?;
436 } else {
437 write!(fmt, "`{feat}`")?;
438 }
439 } else {
440 write_with_opt_paren(fmt, !sub_cfg.is_all(), Display(sub_cfg, self.1))?;
441 }
442 Ok(())
443 })
423 if let Cfg::Cfg(_, Some(feat)) = sub_cfg
424 && short_longhand
425 {
426 Either::Left(self.code_wrappers().wrap(feat))
427 } else {
428 Either::Right(
429 Wrapped::with_parens()
430 .when(!sub_cfg.is_all())
431 .wrap(Display(sub_cfg, self.1)),
432 )
433 }
444434 })
445435 .joined(separator, f)
446436 })
......@@ -461,9 +451,9 @@ impl fmt::Display for Display<'_> {
461451 sub_cfgs
462452 .iter()
463453 .map(|sub_cfg| {
464 fmt::from_fn(|fmt| {
465 write_with_opt_paren(fmt, !sub_cfg.is_all(), Display(sub_cfg, self.1))
466 })
454 Wrapped::with_parens()
455 .when(!sub_cfg.is_all())
456 .wrap(Display(sub_cfg, self.1))
467457 })
468458 .joined(separator, fmt)
469459 }
......@@ -568,21 +558,13 @@ impl fmt::Display for Display<'_> {
568558 };
569559 if !human_readable.is_empty() {
570560 fmt.write_str(human_readable)
571 } else if let Some(v) = value {
572 if self.1.is_html() {
573 write!(
574 fmt,
575 r#"<code>{}="{}"</code>"#,
576 Escape(name.as_str()),
577 Escape(v.as_str())
578 )
579 } else {
580 write!(fmt, r#"`{name}="{v}"`"#)
581 }
582 } else if self.1.is_html() {
583 write!(fmt, "<code>{}</code>", Escape(name.as_str()))
584561 } else {
585 write!(fmt, "`{name}`")
562 let value = value
563 .map(|v| fmt::from_fn(move |f| write!(f, "={}", self.1.escape(v.as_str()))))
564 .maybe_display();
565 self.code_wrappers()
566 .wrap(format_args!("{}{value}", self.1.escape(name.as_str())))
567 .fmt(fmt)
586568 }
587569 }
588570 }
src/librustdoc/display.rs+85-1
......@@ -1,6 +1,6 @@
11//! Various utilities for working with [`fmt::Display`] implementations.
22
3use std::fmt::{self, Display, Formatter};
3use std::fmt::{self, Display, Formatter, FormattingOptions};
44
55pub(crate) trait Joined: IntoIterator {
66 /// Takes an iterator over elements that implement [`Display`], and format them into `f`, separated by `sep`.
......@@ -45,3 +45,87 @@ impl<T: Display> MaybeDisplay for Option<T> {
4545 })
4646 }
4747}
48
49#[derive(Clone, Copy)]
50pub(crate) struct Wrapped<T> {
51 prefix: T,
52 suffix: T,
53}
54
55pub(crate) enum AngleBracket {
56 Open,
57 Close,
58}
59
60impl Display for AngleBracket {
61 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
62 f.write_str(match (self, f.alternate()) {
63 (Self::Open, true) => "<",
64 (Self::Open, false) => "&lt;",
65 (Self::Close, true) => ">",
66 (Self::Close, false) => "&gt;",
67 })
68 }
69}
70
71impl Wrapped<AngleBracket> {
72 pub(crate) fn with_angle_brackets() -> Self {
73 Self { prefix: AngleBracket::Open, suffix: AngleBracket::Close }
74 }
75}
76
77impl Wrapped<char> {
78 pub(crate) fn with_parens() -> Self {
79 Self { prefix: '(', suffix: ')' }
80 }
81
82 pub(crate) fn with_square_brackets() -> Self {
83 Self { prefix: '[', suffix: ']' }
84 }
85}
86
87impl<T: Display> Wrapped<T> {
88 pub(crate) fn with(prefix: T, suffix: T) -> Self {
89 Self { prefix, suffix }
90 }
91
92 pub(crate) fn when(self, if_: bool) -> Wrapped<impl Display> {
93 Wrapped {
94 prefix: if_.then_some(self.prefix).maybe_display(),
95 suffix: if_.then_some(self.suffix).maybe_display(),
96 }
97 }
98
99 pub(crate) fn wrap_fn(
100 self,
101 content: impl Fn(&mut Formatter<'_>) -> fmt::Result,
102 ) -> impl Display {
103 fmt::from_fn(move |f| {
104 self.prefix.fmt(f)?;
105 content(f)?;
106 self.suffix.fmt(f)
107 })
108 }
109
110 pub(crate) fn wrap<C: Display>(self, content: C) -> impl Display {
111 self.wrap_fn(move |f| content.fmt(f))
112 }
113}
114
115#[derive(Clone, Copy)]
116pub(crate) struct WithOpts {
117 opts: FormattingOptions,
118}
119
120impl WithOpts {
121 pub(crate) fn from(f: &Formatter<'_>) -> Self {
122 Self { opts: f.options() }
123 }
124
125 pub(crate) fn display(self, t: impl Display) -> impl Display {
126 fmt::from_fn(move |f| {
127 let mut f = f.with_options(self.opts);
128 t.fmt(&mut f)
129 })
130 }
131}
src/librustdoc/html/format.rs+146-202
......@@ -30,7 +30,7 @@ use super::url_parts_builder::UrlPartsBuilder;
3030use crate::clean::types::ExternalLocation;
3131use crate::clean::utils::find_nearest_parent_module;
3232use crate::clean::{self, ExternalCrate, PrimitiveType};
33use crate::display::{Joined as _, MaybeDisplay as _};
33use crate::display::{Joined as _, MaybeDisplay as _, WithOpts, Wrapped};
3434use crate::formats::cache::Cache;
3535use crate::formats::item_type::ItemType;
3636use crate::html::escape::{Escape, EscapeBodyText};
......@@ -105,20 +105,16 @@ impl clean::GenericParamDef {
105105
106106impl clean::Generics {
107107 pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
108 fmt::from_fn(move |f| {
109 let mut real_params = self.params.iter().filter(|p| !p.is_synthetic_param()).peekable();
110 if real_params.peek().is_none() {
111 return Ok(());
112 }
113
114 let real_params =
115 fmt::from_fn(|f| real_params.clone().map(|g| g.print(cx)).joined(", ", f));
116 if f.alternate() {
117 write!(f, "<{real_params:#}>")
118 } else {
119 write!(f, "&lt;{real_params}&gt;")
120 }
121 })
108 let mut real_params = self.params.iter().filter(|p| !p.is_synthetic_param()).peekable();
109 if real_params.peek().is_none() {
110 None
111 } else {
112 Some(
113 Wrapped::with_angle_brackets()
114 .wrap_fn(move |f| real_params.clone().map(|g| g.print(cx)).joined(", ", f)),
115 )
116 }
117 .maybe_display()
122118 }
123119}
124120
......@@ -151,11 +147,8 @@ fn print_where_predicate(predicate: &clean::WherePredicate, cx: &Context<'_>) ->
151147 Ok(())
152148 }
153149 clean::WherePredicate::EqPredicate { lhs, rhs } => {
154 if f.alternate() {
155 write!(f, "{:#} == {:#}", lhs.print(cx), rhs.print(cx))
156 } else {
157 write!(f, "{} == {}", lhs.print(cx), rhs.print(cx))
158 }
150 let opts = WithOpts::from(f);
151 write!(f, "{} == {}", opts.display(lhs.print(cx)), opts.display(rhs.print(cx)))
159152 }
160153 }
161154 })
......@@ -279,13 +272,10 @@ impl clean::GenericBound {
279272 ty.print(cx).fmt(f)
280273 }
281274 clean::GenericBound::Use(args) => {
282 if f.alternate() {
283 f.write_str("use<")?;
284 } else {
285 f.write_str("use&lt;")?;
286 }
287 args.iter().map(|arg| arg.name()).joined(", ", f)?;
288 if f.alternate() { f.write_str(">") } else { f.write_str("&gt;") }
275 f.write_str("use")?;
276 Wrapped::with_angle_brackets()
277 .wrap_fn(|f| args.iter().map(|arg| arg.name()).joined(", ", f))
278 .fmt(f)
289279 }
290280 })
291281 }
......@@ -297,40 +287,29 @@ impl clean::GenericArgs {
297287 match self {
298288 clean::GenericArgs::AngleBracketed { args, constraints } => {
299289 if !args.is_empty() || !constraints.is_empty() {
300 if f.alternate() {
301 f.write_str("<")?;
302 } else {
303 f.write_str("&lt;")?;
304 }
305
306 [Either::Left(args), Either::Right(constraints)]
307 .into_iter()
308 .flat_map(Either::factor_into_iter)
309 .map(|either| {
310 either.map_either(
311 |arg| arg.print(cx),
312 |constraint| constraint.print(cx),
313 )
290 Wrapped::with_angle_brackets()
291 .wrap_fn(|f| {
292 [Either::Left(args), Either::Right(constraints)]
293 .into_iter()
294 .flat_map(Either::factor_into_iter)
295 .map(|either| {
296 either.map_either(
297 |arg| arg.print(cx),
298 |constraint| constraint.print(cx),
299 )
300 })
301 .joined(", ", f)
314302 })
315 .joined(", ", f)?;
316
317 if f.alternate() {
318 f.write_str(">")?;
319 } else {
320 f.write_str("&gt;")?;
321 }
303 .fmt(f)?;
322304 }
323305 }
324306 clean::GenericArgs::Parenthesized { inputs, output } => {
325 f.write_str("(")?;
326 inputs.iter().map(|ty| ty.print(cx)).joined(", ", f)?;
327 f.write_str(")")?;
307 Wrapped::with_parens()
308 .wrap_fn(|f| inputs.iter().map(|ty| ty.print(cx)).joined(", ", f))
309 .fmt(f)?;
328310 if let Some(ref ty) = *output {
329 if f.alternate() {
330 write!(f, " -> {:#}", ty.print(cx))?;
331 } else {
332 write!(f, " -&gt; {}", ty.print(cx))?;
333 }
311 f.write_str(if f.alternate() { " -> " } else { " -&gt; " })?;
312 ty.print(cx).fmt(f)?;
334313 }
335314 }
336315 clean::GenericArgs::ReturnTypeNotation => {
......@@ -834,9 +813,10 @@ fn print_higher_ranked_params_with_space(
834813 fmt::from_fn(move |f| {
835814 if !params.is_empty() {
836815 f.write_str(keyword)?;
837 f.write_str(if f.alternate() { "<" } else { "&lt;" })?;
838 params.iter().map(|lt| lt.print(cx)).joined(", ", f)?;
839 f.write_str(if f.alternate() { "> " } else { "&gt; " })?;
816 Wrapped::with_angle_brackets()
817 .wrap_fn(|f| params.iter().map(|lt| lt.print(cx)).joined(", ", f))
818 .fmt(f)?;
819 f.write_char(' ')?;
840820 }
841821 Ok(())
842822 })
......@@ -923,26 +903,23 @@ fn fmt_type(
923903 f,
924904 PrimitiveType::Tuple,
925905 format_args!(
926 "({})",
927 fmt::from_fn(|f| generic_names.iter().joined(", ", f))
906 "{}",
907 Wrapped::with_parens()
908 .wrap_fn(|f| generic_names.iter().joined(", ", f))
928909 ),
929910 cx,
930911 )
931912 } else {
932 f.write_str("(")?;
933 many.iter().map(|item| item.print(cx)).joined(", ", f)?;
934 f.write_str(")")
913 Wrapped::with_parens()
914 .wrap_fn(|f| many.iter().map(|item| item.print(cx)).joined(", ", f))
915 .fmt(f)
935916 }
936917 }
937918 },
938919 clean::Slice(box clean::Generic(name)) => {
939920 primitive_link(f, PrimitiveType::Slice, format_args!("[{name}]"), cx)
940921 }
941 clean::Slice(t) => {
942 write!(f, "[")?;
943 t.print(cx).fmt(f)?;
944 write!(f, "]")
945 }
922 clean::Slice(t) => Wrapped::with_square_brackets().wrap(t.print(cx)).fmt(f),
946923 clean::Type::Pat(t, pat) => {
947924 fmt::Display::fmt(&t.print(cx), f)?;
948925 write!(f, " is {pat}")
......@@ -953,40 +930,27 @@ fn fmt_type(
953930 format_args!("[{name}; {n}]", n = Escape(n)),
954931 cx,
955932 ),
956 clean::Array(t, n) => {
957 write!(f, "[")?;
958 t.print(cx).fmt(f)?;
959 if f.alternate() {
960 write!(f, "; {n}")?;
961 } else {
962 write!(f, "; ")?;
963 primitive_link(f, PrimitiveType::Array, format_args!("{n}", n = Escape(n)), cx)?;
964 }
965 write!(f, "]")
966 }
967 clean::RawPointer(m, t) => {
968 let m = match m {
969 hir::Mutability::Mut => "mut",
970 hir::Mutability::Not => "const",
971 };
972
973 if matches!(**t, clean::Generic(_)) || t.is_assoc_ty() {
974 let ty = t.print(cx);
933 clean::Array(t, n) => Wrapped::with_square_brackets()
934 .wrap(fmt::from_fn(|f| {
935 t.print(cx).fmt(f)?;
936 f.write_str("; ")?;
975937 if f.alternate() {
976 primitive_link(
977 f,
978 clean::PrimitiveType::RawPointer,
979 format_args!("*{m} {ty:#}"),
980 cx,
981 )
938 f.write_str(n)
982939 } else {
983 primitive_link(
984 f,
985 clean::PrimitiveType::RawPointer,
986 format_args!("*{m} {ty}"),
987 cx,
988 )
940 primitive_link(f, PrimitiveType::Array, format_args!("{n}", n = Escape(n)), cx)
989941 }
942 }))
943 .fmt(f),
944 clean::RawPointer(m, t) => {
945 let m = m.ptr_str();
946
947 if matches!(**t, clean::Generic(_)) || t.is_assoc_ty() {
948 primitive_link(
949 f,
950 clean::PrimitiveType::RawPointer,
951 format_args!("*{m} {ty}", ty = WithOpts::from(f).display(t.print(cx))),
952 cx,
953 )
990954 } else {
991955 primitive_link(f, clean::PrimitiveType::RawPointer, format_args!("*{m} "), cx)?;
992956 t.print(cx).fmt(f)
......@@ -1020,14 +984,10 @@ fn fmt_type(
1020984 clean::ImplTrait(ref bounds) if bounds.len() > 1 => true,
1021985 _ => false,
1022986 };
1023 if needs_parens {
1024 f.write_str("(")?;
1025 }
1026 fmt_type(ty, f, use_absolute, cx)?;
1027 if needs_parens {
1028 f.write_str(")")?;
1029 }
1030 Ok(())
987 Wrapped::with_parens()
988 .when(needs_parens)
989 .wrap_fn(|f| fmt_type(ty, f, use_absolute, cx))
990 .fmt(f)
1031991 }
1032992 clean::ImplTrait(bounds) => {
1033993 f.write_str("impl ")?;
......@@ -1057,23 +1017,21 @@ impl clean::QPathData {
10571017 // FIXME(inherent_associated_types): Once we support non-ADT self-types (#106719),
10581018 // we need to surround them with angle brackets in some cases (e.g. `<dyn …>::P`).
10591019
1060 if f.alternate() {
1061 if let Some(trait_) = trait_
1062 && should_fully_qualify
1063 {
1064 write!(f, "<{:#} as {:#}>::", self_type.print(cx), trait_.print(cx))?
1065 } else {
1066 write!(f, "{:#}::", self_type.print(cx))?
1067 }
1020 if let Some(trait_) = trait_
1021 && should_fully_qualify
1022 {
1023 let opts = WithOpts::from(f);
1024 Wrapped::with_angle_brackets()
1025 .wrap(format_args!(
1026 "{} as {}",
1027 opts.display(self_type.print(cx)),
1028 opts.display(trait_.print(cx))
1029 ))
1030 .fmt(f)?
10681031 } else {
1069 if let Some(trait_) = trait_
1070 && should_fully_qualify
1071 {
1072 write!(f, "&lt;{} as {}&gt;::", self_type.print(cx), trait_.print(cx))?
1073 } else {
1074 write!(f, "{}::", self_type.print(cx))?
1075 }
1076 };
1032 self_type.print(cx).fmt(f)?;
1033 }
1034 f.write_str("::")?;
10771035 // It's pretty unsightly to look at `<A as B>::C` in output, and
10781036 // we've got hyperlinking on our side, so try to avoid longer
10791037 // notation as much as possible by making `C` a hyperlink to trait
......@@ -1132,7 +1090,7 @@ impl clean::Impl {
11321090
11331091 if let Some(ref ty) = self.trait_ {
11341092 if self.is_negative_trait_impl() {
1135 write!(f, "!")?;
1093 f.write_char('!')?;
11361094 }
11371095 if self.kind.is_fake_variadic()
11381096 && let Some(generics) = ty.generics()
......@@ -1140,18 +1098,17 @@ impl clean::Impl {
11401098 {
11411099 let last = ty.last();
11421100 if f.alternate() {
1143 write!(f, "{last}<")?;
1144 self.print_type(inner_type, f, use_absolute, cx)?;
1145 write!(f, ">")?;
1101 write!(f, "{last}")?;
11461102 } else {
1147 write!(f, "{}&lt;", print_anchor(ty.def_id(), last, cx))?;
1148 self.print_type(inner_type, f, use_absolute, cx)?;
1149 write!(f, "&gt;")?;
1150 }
1103 write!(f, "{}", print_anchor(ty.def_id(), last, cx))?;
1104 };
1105 Wrapped::with_angle_brackets()
1106 .wrap_fn(|f| self.print_type(inner_type, f, use_absolute, cx))
1107 .fmt(f)?;
11511108 } else {
11521109 ty.print(cx).fmt(f)?;
11531110 }
1154 write!(f, " for ")?;
1111 f.write_str(" for ")?;
11551112 }
11561113
11571114 if let Some(ty) = self.kind.as_blanket_ty() {
......@@ -1218,18 +1175,10 @@ impl clean::Impl {
12181175 && let Ok(ty) = generics.exactly_one()
12191176 && self.kind.is_fake_variadic()
12201177 {
1221 let wrapper = print_anchor(path.def_id(), path.last(), cx);
1222 if f.alternate() {
1223 write!(f, "{wrapper:#}&lt;")?;
1224 } else {
1225 write!(f, "{wrapper}<")?;
1226 }
1227 self.print_type(ty, f, use_absolute, cx)?;
1228 if f.alternate() {
1229 write!(f, "&gt;")?;
1230 } else {
1231 write!(f, ">")?;
1232 }
1178 print_anchor(path.def_id(), path.last(), cx).fmt(f)?;
1179 Wrapped::with_angle_brackets()
1180 .wrap_fn(|f| self.print_type(ty, f, use_absolute, cx))
1181 .fmt(f)?;
12331182 } else {
12341183 fmt_type(type_, f, use_absolute, cx)?;
12351184 }
......@@ -1311,23 +1260,13 @@ impl clean::FnDecl {
13111260 pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
13121261 fmt::from_fn(move |f| {
13131262 let ellipsis = if self.c_variadic { ", ..." } else { "" };
1314 if f.alternate() {
1315 write!(
1316 f,
1317 "({params:#}{ellipsis}){arrow:#}",
1318 params = print_params(&self.inputs, cx),
1319 ellipsis = ellipsis,
1320 arrow = self.print_output(cx)
1321 )
1322 } else {
1323 write!(
1324 f,
1325 "({params}{ellipsis}){arrow}",
1326 params = print_params(&self.inputs, cx),
1327 ellipsis = ellipsis,
1328 arrow = self.print_output(cx)
1329 )
1330 }
1263 Wrapped::with_parens()
1264 .wrap_fn(|f| {
1265 print_params(&self.inputs, cx).fmt(f)?;
1266 f.write_str(ellipsis)
1267 })
1268 .fmt(f)?;
1269 self.print_output(cx).fmt(f)
13311270 })
13321271 }
13331272
......@@ -1346,8 +1285,7 @@ impl clean::FnDecl {
13461285 fmt::from_fn(move |f| {
13471286 // First, generate the text form of the declaration, with no line wrapping, and count the bytes.
13481287 let mut counter = WriteCounter(0);
1349 write!(&mut counter, "{:#}", fmt::from_fn(|f| { self.inner_full_print(None, f, cx) }))
1350 .unwrap();
1288 write!(&mut counter, "{:#}", fmt::from_fn(|f| { self.inner_full_print(None, f, cx) }))?;
13511289 // If the text form was over 80 characters wide, we will line-wrap our output.
13521290 let line_wrapping_indent =
13531291 if header_len + counter.0 > 80 { Some(indent) } else { None };
......@@ -1365,53 +1303,56 @@ impl clean::FnDecl {
13651303 f: &mut fmt::Formatter<'_>,
13661304 cx: &Context<'_>,
13671305 ) -> fmt::Result {
1368 f.write_char('(')?;
1306 Wrapped::with_parens()
1307 .wrap_fn(|f| {
1308 if !self.inputs.is_empty() {
1309 let line_wrapping_indent = line_wrapping_indent.map(|n| Indent(n + 4));
13691310
1370 if !self.inputs.is_empty() {
1371 let line_wrapping_indent = line_wrapping_indent.map(|n| Indent(n + 4));
1372
1373 if let Some(indent) = line_wrapping_indent {
1374 write!(f, "\n{indent}")?;
1375 }
1311 if let Some(indent) = line_wrapping_indent {
1312 write!(f, "\n{indent}")?;
1313 }
13761314
1377 let sep = fmt::from_fn(|f| {
1378 if let Some(indent) = line_wrapping_indent {
1379 write!(f, ",\n{indent}")
1380 } else {
1381 f.write_str(", ")
1382 }
1383 });
1315 let sep = fmt::from_fn(|f| {
1316 if let Some(indent) = line_wrapping_indent {
1317 write!(f, ",\n{indent}")
1318 } else {
1319 f.write_str(", ")
1320 }
1321 });
13841322
1385 self.inputs.iter().map(|param| param.print(cx)).joined(sep, f)?;
1323 self.inputs.iter().map(|param| param.print(cx)).joined(sep, f)?;
13861324
1387 if line_wrapping_indent.is_some() {
1388 writeln!(f, ",")?
1389 }
1325 if line_wrapping_indent.is_some() {
1326 writeln!(f, ",")?
1327 }
13901328
1391 if self.c_variadic {
1392 match line_wrapping_indent {
1393 None => write!(f, ", ...")?,
1394 Some(indent) => writeln!(f, "{indent}...")?,
1395 };
1396 }
1397 }
1329 if self.c_variadic {
1330 match line_wrapping_indent {
1331 None => write!(f, ", ...")?,
1332 Some(indent) => writeln!(f, "{indent}...")?,
1333 };
1334 }
1335 }
13981336
1399 if let Some(n) = line_wrapping_indent {
1400 write!(f, "{}", Indent(n))?
1401 }
1337 if let Some(n) = line_wrapping_indent {
1338 write!(f, "{}", Indent(n))?
1339 }
14021340
1403 f.write_char(')')?;
1341 Ok(())
1342 })
1343 .fmt(f)?;
14041344
14051345 self.print_output(cx).fmt(f)
14061346 }
14071347
14081348 fn print_output(&self, cx: &Context<'_>) -> impl Display {
1409 fmt::from_fn(move |f| match &self.output {
1410 clean::Tuple(tys) if tys.is_empty() => Ok(()),
1411 ty if f.alternate() => {
1412 write!(f, " -> {:#}", ty.print(cx))
1349 fmt::from_fn(move |f| {
1350 if self.output.is_unit() {
1351 return Ok(());
14131352 }
1414 ty => write!(f, " -&gt; {}", ty.print(cx)),
1353
1354 f.write_str(if f.alternate() { " -> " } else { " -&gt; " })?;
1355 self.output.print(cx).fmt(f)
14151356 })
14161357 }
14171358}
......@@ -1422,10 +1363,13 @@ pub(crate) fn visibility_print_with_space(item: &clean::Item, cx: &Context<'_>)
14221363 f.write_str("#[doc(hidden)] ")?;
14231364 }
14241365
1425 match item.visibility(cx.tcx()) {
1426 None => {}
1427 Some(ty::Visibility::Public) => f.write_str("pub ")?,
1428 Some(ty::Visibility::Restricted(vis_did)) => {
1366 let Some(vis) = item.visibility(cx.tcx()) else {
1367 return Ok(());
1368 };
1369
1370 match vis {
1371 ty::Visibility::Public => f.write_str("pub ")?,
1372 ty::Visibility::Restricted(vis_did) => {
14291373 // FIXME(camelid): This may not work correctly if `item_did` is a module.
14301374 // However, rustdoc currently never displays a module's
14311375 // visibility, so it shouldn't matter.
src/librustdoc/lib.rs+1
......@@ -10,6 +10,7 @@
1010#![feature(box_patterns)]
1111#![feature(debug_closure_helpers)]
1212#![feature(file_buffered)]
13#![feature(formatting_options)]
1314#![feature(if_let_guard)]
1415#![feature(iter_advance_by)]
1516#![feature(iter_intersperse)]
tests/codegen-llvm/asm/powerpc-clobbers.rs+4-4
......@@ -58,10 +58,10 @@ pub unsafe fn v0_clobber() {
5858
5959// Output format depends on the availability of altivec.
6060// CHECK-LABEL: @clobber_abi
61// powerpc: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
62// powerpc64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
63// powerpc64le: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
64// aix64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
61// powerpc: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
62// powerpc64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
63// powerpc64le: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
64// aix64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
6565#[no_mangle]
6666pub unsafe fn clobber_abi() {
6767 asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
tests/codegen-llvm/asm/readonly-not-pure.rs created+48
......@@ -0,0 +1,48 @@
1//@ add-core-stubs
2//@ compile-flags: -Copt-level=3 --target x86_64-unknown-linux-gnu
3//@ needs-llvm-components: x86
4
5#![crate_type = "rlib"]
6#![feature(no_core)]
7#![no_core]
8
9// Test that when an inline assembly block specifies `readonly` but not `pure`, a detailed
10// `MemoryEffects` is provided to LLVM: this assembly block is not allowed to perform writes,
11// but it may have side-effects.
12
13extern crate minicore;
14use minicore::*;
15
16pub static mut VAR: i32 = 0;
17
18// CHECK-LABEL: @no_options
19// CHECK: call i32 asm
20#[no_mangle]
21pub unsafe fn no_options() -> i32 {
22 VAR = 1;
23 let _ignored: i32;
24 asm!("mov {0}, 1", out(reg) _ignored);
25 VAR
26}
27
28// CHECK-LABEL: @readonly_pure
29// CHECK-NOT: call i32 asm
30#[no_mangle]
31pub unsafe fn readonly_pure() -> i32 {
32 VAR = 1;
33 let _ignored: i32;
34 asm!("mov {0}, 1", out(reg) _ignored, options(pure, readonly));
35 VAR
36}
37
38// CHECK-LABEL: @readonly_not_pure
39// CHECK: call i32 asm {{.*}} #[[ATTR:[0-9]+]]
40#[no_mangle]
41pub unsafe fn readonly_not_pure() -> i32 {
42 VAR = 1;
43 let _ignored: i32;
44 asm!("mov {0}, 1", out(reg) _ignored, options(readonly));
45 VAR
46}
47
48// CHECK: attributes #[[ATTR]] = { nounwind memory(read, inaccessiblemem: readwrite) }
tests/codegen-llvm/issues/cows-dont-have-branches-117763.rs created+17
......@@ -0,0 +1,17 @@
1//@ compile-flags: -Copt-level=3
2//@ needs-deterministic-layouts
3
4// Currently Vec<T> and &[T] have layouts that start with (pointer, len)
5// which makes the conversion branchless.
6// A nice-to-have property, not guaranteed.
7#![crate_type = "cdylib"]
8
9// CHECK-LABEL: @branchless_cow_slices
10#[no_mangle]
11pub fn branchless_cow_slices<'a>(cow: &'a std::borrow::Cow<'a, [u8]>) -> &'a [u8] {
12 // CHECK-NOT: br
13 // CHECK-NOT: select
14 // CHECK-NOT: icmp
15 // CHECK: ret { ptr, {{i32|i64}} }
16 &*cow
17}
tests/run-make/musl-default-linking/rmake.rs+1-2
......@@ -4,7 +4,7 @@ use run_make_support::{rustc, serde_json};
44// Per https://github.com/rust-lang/compiler-team/issues/422,
55// we should be trying to move these targets to dynamically link
66// musl libc by default.
7//@ needs-llvm-components: aarch64 arm mips powerpc x86
7//@ needs-llvm-components: aarch64 arm powerpc x86
88static LEGACY_STATIC_LINKING_TARGETS: &[&'static str] = &[
99 "aarch64-unknown-linux-musl",
1010 "arm-unknown-linux-musleabi",
......@@ -14,7 +14,6 @@ static LEGACY_STATIC_LINKING_TARGETS: &[&'static str] = &[
1414 "armv7-unknown-linux-musleabihf",
1515 "i586-unknown-linux-musl",
1616 "i686-unknown-linux-musl",
17 "mips64el-unknown-linux-muslabi64",
1817 "powerpc64le-unknown-linux-musl",
1918 "x86_64-unknown-linux-musl",
2019];
tests/ui/asm/powerpc/bad-reg.aix64.stderr+123-39
......@@ -28,74 +28,110 @@ error: invalid register `fp`: the frame pointer cannot be used as an operand for
2828LL | asm!("", out("fp") _);
2929 | ^^^^^^^^^^^
3030
31error: invalid register `lr`: the link register cannot be used as an operand for inline asm
32 --> $DIR/bad-reg.rs:48:18
33 |
34LL | asm!("", out("lr") _);
35 | ^^^^^^^^^^^
36
37error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm
38 --> $DIR/bad-reg.rs:50:18
39 |
40LL | asm!("", out("ctr") _);
41 | ^^^^^^^^^^^^
42
4331error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm
44 --> $DIR/bad-reg.rs:52:18
32 --> $DIR/bad-reg.rs:48:18
4533 |
4634LL | asm!("", out("vrsave") _);
4735 | ^^^^^^^^^^^^^^^
4836
4937error: register class `cr` can only be used as a clobber, not as an input or output
50 --> $DIR/bad-reg.rs:100:18
38 --> $DIR/bad-reg.rs:96:18
5139 |
5240LL | asm!("", in("cr") x);
5341 | ^^^^^^^^^^
5442
5543error: register class `cr` can only be used as a clobber, not as an input or output
56 --> $DIR/bad-reg.rs:103:18
44 --> $DIR/bad-reg.rs:99:18
5745 |
5846LL | asm!("", out("cr") x);
5947 | ^^^^^^^^^^^
6048
6149error: register class `cr` can only be used as a clobber, not as an input or output
62 --> $DIR/bad-reg.rs:106:26
50 --> $DIR/bad-reg.rs:102:26
6351 |
6452LL | asm!("/* {} */", in(cr) x);
6553 | ^^^^^^^^
6654
6755error: register class `cr` can only be used as a clobber, not as an input or output
68 --> $DIR/bad-reg.rs:109:26
56 --> $DIR/bad-reg.rs:105:26
6957 |
7058LL | asm!("/* {} */", out(cr) _);
7159 | ^^^^^^^^^
7260
61error: register class `ctr` can only be used as a clobber, not as an input or output
62 --> $DIR/bad-reg.rs:109:18
63 |
64LL | asm!("", in("ctr") x);
65 | ^^^^^^^^^^^
66
67error: register class `ctr` can only be used as a clobber, not as an input or output
68 --> $DIR/bad-reg.rs:112:18
69 |
70LL | asm!("", out("ctr") x);
71 | ^^^^^^^^^^^^
72
73error: register class `ctr` can only be used as a clobber, not as an input or output
74 --> $DIR/bad-reg.rs:115:26
75 |
76LL | asm!("/* {} */", in(ctr) x);
77 | ^^^^^^^^^
78
79error: register class `ctr` can only be used as a clobber, not as an input or output
80 --> $DIR/bad-reg.rs:118:26
81 |
82LL | asm!("/* {} */", out(ctr) _);
83 | ^^^^^^^^^^
84
85error: register class `lr` can only be used as a clobber, not as an input or output
86 --> $DIR/bad-reg.rs:122:18
87 |
88LL | asm!("", in("lr") x);
89 | ^^^^^^^^^^
90
91error: register class `lr` can only be used as a clobber, not as an input or output
92 --> $DIR/bad-reg.rs:125:18
93 |
94LL | asm!("", out("lr") x);
95 | ^^^^^^^^^^^
96
97error: register class `lr` can only be used as a clobber, not as an input or output
98 --> $DIR/bad-reg.rs:128:26
99 |
100LL | asm!("/* {} */", in(lr) x);
101 | ^^^^^^^^
102
103error: register class `lr` can only be used as a clobber, not as an input or output
104 --> $DIR/bad-reg.rs:131:26
105 |
106LL | asm!("/* {} */", out(lr) _);
107 | ^^^^^^^^^
108
73109error: register class `xer` can only be used as a clobber, not as an input or output
74 --> $DIR/bad-reg.rs:113:18
110 --> $DIR/bad-reg.rs:135:18
75111 |
76112LL | asm!("", in("xer") x);
77113 | ^^^^^^^^^^^
78114
79115error: register class `xer` can only be used as a clobber, not as an input or output
80 --> $DIR/bad-reg.rs:116:18
116 --> $DIR/bad-reg.rs:138:18
81117 |
82118LL | asm!("", out("xer") x);
83119 | ^^^^^^^^^^^^
84120
85121error: register class `xer` can only be used as a clobber, not as an input or output
86 --> $DIR/bad-reg.rs:119:26
122 --> $DIR/bad-reg.rs:141:26
87123 |
88124LL | asm!("/* {} */", in(xer) x);
89125 | ^^^^^^^^^
90126
91127error: register class `xer` can only be used as a clobber, not as an input or output
92 --> $DIR/bad-reg.rs:122:26
128 --> $DIR/bad-reg.rs:144:26
93129 |
94130LL | asm!("/* {} */", out(xer) _);
95131 | ^^^^^^^^^^
96132
97133error: register `cr0` conflicts with register `cr`
98 --> $DIR/bad-reg.rs:126:31
134 --> $DIR/bad-reg.rs:148:31
99135 |
100136LL | asm!("", out("cr") _, out("cr0") _);
101137 | ----------- ^^^^^^^^^^^^ register `cr0`
......@@ -103,7 +139,7 @@ LL | asm!("", out("cr") _, out("cr0") _);
103139 | register `cr`
104140
105141error: register `cr1` conflicts with register `cr`
106 --> $DIR/bad-reg.rs:128:31
142 --> $DIR/bad-reg.rs:150:31
107143 |
108144LL | asm!("", out("cr") _, out("cr1") _);
109145 | ----------- ^^^^^^^^^^^^ register `cr1`
......@@ -111,7 +147,7 @@ LL | asm!("", out("cr") _, out("cr1") _);
111147 | register `cr`
112148
113149error: register `cr2` conflicts with register `cr`
114 --> $DIR/bad-reg.rs:130:31
150 --> $DIR/bad-reg.rs:152:31
115151 |
116152LL | asm!("", out("cr") _, out("cr2") _);
117153 | ----------- ^^^^^^^^^^^^ register `cr2`
......@@ -119,7 +155,7 @@ LL | asm!("", out("cr") _, out("cr2") _);
119155 | register `cr`
120156
121157error: register `cr3` conflicts with register `cr`
122 --> $DIR/bad-reg.rs:132:31
158 --> $DIR/bad-reg.rs:154:31
123159 |
124160LL | asm!("", out("cr") _, out("cr3") _);
125161 | ----------- ^^^^^^^^^^^^ register `cr3`
......@@ -127,7 +163,7 @@ LL | asm!("", out("cr") _, out("cr3") _);
127163 | register `cr`
128164
129165error: register `cr4` conflicts with register `cr`
130 --> $DIR/bad-reg.rs:134:31
166 --> $DIR/bad-reg.rs:156:31
131167 |
132168LL | asm!("", out("cr") _, out("cr4") _);
133169 | ----------- ^^^^^^^^^^^^ register `cr4`
......@@ -135,7 +171,7 @@ LL | asm!("", out("cr") _, out("cr4") _);
135171 | register `cr`
136172
137173error: register `cr5` conflicts with register `cr`
138 --> $DIR/bad-reg.rs:136:31
174 --> $DIR/bad-reg.rs:158:31
139175 |
140176LL | asm!("", out("cr") _, out("cr5") _);
141177 | ----------- ^^^^^^^^^^^^ register `cr5`
......@@ -143,7 +179,7 @@ LL | asm!("", out("cr") _, out("cr5") _);
143179 | register `cr`
144180
145181error: register `cr6` conflicts with register `cr`
146 --> $DIR/bad-reg.rs:138:31
182 --> $DIR/bad-reg.rs:160:31
147183 |
148184LL | asm!("", out("cr") _, out("cr6") _);
149185 | ----------- ^^^^^^^^^^^^ register `cr6`
......@@ -151,7 +187,7 @@ LL | asm!("", out("cr") _, out("cr6") _);
151187 | register `cr`
152188
153189error: register `cr7` conflicts with register `cr`
154 --> $DIR/bad-reg.rs:140:31
190 --> $DIR/bad-reg.rs:162:31
155191 |
156192LL | asm!("", out("cr") _, out("cr7") _);
157193 | ----------- ^^^^^^^^^^^^ register `cr7`
......@@ -165,7 +201,7 @@ LL | asm!("", out("r13") _);
165201 | ^^^^^^^^^^^^
166202
167203error: type `i32` cannot be used with this register class
168 --> $DIR/bad-reg.rs:67:27
204 --> $DIR/bad-reg.rs:63:27
169205 |
170206LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available
171207 | ^
......@@ -173,7 +209,7 @@ LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available
173209 = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
174210
175211error: type `i32` cannot be used with this register class
176 --> $DIR/bad-reg.rs:70:28
212 --> $DIR/bad-reg.rs:66:28
177213 |
178214LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available
179215 | ^
......@@ -181,7 +217,7 @@ LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available
181217 = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
182218
183219error: type `i32` cannot be used with this register class
184 --> $DIR/bad-reg.rs:78:35
220 --> $DIR/bad-reg.rs:74:35
185221 |
186222LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available
187223 | ^
......@@ -189,7 +225,7 @@ LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is avai
189225 = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
190226
191227error: type `i32` cannot be used with this register class
192 --> $DIR/bad-reg.rs:100:27
228 --> $DIR/bad-reg.rs:96:27
193229 |
194230LL | asm!("", in("cr") x);
195231 | ^
......@@ -197,7 +233,7 @@ LL | asm!("", in("cr") x);
197233 = note: register class `cr` supports these types:
198234
199235error: type `i32` cannot be used with this register class
200 --> $DIR/bad-reg.rs:103:28
236 --> $DIR/bad-reg.rs:99:28
201237 |
202238LL | asm!("", out("cr") x);
203239 | ^
......@@ -205,7 +241,7 @@ LL | asm!("", out("cr") x);
205241 = note: register class `cr` supports these types:
206242
207243error: type `i32` cannot be used with this register class
208 --> $DIR/bad-reg.rs:106:33
244 --> $DIR/bad-reg.rs:102:33
209245 |
210246LL | asm!("/* {} */", in(cr) x);
211247 | ^
......@@ -213,7 +249,55 @@ LL | asm!("/* {} */", in(cr) x);
213249 = note: register class `cr` supports these types:
214250
215251error: type `i32` cannot be used with this register class
216 --> $DIR/bad-reg.rs:113:28
252 --> $DIR/bad-reg.rs:109:28
253 |
254LL | asm!("", in("ctr") x);
255 | ^
256 |
257 = note: register class `ctr` supports these types:
258
259error: type `i32` cannot be used with this register class
260 --> $DIR/bad-reg.rs:112:29
261 |
262LL | asm!("", out("ctr") x);
263 | ^
264 |
265 = note: register class `ctr` supports these types:
266
267error: type `i32` cannot be used with this register class
268 --> $DIR/bad-reg.rs:115:34
269 |
270LL | asm!("/* {} */", in(ctr) x);
271 | ^
272 |
273 = note: register class `ctr` supports these types:
274
275error: type `i32` cannot be used with this register class
276 --> $DIR/bad-reg.rs:122:27
277 |
278LL | asm!("", in("lr") x);
279 | ^
280 |
281 = note: register class `lr` supports these types:
282
283error: type `i32` cannot be used with this register class
284 --> $DIR/bad-reg.rs:125:28
285 |
286LL | asm!("", out("lr") x);
287 | ^
288 |
289 = note: register class `lr` supports these types:
290
291error: type `i32` cannot be used with this register class
292 --> $DIR/bad-reg.rs:128:33
293 |
294LL | asm!("/* {} */", in(lr) x);
295 | ^
296 |
297 = note: register class `lr` supports these types:
298
299error: type `i32` cannot be used with this register class
300 --> $DIR/bad-reg.rs:135:28
217301 |
218302LL | asm!("", in("xer") x);
219303 | ^
......@@ -221,7 +305,7 @@ LL | asm!("", in("xer") x);
221305 = note: register class `xer` supports these types:
222306
223307error: type `i32` cannot be used with this register class
224 --> $DIR/bad-reg.rs:116:29
308 --> $DIR/bad-reg.rs:138:29
225309 |
226310LL | asm!("", out("xer") x);
227311 | ^
......@@ -229,12 +313,12 @@ LL | asm!("", out("xer") x);
229313 = note: register class `xer` supports these types:
230314
231315error: type `i32` cannot be used with this register class
232 --> $DIR/bad-reg.rs:119:34
316 --> $DIR/bad-reg.rs:141:34
233317 |
234318LL | asm!("/* {} */", in(xer) x);
235319 | ^
236320 |
237321 = note: register class `xer` supports these types:
238322
239error: aborting due to 34 previous errors
323error: aborting due to 46 previous errors
240324
tests/ui/asm/powerpc/bad-reg.powerpc.stderr+130-46
......@@ -28,74 +28,110 @@ error: invalid register `fp`: the frame pointer cannot be used as an operand for
2828LL | asm!("", out("fp") _);
2929 | ^^^^^^^^^^^
3030
31error: invalid register `lr`: the link register cannot be used as an operand for inline asm
32 --> $DIR/bad-reg.rs:48:18
33 |
34LL | asm!("", out("lr") _);
35 | ^^^^^^^^^^^
36
37error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm
38 --> $DIR/bad-reg.rs:50:18
39 |
40LL | asm!("", out("ctr") _);
41 | ^^^^^^^^^^^^
42
4331error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm
44 --> $DIR/bad-reg.rs:52:18
32 --> $DIR/bad-reg.rs:48:18
4533 |
4634LL | asm!("", out("vrsave") _);
4735 | ^^^^^^^^^^^^^^^
4836
4937error: register class `cr` can only be used as a clobber, not as an input or output
50 --> $DIR/bad-reg.rs:100:18
38 --> $DIR/bad-reg.rs:96:18
5139 |
5240LL | asm!("", in("cr") x);
5341 | ^^^^^^^^^^
5442
5543error: register class `cr` can only be used as a clobber, not as an input or output
56 --> $DIR/bad-reg.rs:103:18
44 --> $DIR/bad-reg.rs:99:18
5745 |
5846LL | asm!("", out("cr") x);
5947 | ^^^^^^^^^^^
6048
6149error: register class `cr` can only be used as a clobber, not as an input or output
62 --> $DIR/bad-reg.rs:106:26
50 --> $DIR/bad-reg.rs:102:26
6351 |
6452LL | asm!("/* {} */", in(cr) x);
6553 | ^^^^^^^^
6654
6755error: register class `cr` can only be used as a clobber, not as an input or output
68 --> $DIR/bad-reg.rs:109:26
56 --> $DIR/bad-reg.rs:105:26
6957 |
7058LL | asm!("/* {} */", out(cr) _);
7159 | ^^^^^^^^^
7260
61error: register class `ctr` can only be used as a clobber, not as an input or output
62 --> $DIR/bad-reg.rs:109:18
63 |
64LL | asm!("", in("ctr") x);
65 | ^^^^^^^^^^^
66
67error: register class `ctr` can only be used as a clobber, not as an input or output
68 --> $DIR/bad-reg.rs:112:18
69 |
70LL | asm!("", out("ctr") x);
71 | ^^^^^^^^^^^^
72
73error: register class `ctr` can only be used as a clobber, not as an input or output
74 --> $DIR/bad-reg.rs:115:26
75 |
76LL | asm!("/* {} */", in(ctr) x);
77 | ^^^^^^^^^
78
79error: register class `ctr` can only be used as a clobber, not as an input or output
80 --> $DIR/bad-reg.rs:118:26
81 |
82LL | asm!("/* {} */", out(ctr) _);
83 | ^^^^^^^^^^
84
85error: register class `lr` can only be used as a clobber, not as an input or output
86 --> $DIR/bad-reg.rs:122:18
87 |
88LL | asm!("", in("lr") x);
89 | ^^^^^^^^^^
90
91error: register class `lr` can only be used as a clobber, not as an input or output
92 --> $DIR/bad-reg.rs:125:18
93 |
94LL | asm!("", out("lr") x);
95 | ^^^^^^^^^^^
96
97error: register class `lr` can only be used as a clobber, not as an input or output
98 --> $DIR/bad-reg.rs:128:26
99 |
100LL | asm!("/* {} */", in(lr) x);
101 | ^^^^^^^^
102
103error: register class `lr` can only be used as a clobber, not as an input or output
104 --> $DIR/bad-reg.rs:131:26
105 |
106LL | asm!("/* {} */", out(lr) _);
107 | ^^^^^^^^^
108
73109error: register class `xer` can only be used as a clobber, not as an input or output
74 --> $DIR/bad-reg.rs:113:18
110 --> $DIR/bad-reg.rs:135:18
75111 |
76112LL | asm!("", in("xer") x);
77113 | ^^^^^^^^^^^
78114
79115error: register class `xer` can only be used as a clobber, not as an input or output
80 --> $DIR/bad-reg.rs:116:18
116 --> $DIR/bad-reg.rs:138:18
81117 |
82118LL | asm!("", out("xer") x);
83119 | ^^^^^^^^^^^^
84120
85121error: register class `xer` can only be used as a clobber, not as an input or output
86 --> $DIR/bad-reg.rs:119:26
122 --> $DIR/bad-reg.rs:141:26
87123 |
88124LL | asm!("/* {} */", in(xer) x);
89125 | ^^^^^^^^^
90126
91127error: register class `xer` can only be used as a clobber, not as an input or output
92 --> $DIR/bad-reg.rs:122:26
128 --> $DIR/bad-reg.rs:144:26
93129 |
94130LL | asm!("/* {} */", out(xer) _);
95131 | ^^^^^^^^^^
96132
97133error: register `cr0` conflicts with register `cr`
98 --> $DIR/bad-reg.rs:126:31
134 --> $DIR/bad-reg.rs:148:31
99135 |
100136LL | asm!("", out("cr") _, out("cr0") _);
101137 | ----------- ^^^^^^^^^^^^ register `cr0`
......@@ -103,7 +139,7 @@ LL | asm!("", out("cr") _, out("cr0") _);
103139 | register `cr`
104140
105141error: register `cr1` conflicts with register `cr`
106 --> $DIR/bad-reg.rs:128:31
142 --> $DIR/bad-reg.rs:150:31
107143 |
108144LL | asm!("", out("cr") _, out("cr1") _);
109145 | ----------- ^^^^^^^^^^^^ register `cr1`
......@@ -111,7 +147,7 @@ LL | asm!("", out("cr") _, out("cr1") _);
111147 | register `cr`
112148
113149error: register `cr2` conflicts with register `cr`
114 --> $DIR/bad-reg.rs:130:31
150 --> $DIR/bad-reg.rs:152:31
115151 |
116152LL | asm!("", out("cr") _, out("cr2") _);
117153 | ----------- ^^^^^^^^^^^^ register `cr2`
......@@ -119,7 +155,7 @@ LL | asm!("", out("cr") _, out("cr2") _);
119155 | register `cr`
120156
121157error: register `cr3` conflicts with register `cr`
122 --> $DIR/bad-reg.rs:132:31
158 --> $DIR/bad-reg.rs:154:31
123159 |
124160LL | asm!("", out("cr") _, out("cr3") _);
125161 | ----------- ^^^^^^^^^^^^ register `cr3`
......@@ -127,7 +163,7 @@ LL | asm!("", out("cr") _, out("cr3") _);
127163 | register `cr`
128164
129165error: register `cr4` conflicts with register `cr`
130 --> $DIR/bad-reg.rs:134:31
166 --> $DIR/bad-reg.rs:156:31
131167 |
132168LL | asm!("", out("cr") _, out("cr4") _);
133169 | ----------- ^^^^^^^^^^^^ register `cr4`
......@@ -135,7 +171,7 @@ LL | asm!("", out("cr") _, out("cr4") _);
135171 | register `cr`
136172
137173error: register `cr5` conflicts with register `cr`
138 --> $DIR/bad-reg.rs:136:31
174 --> $DIR/bad-reg.rs:158:31
139175 |
140176LL | asm!("", out("cr") _, out("cr5") _);
141177 | ----------- ^^^^^^^^^^^^ register `cr5`
......@@ -143,7 +179,7 @@ LL | asm!("", out("cr") _, out("cr5") _);
143179 | register `cr`
144180
145181error: register `cr6` conflicts with register `cr`
146 --> $DIR/bad-reg.rs:138:31
182 --> $DIR/bad-reg.rs:160:31
147183 |
148184LL | asm!("", out("cr") _, out("cr6") _);
149185 | ----------- ^^^^^^^^^^^^ register `cr6`
......@@ -151,7 +187,7 @@ LL | asm!("", out("cr") _, out("cr6") _);
151187 | register `cr`
152188
153189error: register `cr7` conflicts with register `cr`
154 --> $DIR/bad-reg.rs:140:31
190 --> $DIR/bad-reg.rs:162:31
155191 |
156192LL | asm!("", out("cr") _, out("cr7") _);
157193 | ----------- ^^^^^^^^^^^^ register `cr7`
......@@ -165,67 +201,67 @@ LL | asm!("", out("r13") _);
165201 | ^^^^^^^^^^^^
166202
167203error: register class `vreg` requires at least one of the following target features: altivec, vsx
168 --> $DIR/bad-reg.rs:57:18
204 --> $DIR/bad-reg.rs:53:18
169205 |
170206LL | asm!("", in("v0") v32x4); // requires altivec
171207 | ^^^^^^^^^^^^^^
172208
173209error: register class `vreg` requires at least one of the following target features: altivec, vsx
174 --> $DIR/bad-reg.rs:59:18
210 --> $DIR/bad-reg.rs:55:18
175211 |
176212LL | asm!("", out("v0") v32x4); // requires altivec
177213 | ^^^^^^^^^^^^^^^
178214
179215error: register class `vreg` requires at least one of the following target features: altivec, vsx
180 --> $DIR/bad-reg.rs:61:18
216 --> $DIR/bad-reg.rs:57:18
181217 |
182218LL | asm!("", in("v0") v64x2); // requires vsx
183219 | ^^^^^^^^^^^^^^
184220
185221error: register class `vreg` requires at least one of the following target features: altivec, vsx
186 --> $DIR/bad-reg.rs:64:18
222 --> $DIR/bad-reg.rs:60:18
187223 |
188224LL | asm!("", out("v0") v64x2); // requires vsx
189225 | ^^^^^^^^^^^^^^^
190226
191227error: register class `vreg` requires at least one of the following target features: altivec, vsx
192 --> $DIR/bad-reg.rs:67:18
228 --> $DIR/bad-reg.rs:63:18
193229 |
194230LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available
195231 | ^^^^^^^^^^
196232
197233error: register class `vreg` requires at least one of the following target features: altivec, vsx
198 --> $DIR/bad-reg.rs:70:18
234 --> $DIR/bad-reg.rs:66:18
199235 |
200236LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available
201237 | ^^^^^^^^^^^
202238
203239error: register class `vreg` requires at least one of the following target features: altivec, vsx
204 --> $DIR/bad-reg.rs:73:26
240 --> $DIR/bad-reg.rs:69:26
205241 |
206242LL | asm!("/* {} */", in(vreg) v32x4); // requires altivec
207243 | ^^^^^^^^^^^^^^
208244
209245error: register class `vreg` requires at least one of the following target features: altivec, vsx
210 --> $DIR/bad-reg.rs:75:26
246 --> $DIR/bad-reg.rs:71:26
211247 |
212248LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx
213249 | ^^^^^^^^^^^^^^
214250
215251error: register class `vreg` requires at least one of the following target features: altivec, vsx
216 --> $DIR/bad-reg.rs:78:26
252 --> $DIR/bad-reg.rs:74:26
217253 |
218254LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available
219255 | ^^^^^^^^^^
220256
221257error: register class `vreg` requires at least one of the following target features: altivec, vsx
222 --> $DIR/bad-reg.rs:81:26
258 --> $DIR/bad-reg.rs:77:26
223259 |
224260LL | asm!("/* {} */", out(vreg) _); // requires altivec
225261 | ^^^^^^^^^^^
226262
227263error: type `i32` cannot be used with this register class
228 --> $DIR/bad-reg.rs:100:27
264 --> $DIR/bad-reg.rs:96:27
229265 |
230266LL | asm!("", in("cr") x);
231267 | ^
......@@ -233,7 +269,7 @@ LL | asm!("", in("cr") x);
233269 = note: register class `cr` supports these types:
234270
235271error: type `i32` cannot be used with this register class
236 --> $DIR/bad-reg.rs:103:28
272 --> $DIR/bad-reg.rs:99:28
237273 |
238274LL | asm!("", out("cr") x);
239275 | ^
......@@ -241,7 +277,7 @@ LL | asm!("", out("cr") x);
241277 = note: register class `cr` supports these types:
242278
243279error: type `i32` cannot be used with this register class
244 --> $DIR/bad-reg.rs:106:33
280 --> $DIR/bad-reg.rs:102:33
245281 |
246282LL | asm!("/* {} */", in(cr) x);
247283 | ^
......@@ -249,7 +285,55 @@ LL | asm!("/* {} */", in(cr) x);
249285 = note: register class `cr` supports these types:
250286
251287error: type `i32` cannot be used with this register class
252 --> $DIR/bad-reg.rs:113:28
288 --> $DIR/bad-reg.rs:109:28
289 |
290LL | asm!("", in("ctr") x);
291 | ^
292 |
293 = note: register class `ctr` supports these types:
294
295error: type `i32` cannot be used with this register class
296 --> $DIR/bad-reg.rs:112:29
297 |
298LL | asm!("", out("ctr") x);
299 | ^
300 |
301 = note: register class `ctr` supports these types:
302
303error: type `i32` cannot be used with this register class
304 --> $DIR/bad-reg.rs:115:34
305 |
306LL | asm!("/* {} */", in(ctr) x);
307 | ^
308 |
309 = note: register class `ctr` supports these types:
310
311error: type `i32` cannot be used with this register class
312 --> $DIR/bad-reg.rs:122:27
313 |
314LL | asm!("", in("lr") x);
315 | ^
316 |
317 = note: register class `lr` supports these types:
318
319error: type `i32` cannot be used with this register class
320 --> $DIR/bad-reg.rs:125:28
321 |
322LL | asm!("", out("lr") x);
323 | ^
324 |
325 = note: register class `lr` supports these types:
326
327error: type `i32` cannot be used with this register class
328 --> $DIR/bad-reg.rs:128:33
329 |
330LL | asm!("/* {} */", in(lr) x);
331 | ^
332 |
333 = note: register class `lr` supports these types:
334
335error: type `i32` cannot be used with this register class
336 --> $DIR/bad-reg.rs:135:28
253337 |
254338LL | asm!("", in("xer") x);
255339 | ^
......@@ -257,7 +341,7 @@ LL | asm!("", in("xer") x);
257341 = note: register class `xer` supports these types:
258342
259343error: type `i32` cannot be used with this register class
260 --> $DIR/bad-reg.rs:116:29
344 --> $DIR/bad-reg.rs:138:29
261345 |
262346LL | asm!("", out("xer") x);
263347 | ^
......@@ -265,12 +349,12 @@ LL | asm!("", out("xer") x);
265349 = note: register class `xer` supports these types:
266350
267351error: type `i32` cannot be used with this register class
268 --> $DIR/bad-reg.rs:119:34
352 --> $DIR/bad-reg.rs:141:34
269353 |
270354LL | asm!("/* {} */", in(xer) x);
271355 | ^
272356 |
273357 = note: register class `xer` supports these types:
274358
275error: aborting due to 41 previous errors
359error: aborting due to 53 previous errors
276360
tests/ui/asm/powerpc/bad-reg.powerpc64.stderr+126-42
......@@ -28,74 +28,110 @@ error: invalid register `fp`: the frame pointer cannot be used as an operand for
2828LL | asm!("", out("fp") _);
2929 | ^^^^^^^^^^^
3030
31error: invalid register `lr`: the link register cannot be used as an operand for inline asm
32 --> $DIR/bad-reg.rs:48:18
33 |
34LL | asm!("", out("lr") _);
35 | ^^^^^^^^^^^
36
37error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm
38 --> $DIR/bad-reg.rs:50:18
39 |
40LL | asm!("", out("ctr") _);
41 | ^^^^^^^^^^^^
42
4331error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm
44 --> $DIR/bad-reg.rs:52:18
32 --> $DIR/bad-reg.rs:48:18
4533 |
4634LL | asm!("", out("vrsave") _);
4735 | ^^^^^^^^^^^^^^^
4836
4937error: register class `cr` can only be used as a clobber, not as an input or output
50 --> $DIR/bad-reg.rs:100:18
38 --> $DIR/bad-reg.rs:96:18
5139 |
5240LL | asm!("", in("cr") x);
5341 | ^^^^^^^^^^
5442
5543error: register class `cr` can only be used as a clobber, not as an input or output
56 --> $DIR/bad-reg.rs:103:18
44 --> $DIR/bad-reg.rs:99:18
5745 |
5846LL | asm!("", out("cr") x);
5947 | ^^^^^^^^^^^
6048
6149error: register class `cr` can only be used as a clobber, not as an input or output
62 --> $DIR/bad-reg.rs:106:26
50 --> $DIR/bad-reg.rs:102:26
6351 |
6452LL | asm!("/* {} */", in(cr) x);
6553 | ^^^^^^^^
6654
6755error: register class `cr` can only be used as a clobber, not as an input or output
68 --> $DIR/bad-reg.rs:109:26
56 --> $DIR/bad-reg.rs:105:26
6957 |
7058LL | asm!("/* {} */", out(cr) _);
7159 | ^^^^^^^^^
7260
61error: register class `ctr` can only be used as a clobber, not as an input or output
62 --> $DIR/bad-reg.rs:109:18
63 |
64LL | asm!("", in("ctr") x);
65 | ^^^^^^^^^^^
66
67error: register class `ctr` can only be used as a clobber, not as an input or output
68 --> $DIR/bad-reg.rs:112:18
69 |
70LL | asm!("", out("ctr") x);
71 | ^^^^^^^^^^^^
72
73error: register class `ctr` can only be used as a clobber, not as an input or output
74 --> $DIR/bad-reg.rs:115:26
75 |
76LL | asm!("/* {} */", in(ctr) x);
77 | ^^^^^^^^^
78
79error: register class `ctr` can only be used as a clobber, not as an input or output
80 --> $DIR/bad-reg.rs:118:26
81 |
82LL | asm!("/* {} */", out(ctr) _);
83 | ^^^^^^^^^^
84
85error: register class `lr` can only be used as a clobber, not as an input or output
86 --> $DIR/bad-reg.rs:122:18
87 |
88LL | asm!("", in("lr") x);
89 | ^^^^^^^^^^
90
91error: register class `lr` can only be used as a clobber, not as an input or output
92 --> $DIR/bad-reg.rs:125:18
93 |
94LL | asm!("", out("lr") x);
95 | ^^^^^^^^^^^
96
97error: register class `lr` can only be used as a clobber, not as an input or output
98 --> $DIR/bad-reg.rs:128:26
99 |
100LL | asm!("/* {} */", in(lr) x);
101 | ^^^^^^^^
102
103error: register class `lr` can only be used as a clobber, not as an input or output
104 --> $DIR/bad-reg.rs:131:26
105 |
106LL | asm!("/* {} */", out(lr) _);
107 | ^^^^^^^^^
108
73109error: register class `xer` can only be used as a clobber, not as an input or output
74 --> $DIR/bad-reg.rs:113:18
110 --> $DIR/bad-reg.rs:135:18
75111 |
76112LL | asm!("", in("xer") x);
77113 | ^^^^^^^^^^^
78114
79115error: register class `xer` can only be used as a clobber, not as an input or output
80 --> $DIR/bad-reg.rs:116:18
116 --> $DIR/bad-reg.rs:138:18
81117 |
82118LL | asm!("", out("xer") x);
83119 | ^^^^^^^^^^^^
84120
85121error: register class `xer` can only be used as a clobber, not as an input or output
86 --> $DIR/bad-reg.rs:119:26
122 --> $DIR/bad-reg.rs:141:26
87123 |
88124LL | asm!("/* {} */", in(xer) x);
89125 | ^^^^^^^^^
90126
91127error: register class `xer` can only be used as a clobber, not as an input or output
92 --> $DIR/bad-reg.rs:122:26
128 --> $DIR/bad-reg.rs:144:26
93129 |
94130LL | asm!("/* {} */", out(xer) _);
95131 | ^^^^^^^^^^
96132
97133error: register `cr0` conflicts with register `cr`
98 --> $DIR/bad-reg.rs:126:31
134 --> $DIR/bad-reg.rs:148:31
99135 |
100136LL | asm!("", out("cr") _, out("cr0") _);
101137 | ----------- ^^^^^^^^^^^^ register `cr0`
......@@ -103,7 +139,7 @@ LL | asm!("", out("cr") _, out("cr0") _);
103139 | register `cr`
104140
105141error: register `cr1` conflicts with register `cr`
106 --> $DIR/bad-reg.rs:128:31
142 --> $DIR/bad-reg.rs:150:31
107143 |
108144LL | asm!("", out("cr") _, out("cr1") _);
109145 | ----------- ^^^^^^^^^^^^ register `cr1`
......@@ -111,7 +147,7 @@ LL | asm!("", out("cr") _, out("cr1") _);
111147 | register `cr`
112148
113149error: register `cr2` conflicts with register `cr`
114 --> $DIR/bad-reg.rs:130:31
150 --> $DIR/bad-reg.rs:152:31
115151 |
116152LL | asm!("", out("cr") _, out("cr2") _);
117153 | ----------- ^^^^^^^^^^^^ register `cr2`
......@@ -119,7 +155,7 @@ LL | asm!("", out("cr") _, out("cr2") _);
119155 | register `cr`
120156
121157error: register `cr3` conflicts with register `cr`
122 --> $DIR/bad-reg.rs:132:31
158 --> $DIR/bad-reg.rs:154:31
123159 |
124160LL | asm!("", out("cr") _, out("cr3") _);
125161 | ----------- ^^^^^^^^^^^^ register `cr3`
......@@ -127,7 +163,7 @@ LL | asm!("", out("cr") _, out("cr3") _);
127163 | register `cr`
128164
129165error: register `cr4` conflicts with register `cr`
130 --> $DIR/bad-reg.rs:134:31
166 --> $DIR/bad-reg.rs:156:31
131167 |
132168LL | asm!("", out("cr") _, out("cr4") _);
133169 | ----------- ^^^^^^^^^^^^ register `cr4`
......@@ -135,7 +171,7 @@ LL | asm!("", out("cr") _, out("cr4") _);
135171 | register `cr`
136172
137173error: register `cr5` conflicts with register `cr`
138 --> $DIR/bad-reg.rs:136:31
174 --> $DIR/bad-reg.rs:158:31
139175 |
140176LL | asm!("", out("cr") _, out("cr5") _);
141177 | ----------- ^^^^^^^^^^^^ register `cr5`
......@@ -143,7 +179,7 @@ LL | asm!("", out("cr") _, out("cr5") _);
143179 | register `cr`
144180
145181error: register `cr6` conflicts with register `cr`
146 --> $DIR/bad-reg.rs:138:31
182 --> $DIR/bad-reg.rs:160:31
147183 |
148184LL | asm!("", out("cr") _, out("cr6") _);
149185 | ----------- ^^^^^^^^^^^^ register `cr6`
......@@ -151,7 +187,7 @@ LL | asm!("", out("cr") _, out("cr6") _);
151187 | register `cr`
152188
153189error: register `cr7` conflicts with register `cr`
154 --> $DIR/bad-reg.rs:140:31
190 --> $DIR/bad-reg.rs:162:31
155191 |
156192LL | asm!("", out("cr") _, out("cr7") _);
157193 | ----------- ^^^^^^^^^^^^ register `cr7`
......@@ -165,7 +201,7 @@ LL | asm!("", out("r13") _);
165201 | ^^^^^^^^^^^^
166202
167203error: `vsx` target feature is not enabled
168 --> $DIR/bad-reg.rs:61:27
204 --> $DIR/bad-reg.rs:57:27
169205 |
170206LL | asm!("", in("v0") v64x2); // requires vsx
171207 | ^^^^^
......@@ -173,7 +209,7 @@ LL | asm!("", in("v0") v64x2); // requires vsx
173209 = note: this is required to use type `i64x2` with register class `vreg`
174210
175211error: `vsx` target feature is not enabled
176 --> $DIR/bad-reg.rs:64:28
212 --> $DIR/bad-reg.rs:60:28
177213 |
178214LL | asm!("", out("v0") v64x2); // requires vsx
179215 | ^^^^^
......@@ -181,7 +217,7 @@ LL | asm!("", out("v0") v64x2); // requires vsx
181217 = note: this is required to use type `i64x2` with register class `vreg`
182218
183219error: type `i32` cannot be used with this register class
184 --> $DIR/bad-reg.rs:67:27
220 --> $DIR/bad-reg.rs:63:27
185221 |
186222LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available
187223 | ^
......@@ -189,7 +225,7 @@ LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available
189225 = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
190226
191227error: type `i32` cannot be used with this register class
192 --> $DIR/bad-reg.rs:70:28
228 --> $DIR/bad-reg.rs:66:28
193229 |
194230LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available
195231 | ^
......@@ -197,7 +233,7 @@ LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available
197233 = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
198234
199235error: `vsx` target feature is not enabled
200 --> $DIR/bad-reg.rs:75:35
236 --> $DIR/bad-reg.rs:71:35
201237 |
202238LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx
203239 | ^^^^^
......@@ -205,7 +241,7 @@ LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx
205241 = note: this is required to use type `i64x2` with register class `vreg`
206242
207243error: type `i32` cannot be used with this register class
208 --> $DIR/bad-reg.rs:78:35
244 --> $DIR/bad-reg.rs:74:35
209245 |
210246LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available
211247 | ^
......@@ -213,7 +249,7 @@ LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is avai
213249 = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
214250
215251error: type `i32` cannot be used with this register class
216 --> $DIR/bad-reg.rs:100:27
252 --> $DIR/bad-reg.rs:96:27
217253 |
218254LL | asm!("", in("cr") x);
219255 | ^
......@@ -221,7 +257,7 @@ LL | asm!("", in("cr") x);
221257 = note: register class `cr` supports these types:
222258
223259error: type `i32` cannot be used with this register class
224 --> $DIR/bad-reg.rs:103:28
260 --> $DIR/bad-reg.rs:99:28
225261 |
226262LL | asm!("", out("cr") x);
227263 | ^
......@@ -229,7 +265,7 @@ LL | asm!("", out("cr") x);
229265 = note: register class `cr` supports these types:
230266
231267error: type `i32` cannot be used with this register class
232 --> $DIR/bad-reg.rs:106:33
268 --> $DIR/bad-reg.rs:102:33
233269 |
234270LL | asm!("/* {} */", in(cr) x);
235271 | ^
......@@ -237,7 +273,55 @@ LL | asm!("/* {} */", in(cr) x);
237273 = note: register class `cr` supports these types:
238274
239275error: type `i32` cannot be used with this register class
240 --> $DIR/bad-reg.rs:113:28
276 --> $DIR/bad-reg.rs:109:28
277 |
278LL | asm!("", in("ctr") x);
279 | ^
280 |
281 = note: register class `ctr` supports these types:
282
283error: type `i32` cannot be used with this register class
284 --> $DIR/bad-reg.rs:112:29
285 |
286LL | asm!("", out("ctr") x);
287 | ^
288 |
289 = note: register class `ctr` supports these types:
290
291error: type `i32` cannot be used with this register class
292 --> $DIR/bad-reg.rs:115:34
293 |
294LL | asm!("/* {} */", in(ctr) x);
295 | ^
296 |
297 = note: register class `ctr` supports these types:
298
299error: type `i32` cannot be used with this register class
300 --> $DIR/bad-reg.rs:122:27
301 |
302LL | asm!("", in("lr") x);
303 | ^
304 |
305 = note: register class `lr` supports these types:
306
307error: type `i32` cannot be used with this register class
308 --> $DIR/bad-reg.rs:125:28
309 |
310LL | asm!("", out("lr") x);
311 | ^
312 |
313 = note: register class `lr` supports these types:
314
315error: type `i32` cannot be used with this register class
316 --> $DIR/bad-reg.rs:128:33
317 |
318LL | asm!("/* {} */", in(lr) x);
319 | ^
320 |
321 = note: register class `lr` supports these types:
322
323error: type `i32` cannot be used with this register class
324 --> $DIR/bad-reg.rs:135:28
241325 |
242326LL | asm!("", in("xer") x);
243327 | ^
......@@ -245,7 +329,7 @@ LL | asm!("", in("xer") x);
245329 = note: register class `xer` supports these types:
246330
247331error: type `i32` cannot be used with this register class
248 --> $DIR/bad-reg.rs:116:29
332 --> $DIR/bad-reg.rs:138:29
249333 |
250334LL | asm!("", out("xer") x);
251335 | ^
......@@ -253,12 +337,12 @@ LL | asm!("", out("xer") x);
253337 = note: register class `xer` supports these types:
254338
255339error: type `i32` cannot be used with this register class
256 --> $DIR/bad-reg.rs:119:34
340 --> $DIR/bad-reg.rs:141:34
257341 |
258342LL | asm!("/* {} */", in(xer) x);
259343 | ^
260344 |
261345 = note: register class `xer` supports these types:
262346
263error: aborting due to 37 previous errors
347error: aborting due to 49 previous errors
264348
tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr+123-39
......@@ -28,74 +28,110 @@ error: invalid register `fp`: the frame pointer cannot be used as an operand for
2828LL | asm!("", out("fp") _);
2929 | ^^^^^^^^^^^
3030
31error: invalid register `lr`: the link register cannot be used as an operand for inline asm
32 --> $DIR/bad-reg.rs:48:18
33 |
34LL | asm!("", out("lr") _);
35 | ^^^^^^^^^^^
36
37error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm
38 --> $DIR/bad-reg.rs:50:18
39 |
40LL | asm!("", out("ctr") _);
41 | ^^^^^^^^^^^^
42
4331error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm
44 --> $DIR/bad-reg.rs:52:18
32 --> $DIR/bad-reg.rs:48:18
4533 |
4634LL | asm!("", out("vrsave") _);
4735 | ^^^^^^^^^^^^^^^
4836
4937error: register class `cr` can only be used as a clobber, not as an input or output
50 --> $DIR/bad-reg.rs:100:18
38 --> $DIR/bad-reg.rs:96:18
5139 |
5240LL | asm!("", in("cr") x);
5341 | ^^^^^^^^^^
5442
5543error: register class `cr` can only be used as a clobber, not as an input or output
56 --> $DIR/bad-reg.rs:103:18
44 --> $DIR/bad-reg.rs:99:18
5745 |
5846LL | asm!("", out("cr") x);
5947 | ^^^^^^^^^^^
6048
6149error: register class `cr` can only be used as a clobber, not as an input or output
62 --> $DIR/bad-reg.rs:106:26
50 --> $DIR/bad-reg.rs:102:26
6351 |
6452LL | asm!("/* {} */", in(cr) x);
6553 | ^^^^^^^^
6654
6755error: register class `cr` can only be used as a clobber, not as an input or output
68 --> $DIR/bad-reg.rs:109:26
56 --> $DIR/bad-reg.rs:105:26
6957 |
7058LL | asm!("/* {} */", out(cr) _);
7159 | ^^^^^^^^^
7260
61error: register class `ctr` can only be used as a clobber, not as an input or output
62 --> $DIR/bad-reg.rs:109:18
63 |
64LL | asm!("", in("ctr") x);
65 | ^^^^^^^^^^^
66
67error: register class `ctr` can only be used as a clobber, not as an input or output
68 --> $DIR/bad-reg.rs:112:18
69 |
70LL | asm!("", out("ctr") x);
71 | ^^^^^^^^^^^^
72
73error: register class `ctr` can only be used as a clobber, not as an input or output
74 --> $DIR/bad-reg.rs:115:26
75 |
76LL | asm!("/* {} */", in(ctr) x);
77 | ^^^^^^^^^
78
79error: register class `ctr` can only be used as a clobber, not as an input or output
80 --> $DIR/bad-reg.rs:118:26
81 |
82LL | asm!("/* {} */", out(ctr) _);
83 | ^^^^^^^^^^
84
85error: register class `lr` can only be used as a clobber, not as an input or output
86 --> $DIR/bad-reg.rs:122:18
87 |
88LL | asm!("", in("lr") x);
89 | ^^^^^^^^^^
90
91error: register class `lr` can only be used as a clobber, not as an input or output
92 --> $DIR/bad-reg.rs:125:18
93 |
94LL | asm!("", out("lr") x);
95 | ^^^^^^^^^^^
96
97error: register class `lr` can only be used as a clobber, not as an input or output
98 --> $DIR/bad-reg.rs:128:26
99 |
100LL | asm!("/* {} */", in(lr) x);
101 | ^^^^^^^^
102
103error: register class `lr` can only be used as a clobber, not as an input or output
104 --> $DIR/bad-reg.rs:131:26
105 |
106LL | asm!("/* {} */", out(lr) _);
107 | ^^^^^^^^^
108
73109error: register class `xer` can only be used as a clobber, not as an input or output
74 --> $DIR/bad-reg.rs:113:18
110 --> $DIR/bad-reg.rs:135:18
75111 |
76112LL | asm!("", in("xer") x);
77113 | ^^^^^^^^^^^
78114
79115error: register class `xer` can only be used as a clobber, not as an input or output
80 --> $DIR/bad-reg.rs:116:18
116 --> $DIR/bad-reg.rs:138:18
81117 |
82118LL | asm!("", out("xer") x);
83119 | ^^^^^^^^^^^^
84120
85121error: register class `xer` can only be used as a clobber, not as an input or output
86 --> $DIR/bad-reg.rs:119:26
122 --> $DIR/bad-reg.rs:141:26
87123 |
88124LL | asm!("/* {} */", in(xer) x);
89125 | ^^^^^^^^^
90126
91127error: register class `xer` can only be used as a clobber, not as an input or output
92 --> $DIR/bad-reg.rs:122:26
128 --> $DIR/bad-reg.rs:144:26
93129 |
94130LL | asm!("/* {} */", out(xer) _);
95131 | ^^^^^^^^^^
96132
97133error: register `cr0` conflicts with register `cr`
98 --> $DIR/bad-reg.rs:126:31
134 --> $DIR/bad-reg.rs:148:31
99135 |
100136LL | asm!("", out("cr") _, out("cr0") _);
101137 | ----------- ^^^^^^^^^^^^ register `cr0`
......@@ -103,7 +139,7 @@ LL | asm!("", out("cr") _, out("cr0") _);
103139 | register `cr`
104140
105141error: register `cr1` conflicts with register `cr`
106 --> $DIR/bad-reg.rs:128:31
142 --> $DIR/bad-reg.rs:150:31
107143 |
108144LL | asm!("", out("cr") _, out("cr1") _);
109145 | ----------- ^^^^^^^^^^^^ register `cr1`
......@@ -111,7 +147,7 @@ LL | asm!("", out("cr") _, out("cr1") _);
111147 | register `cr`
112148
113149error: register `cr2` conflicts with register `cr`
114 --> $DIR/bad-reg.rs:130:31
150 --> $DIR/bad-reg.rs:152:31
115151 |
116152LL | asm!("", out("cr") _, out("cr2") _);
117153 | ----------- ^^^^^^^^^^^^ register `cr2`
......@@ -119,7 +155,7 @@ LL | asm!("", out("cr") _, out("cr2") _);
119155 | register `cr`
120156
121157error: register `cr3` conflicts with register `cr`
122 --> $DIR/bad-reg.rs:132:31
158 --> $DIR/bad-reg.rs:154:31
123159 |
124160LL | asm!("", out("cr") _, out("cr3") _);
125161 | ----------- ^^^^^^^^^^^^ register `cr3`
......@@ -127,7 +163,7 @@ LL | asm!("", out("cr") _, out("cr3") _);
127163 | register `cr`
128164
129165error: register `cr4` conflicts with register `cr`
130 --> $DIR/bad-reg.rs:134:31
166 --> $DIR/bad-reg.rs:156:31
131167 |
132168LL | asm!("", out("cr") _, out("cr4") _);
133169 | ----------- ^^^^^^^^^^^^ register `cr4`
......@@ -135,7 +171,7 @@ LL | asm!("", out("cr") _, out("cr4") _);
135171 | register `cr`
136172
137173error: register `cr5` conflicts with register `cr`
138 --> $DIR/bad-reg.rs:136:31
174 --> $DIR/bad-reg.rs:158:31
139175 |
140176LL | asm!("", out("cr") _, out("cr5") _);
141177 | ----------- ^^^^^^^^^^^^ register `cr5`
......@@ -143,7 +179,7 @@ LL | asm!("", out("cr") _, out("cr5") _);
143179 | register `cr`
144180
145181error: register `cr6` conflicts with register `cr`
146 --> $DIR/bad-reg.rs:138:31
182 --> $DIR/bad-reg.rs:160:31
147183 |
148184LL | asm!("", out("cr") _, out("cr6") _);
149185 | ----------- ^^^^^^^^^^^^ register `cr6`
......@@ -151,7 +187,7 @@ LL | asm!("", out("cr") _, out("cr6") _);
151187 | register `cr`
152188
153189error: register `cr7` conflicts with register `cr`
154 --> $DIR/bad-reg.rs:140:31
190 --> $DIR/bad-reg.rs:162:31
155191 |
156192LL | asm!("", out("cr") _, out("cr7") _);
157193 | ----------- ^^^^^^^^^^^^ register `cr7`
......@@ -165,7 +201,7 @@ LL | asm!("", out("r13") _);
165201 | ^^^^^^^^^^^^
166202
167203error: type `i32` cannot be used with this register class
168 --> $DIR/bad-reg.rs:67:27
204 --> $DIR/bad-reg.rs:63:27
169205 |
170206LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available
171207 | ^
......@@ -173,7 +209,7 @@ LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available
173209 = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
174210
175211error: type `i32` cannot be used with this register class
176 --> $DIR/bad-reg.rs:70:28
212 --> $DIR/bad-reg.rs:66:28
177213 |
178214LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available
179215 | ^
......@@ -181,7 +217,7 @@ LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available
181217 = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
182218
183219error: type `i32` cannot be used with this register class
184 --> $DIR/bad-reg.rs:78:35
220 --> $DIR/bad-reg.rs:74:35
185221 |
186222LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available
187223 | ^
......@@ -189,7 +225,7 @@ LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is avai
189225 = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
190226
191227error: type `i32` cannot be used with this register class
192 --> $DIR/bad-reg.rs:100:27
228 --> $DIR/bad-reg.rs:96:27
193229 |
194230LL | asm!("", in("cr") x);
195231 | ^
......@@ -197,7 +233,7 @@ LL | asm!("", in("cr") x);
197233 = note: register class `cr` supports these types:
198234
199235error: type `i32` cannot be used with this register class
200 --> $DIR/bad-reg.rs:103:28
236 --> $DIR/bad-reg.rs:99:28
201237 |
202238LL | asm!("", out("cr") x);
203239 | ^
......@@ -205,7 +241,7 @@ LL | asm!("", out("cr") x);
205241 = note: register class `cr` supports these types:
206242
207243error: type `i32` cannot be used with this register class
208 --> $DIR/bad-reg.rs:106:33
244 --> $DIR/bad-reg.rs:102:33
209245 |
210246LL | asm!("/* {} */", in(cr) x);
211247 | ^
......@@ -213,7 +249,55 @@ LL | asm!("/* {} */", in(cr) x);
213249 = note: register class `cr` supports these types:
214250
215251error: type `i32` cannot be used with this register class
216 --> $DIR/bad-reg.rs:113:28
252 --> $DIR/bad-reg.rs:109:28
253 |
254LL | asm!("", in("ctr") x);
255 | ^
256 |
257 = note: register class `ctr` supports these types:
258
259error: type `i32` cannot be used with this register class
260 --> $DIR/bad-reg.rs:112:29
261 |
262LL | asm!("", out("ctr") x);
263 | ^
264 |
265 = note: register class `ctr` supports these types:
266
267error: type `i32` cannot be used with this register class
268 --> $DIR/bad-reg.rs:115:34
269 |
270LL | asm!("/* {} */", in(ctr) x);
271 | ^
272 |
273 = note: register class `ctr` supports these types:
274
275error: type `i32` cannot be used with this register class
276 --> $DIR/bad-reg.rs:122:27
277 |
278LL | asm!("", in("lr") x);
279 | ^
280 |
281 = note: register class `lr` supports these types:
282
283error: type `i32` cannot be used with this register class
284 --> $DIR/bad-reg.rs:125:28
285 |
286LL | asm!("", out("lr") x);
287 | ^
288 |
289 = note: register class `lr` supports these types:
290
291error: type `i32` cannot be used with this register class
292 --> $DIR/bad-reg.rs:128:33
293 |
294LL | asm!("/* {} */", in(lr) x);
295 | ^
296 |
297 = note: register class `lr` supports these types:
298
299error: type `i32` cannot be used with this register class
300 --> $DIR/bad-reg.rs:135:28
217301 |
218302LL | asm!("", in("xer") x);
219303 | ^
......@@ -221,7 +305,7 @@ LL | asm!("", in("xer") x);
221305 = note: register class `xer` supports these types:
222306
223307error: type `i32` cannot be used with this register class
224 --> $DIR/bad-reg.rs:116:29
308 --> $DIR/bad-reg.rs:138:29
225309 |
226310LL | asm!("", out("xer") x);
227311 | ^
......@@ -229,12 +313,12 @@ LL | asm!("", out("xer") x);
229313 = note: register class `xer` supports these types:
230314
231315error: type `i32` cannot be used with this register class
232 --> $DIR/bad-reg.rs:119:34
316 --> $DIR/bad-reg.rs:141:34
233317 |
234318LL | asm!("/* {} */", in(xer) x);
235319 | ^
236320 |
237321 = note: register class `xer` supports these types:
238322
239error: aborting due to 34 previous errors
323error: aborting due to 46 previous errors
240324
tests/ui/asm/powerpc/bad-reg.rs+26-4
......@@ -45,10 +45,6 @@ fn f() {
4545 //~^ ERROR invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm
4646 asm!("", out("fp") _);
4747 //~^ ERROR invalid register `fp`: the frame pointer cannot be used as an operand for inline asm
48 asm!("", out("lr") _);
49 //~^ ERROR invalid register `lr`: the link register cannot be used as an operand for inline asm
50 asm!("", out("ctr") _);
51 //~^ ERROR invalid register `ctr`: the counter register cannot be used as an operand for inline asm
5248 asm!("", out("vrsave") _);
5349 //~^ ERROR invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm
5450
......@@ -108,6 +104,32 @@ fn f() {
108104 //~| ERROR type `i32` cannot be used with this register class
109105 asm!("/* {} */", out(cr) _);
110106 //~^ ERROR can only be used as a clobber
107 // ctr
108 asm!("", out("ctr") _); // ok
109 asm!("", in("ctr") x);
110 //~^ ERROR can only be used as a clobber
111 //~| ERROR type `i32` cannot be used with this register class
112 asm!("", out("ctr") x);
113 //~^ ERROR can only be used as a clobber
114 //~| ERROR type `i32` cannot be used with this register class
115 asm!("/* {} */", in(ctr) x);
116 //~^ ERROR can only be used as a clobber
117 //~| ERROR type `i32` cannot be used with this register class
118 asm!("/* {} */", out(ctr) _);
119 //~^ ERROR can only be used as a clobber
120 // lr
121 asm!("", out("lr") _); // ok
122 asm!("", in("lr") x);
123 //~^ ERROR can only be used as a clobber
124 //~| ERROR type `i32` cannot be used with this register class
125 asm!("", out("lr") x);
126 //~^ ERROR can only be used as a clobber
127 //~| ERROR type `i32` cannot be used with this register class
128 asm!("/* {} */", in(lr) x);
129 //~^ ERROR can only be used as a clobber
130 //~| ERROR type `i32` cannot be used with this register class
131 asm!("/* {} */", out(lr) _);
132 //~^ ERROR can only be used as a clobber
111133 // xer
112134 asm!("", out("xer") _); // ok
113135 asm!("", in("xer") x);