From fb0210d00b52b04a5bae5ed303ff72f193107e2b Mon Sep 17 00:00:00 2001 From: beetrees Date: Mon, 3 Aug 2026 15:03:22 +0100 Subject: [PATCH 01/18] PowerPC inline ASM: Fix scalar floats being in the wrong vector lane on little endian --- compiler/rustc_codegen_llvm/src/asm.rs | 56 +- tests/assembly-llvm/asm/powerpc-types.rs | 652 +++++++++-------------- 2 files changed, 280 insertions(+), 428 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index d2dfa9a45de8b..3ba28427023e7 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -1,7 +1,7 @@ use std::assert_matches; use std::fmt::Write; -use rustc_abi::{BackendRepr, Float, Integer, Primitive, Scalar, Size}; +use rustc_abi::{BackendRepr, Endian, Float, Integer, Primitive, Scalar, Size}; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_codegen_ssa::mir::operand::OperandValue; use rustc_codegen_ssa::traits::*; @@ -12,6 +12,7 @@ use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::{bug, span_bug}; use rustc_span::{Pos, Span, Symbol, sym}; use rustc_target::asm::*; +use rustc_target::spec::HasTargetSpec; use smallvec::SmallVec; use tracing::debug; @@ -1244,24 +1245,16 @@ fn llvm_fixup_input<'ll, 'tcx>( ( PowerPC(PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg), BackendRepr::Scalar(s), - ) if s.primitive() == Primitive::Float(Float::F32) => { - let value = bx.insert_element( - bx.const_undef(bx.type_vector(bx.type_f32(), 4)), + ) if let Primitive::Float(float @ (Float::F32 | Float::F64)) = s.primitive() => { + let num_lanes = 16 / float.size().bytes(); + bx.insert_element( + bx.const_undef(bx.type_vector(bx.type_from_float(float), num_lanes)), value, - bx.const_usize(0), - ); - bx.bitcast(value, bx.type_vector(bx.type_f32(), 4)) - } - ( - PowerPC(PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg), - BackendRepr::Scalar(s), - ) if s.primitive() == Primitive::Float(Float::F64) => { - let value = bx.insert_element( - bx.const_undef(bx.type_vector(bx.type_f64(), 2)), - value, - bx.const_usize(0), - ); - bx.bitcast(value, bx.type_vector(bx.type_f64(), 2)) + bx.const_usize(match bx.target_spec().endian { + Endian::Little => num_lanes - 1, + Endian::Big => 0, + }), + ) } _ => value, } @@ -1416,16 +1409,15 @@ fn llvm_fixup_output<'ll, 'tcx>( ( PowerPC(PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg), BackendRepr::Scalar(s), - ) if s.primitive() == Primitive::Float(Float::F32) => { - let value = bx.bitcast(value, bx.type_vector(bx.type_f32(), 4)); - bx.extract_element(value, bx.const_usize(0)) - } - ( - PowerPC(PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg), - BackendRepr::Scalar(s), - ) if s.primitive() == Primitive::Float(Float::F64) => { - let value = bx.bitcast(value, bx.type_vector(bx.type_f64(), 2)); - bx.extract_element(value, bx.const_usize(0)) + ) if let Primitive::Float(float @ (Float::F32 | Float::F64)) = s.primitive() => { + let num_lanes = 16 / float.size().bytes(); + bx.extract_element( + value, + bx.const_usize(match bx.target_spec().endian { + Endian::Little => num_lanes - 1, + Endian::Big => 0, + }), + ) } _ => value, } @@ -1566,11 +1558,9 @@ fn llvm_fixup_output_type<'ll, 'tcx>( ( PowerPC(PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg), BackendRepr::Scalar(s), - ) if s.primitive() == Primitive::Float(Float::F32) => cx.type_vector(cx.type_f32(), 4), - ( - PowerPC(PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg), - BackendRepr::Scalar(s), - ) if s.primitive() == Primitive::Float(Float::F64) => cx.type_vector(cx.type_f64(), 2), + ) if let Primitive::Float(float @ (Float::F32 | Float::F64)) = s.primitive() => { + cx.type_vector(cx.type_from_float(float), 16 / float.size().bytes()) + } _ => layout.llvm_type(cx), } } diff --git a/tests/assembly-llvm/asm/powerpc-types.rs b/tests/assembly-llvm/asm/powerpc-types.rs index 211c817a325cb..c1c750914246d 100644 --- a/tests/assembly-llvm/asm/powerpc-types.rs +++ b/tests/assembly-llvm/asm/powerpc-types.rs @@ -1,43 +1,97 @@ +// ignore-tidy-file-linelength (some revision //@ lines are over 100 chars long) + //@ add-minicore -//@ revisions: powerpc powerpc_altivec powerpc_vsx powerpc64 powerpc64_vsx +//@ revisions: powerpc powerpc_altivec powerpc_vsx powerpc_power8 powerpc64 powerpc64_vsx powerpc64_power8 powerpc64le //@ assembly-output: emit-asm //@[powerpc] compile-flags: --target powerpc-unknown-linux-gnu //@[powerpc] needs-llvm-components: powerpc //@[powerpc_altivec] compile-flags: --target powerpc-unknown-linux-gnu -C target-feature=+altivec --cfg altivec //@[powerpc_altivec] needs-llvm-components: powerpc +//@[powerpc_altivec] filecheck-flags: --check-prefix altivec //@[powerpc_vsx] compile-flags: --target powerpc-unknown-linux-gnu -C target-feature=+altivec,+vsx --cfg altivec --cfg vsx //@[powerpc_vsx] needs-llvm-components: powerpc +//@[powerpc_vsx] filecheck-flags: --check-prefix altivec --check-prefix vsx +//@[powerpc_power8] compile-flags: --target powerpc-unknown-linux-gnu -C target-feature=+altivec,+vsx,+power8-vector --cfg altivec --cfg vsx --cfg power8 +//@[powerpc_power8] needs-llvm-components: powerpc +//@[powerpc_power8] filecheck-flags: --check-prefix altivec --check-prefix vsx --check-prefix power8 //@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu --cfg altivec //@[powerpc64] needs-llvm-components: powerpc -//@[powerpc64_vsx] compile-flags: --target powerpc64-unknown-linux-gnu -C target-feature=+vsx --cfg altivec --cfg vsx +//@[powerpc64] filecheck-flags: --check-prefix altivec +//@[powerpc64_vsx] compile-flags: --target powerpc64-unknown-linux-gnu -C target-feature=+vsx --cfg powerpc64 --cfg altivec --cfg vsx //@[powerpc64_vsx] needs-llvm-components: powerpc +//@[powerpc64_vsx] filecheck-flags: --check-prefix powerpc64 --check-prefix altivec --check-prefix vsx +//@[powerpc64_power8] compile-flags: --target powerpc64-unknown-linux-gnu -C target-feature=+vsx,+power8-vector --cfg powerpc64 --cfg altivec --cfg vsx --cfg power8 +//@[powerpc64_power8] needs-llvm-components: powerpc +//@[powerpc64_power8] filecheck-flags: --check-prefix powerpc64 --check-prefix altivec --check-prefix vsx --check-prefix power8 +//@[powerpc64le] compile-flags: --target powerpc64le-unknown-linux-gnu --cfg powerpc64 --cfg altivec --cfg vsx --cfg power8 +//@[powerpc64le] needs-llvm-components: powerpc +//@[powerpc64le] filecheck-flags: --check-prefix powerpc64 --check-prefix altivec --check-prefix vsx --check-prefix power8 //@ compile-flags: -Zmerge-functions=disabled +//@ compile-flags: --check-cfg=cfg(altivec,vsx,power8) -#![feature(no_core, asm_experimental_arch)] +#![feature(no_core)] #![crate_type = "rlib"] #![no_core] -#![allow(asm_sub_register, non_camel_case_types)] +#![allow(asm_sub_register, non_camel_case_types, unused_imports)] +#![deny(unexpected_cfgs)] extern crate minicore; use minicore::simd::*; use minicore::*; +#[cfg_attr(powerpc64, cfg(not(target_arch = "powerpc64")))] +#[cfg_attr(not(powerpc64), cfg(target_arch = "powerpc64"))] +compile_error!("powerpc64 cfg and target arch mismatch"); #[cfg_attr(altivec, cfg(not(target_feature = "altivec")))] #[cfg_attr(not(altivec), cfg(target_feature = "altivec"))] compile_error!("altivec cfg and target feature mismatch"); #[cfg_attr(vsx, cfg(not(target_feature = "vsx")))] #[cfg_attr(not(vsx), cfg(target_feature = "vsx"))] compile_error!("vsx cfg and target feature mismatch"); +#[cfg_attr(power8, cfg(not(target_feature = "power8-vector")))] +#[cfg_attr(not(power8), cfg(target_feature = "power8-vector"))] +compile_error!("power8-vector cfg and target feature mismatch"); + +// Check floating point scalars are put in the right vector lane. This uses power8 for consistent +// assembly between powerpc64le and big-endian powerpc/powerpc64. + +// power8-LABEL: f32_to_f64: +// power8: .cfi_startproc +// power8-NEXT: xscvdpspn [[#INPUT:]], 1 +// powerpc64le-NEXT: vmrgow [[#INPUT - 32]], [[#INPUT - 32]], [[#INPUT - 32]] +// power8-NEXT: #APP +// power8-NEXT: xscvspdp 1, [[#INPUT]] +// power8-NEXT: #NO_APP +// power8-NEXT: blr +#[cfg(power8)] +#[unsafe(no_mangle)] +pub fn f32_to_f64(x: f32) -> f64 { + let res; + unsafe { + asm!("xscvspdp {}, {}", out(vsreg) res, in(vsreg) x, options(pure, nostack, nomem)); + }; + res +} -type ptr = *const i32; - -extern "C" { - fn extern_func(); - static extern_static: u8; +// power8-LABEL: f64_to_f32: +// power8: .cfi_startproc +// power8-NEXT: #APP +// power8-NEXT: xscvdpsp [[#OUTPUT:]], 1 +// power8-NEXT: #NO_APP +// power8-NEXT: xscvspdpn 1, [[#OUTPUT]] +// power8-NEXT: blr +#[cfg(power8)] +#[unsafe(no_mangle)] +pub fn f64_to_f32(x: f64) -> f32 { + let res; + unsafe { + asm!("xscvdpsp {}, {}", out(vsreg) res, in(vsreg) x, options(pure, nostack, nomem)); + }; + res } macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => { - #[no_mangle] + #[unsafe(no_mangle)] pub unsafe fn $func(x: $ty) -> $ty { let y; asm!(concat!($mov," {}, {}"), out($class) y, in($class) x); @@ -46,7 +100,7 @@ macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => { };} macro_rules! check_reg { ($func:ident, $ty:ty, $rego:tt, $regc:tt, $mov:literal) => { - #[no_mangle] + #[unsafe(no_mangle)] pub unsafe fn $func(x: $ty) -> $ty { let y; asm!(concat!($mov, " ", $rego, ", ", $rego), lateout($regc) y, in($regc) x); @@ -116,179 +170,115 @@ check!(reg_f32, f32, freg, "fmr"); // CHECK: #NO_APP check!(reg_f64, f64, freg, "fmr"); -// powerpc_altivec-LABEL: vreg_i8x16: -// powerpc_altivec: #APP -// powerpc_altivec: vmr {{[0-9]+}}, {{[0-9]+}} -// powerpc_altivec: #NO_APP -// powerpc64-LABEL: vreg_i8x16: -// powerpc64: #APP -// powerpc64: vmr {{[0-9]+}}, {{[0-9]+}} -// powerpc64: #NO_APP +// altivec-LABEL: vreg_i8x16: +// altivec: #APP +// altivec: vmr {{[0-9]+}}, {{[0-9]+}} +// altivec: #NO_APP #[cfg(altivec)] check!(vreg_i8x16, i8x16, vreg, "vmr"); -// powerpc_altivec-LABEL: vreg_i16x8: -// powerpc_altivec: #APP -// powerpc_altivec: vmr {{[0-9]+}}, {{[0-9]+}} -// powerpc_altivec: #NO_APP -// powerpc64-LABEL: vreg_i16x8: -// powerpc64: #APP -// powerpc64: vmr {{[0-9]+}}, {{[0-9]+}} -// powerpc64: #NO_APP +// altivec-LABEL: vreg_i16x8: +// altivec: #APP +// altivec: vmr {{[0-9]+}}, {{[0-9]+}} +// altivec: #NO_APP #[cfg(altivec)] check!(vreg_i16x8, i16x8, vreg, "vmr"); -// powerpc_altivec-LABEL: vreg_i32x4: -// powerpc_altivec: #APP -// powerpc_altivec: vmr {{[0-9]+}}, {{[0-9]+}} -// powerpc_altivec: #NO_APP -// powerpc64-LABEL: vreg_i32x4: -// powerpc64: #APP -// powerpc64: vmr {{[0-9]+}}, {{[0-9]+}} -// powerpc64: #NO_APP +// altivec-LABEL: vreg_i32x4: +// altivec: #APP +// altivec: vmr {{[0-9]+}}, {{[0-9]+}} +// altivec: #NO_APP #[cfg(altivec)] check!(vreg_i32x4, i32x4, vreg, "vmr"); -// powerpc_vsx-LABEL: vreg_i64x2: -// powerpc_vsx: #APP -// powerpc_vsx: vmr {{[0-9]+}}, {{[0-9]+}} -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vreg_i64x2: -// powerpc64_vsx: #APP -// powerpc64_vsx: vmr {{[0-9]+}}, {{[0-9]+}} -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vreg_i64x2: +// vsx: #APP +// vsx: vmr {{[0-9]+}}, {{[0-9]+}} +// vsx: #NO_APP #[cfg(vsx)] check!(vreg_i64x2, i64x2, vreg, "vmr"); -// powerpc_altivec-LABEL: vreg_f32x4: -// powerpc_altivec: #APP -// powerpc_altivec: vmr {{[0-9]+}}, {{[0-9]+}} -// powerpc_altivec: #NO_APP -// powerpc64-LABEL: vreg_f32x4: -// powerpc64: #APP -// powerpc64: vmr {{[0-9]+}}, {{[0-9]+}} -// powerpc64: #NO_APP +// altivec-LABEL: vreg_f32x4: +// altivec: #APP +// altivec: vmr {{[0-9]+}}, {{[0-9]+}} +// altivec: #NO_APP #[cfg(altivec)] check!(vreg_f32x4, f32x4, vreg, "vmr"); -// powerpc_vsx-LABEL: vreg_f64x2: -// powerpc_vsx: #APP -// powerpc_vsx: vmr {{[0-9]+}}, {{[0-9]+}} -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vreg_f64x2: -// powerpc64_vsx: #APP -// powerpc64_vsx: vmr {{[0-9]+}}, {{[0-9]+}} -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vreg_f64x2: +// vsx: #APP +// vsx: vmr {{[0-9]+}}, {{[0-9]+}} +// vsx: #NO_APP #[cfg(vsx)] check!(vreg_f64x2, f64x2, vreg, "vmr"); -// powerpc_vsx-LABEL: vreg_f32: -// powerpc_vsx: #APP -// powerpc_vsx: vmr {{[0-9]+}}, {{[0-9]+}} -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vreg_f32: -// powerpc64_vsx: #APP -// powerpc64_vsx: vmr {{[0-9]+}}, {{[0-9]+}} -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vreg_f32: +// vsx: #APP +// vsx: vmr {{[0-9]+}}, {{[0-9]+}} +// vsx: #NO_APP #[cfg(vsx)] check!(vreg_f32, f32, vreg, "vmr"); -// powerpc_vsx-LABEL: vreg_f64: -// powerpc_vsx: #APP -// powerpc_vsx: vmr {{[0-9]+}}, {{[0-9]+}} -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vreg_f64: -// powerpc64_vsx: #APP -// powerpc64_vsx: vmr {{[0-9]+}}, {{[0-9]+}} -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vreg_f64: +// vsx: #APP +// vsx: vmr {{[0-9]+}}, {{[0-9]+}} +// vsx: #NO_APP #[cfg(vsx)] check!(vreg_f64, f64, vreg, "vmr"); -// powerpc_vsx-LABEL: vsreg_i8x16: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_i8x16: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_i8x16: +// vsx: #APP +// vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// vsx: #NO_APP #[cfg(vsx)] check!(vsreg_i8x16, i8x16, vsreg, "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_i16x8: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_i16x8: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_i16x8: +// vsx: #APP +// vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// vsx: #NO_APP #[cfg(vsx)] check!(vsreg_i16x8, i16x8, vsreg, "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_i32x4: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_i32x4: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_i32x4: +// vsx: #APP +// vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// vsx: #NO_APP #[cfg(vsx)] check!(vsreg_i32x4, i32x4, vsreg, "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_i64x2: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_i64x2: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_i64x2: +// vsx: #APP +// vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// vsx: #NO_APP #[cfg(vsx)] check!(vsreg_i64x2, i64x2, vsreg, "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_f32x4: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_f32x4: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_f32x4: +// vsx: #APP +// vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// vsx: #NO_APP #[cfg(vsx)] check!(vsreg_f32x4, f32x4, vsreg, "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_f64x2: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_f64x2: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_f64x2: +// vsx: #APP +// vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// vsx: #NO_APP #[cfg(vsx)] check!(vsreg_f64x2, f64x2, vsreg, "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_f32: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_f32: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_f32: +// vsx: #APP +// vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// vsx: #NO_APP #[cfg(vsx)] check!(vsreg_f32, f32, vsreg, "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_f64: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_f64: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_f64: +// vsx: #APP +// vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// vsx: #NO_APP #[cfg(vsx)] check!(vsreg_f64, f64, vsreg, "xvsqrtdp"); @@ -366,354 +356,226 @@ check_reg!(reg_f32_f18, f32, "18", "f18", "fmr"); // CHECK: #NO_APP check_reg!(reg_f64_f18, f64, "18", "f18", "fmr"); -// powerpc_altivec-LABEL: vreg_i8x16_v0: -// powerpc_altivec: #APP -// powerpc_altivec: vmr 0, 0 -// powerpc_altivec: #NO_APP -// powerpc64-LABEL: vreg_i8x16_v0: -// powerpc64: #APP -// powerpc64: vmr 0, 0 -// powerpc64: #NO_APP +// altivec-LABEL: vreg_i8x16_v0: +// altivec: #APP +// altivec: vmr 0, 0 +// altivec: #NO_APP #[cfg(altivec)] check_reg!(vreg_i8x16_v0, i8x16, "0", "v0", "vmr"); -// powerpc_altivec-LABEL: vreg_i16x8_v0: -// powerpc_altivec: #APP -// powerpc_altivec: vmr 0, 0 -// powerpc_altivec: #NO_APP -// powerpc64-LABEL: vreg_i16x8_v0: -// powerpc64: #APP -// powerpc64: vmr 0, 0 -// powerpc64: #NO_APP +// altivec-LABEL: vreg_i16x8_v0: +// altivec: #APP +// altivec: vmr 0, 0 +// altivec: #NO_APP #[cfg(altivec)] check_reg!(vreg_i16x8_v0, i16x8, "0", "v0", "vmr"); -// powerpc_altivec-LABEL: vreg_i32x4_v0: -// powerpc_altivec: #APP -// powerpc_altivec: vmr 0, 0 -// powerpc_altivec: #NO_APP -// powerpc64-LABEL: vreg_i32x4_v0: -// powerpc64: #APP -// powerpc64: vmr 0, 0 -// powerpc64: #NO_APP +// altivec-LABEL: vreg_i32x4_v0: +// altivec: #APP +// altivec: vmr 0, 0 +// altivec: #NO_APP #[cfg(altivec)] check_reg!(vreg_i32x4_v0, i32x4, "0", "v0", "vmr"); -// powerpc_vsx-LABEL: vreg_i64x2_v0: -// powerpc_vsx: #APP -// powerpc_vsx: vmr 0, 0 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vreg_i64x2_v0: -// powerpc64_vsx: #APP -// powerpc64_vsx: vmr 0, 0 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vreg_i64x2_v0: +// vsx: #APP +// vsx: vmr 0, 0 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vreg_i64x2_v0, i64x2, "0", "v0", "vmr"); -// powerpc_altivec-LABEL: vreg_f32x4_v0: -// powerpc_altivec: #APP -// powerpc_altivec: vmr 0, 0 -// powerpc_altivec: #NO_APP -// powerpc64-LABEL: vreg_f32x4_v0: -// powerpc64: #APP -// powerpc64: vmr 0, 0 -// powerpc64: #NO_APP +// altivec-LABEL: vreg_f32x4_v0: +// altivec: #APP +// altivec: vmr 0, 0 +// altivec: #NO_APP #[cfg(altivec)] check_reg!(vreg_f32x4_v0, f32x4, "0", "v0", "vmr"); -// powerpc_vsx-LABEL: vreg_f64x2_v0: -// powerpc_vsx: #APP -// powerpc_vsx: vmr 0, 0 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vreg_f64x2_v0: -// powerpc64_vsx: #APP -// powerpc64_vsx: vmr 0, 0 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vreg_f64x2_v0: +// vsx: #APP +// vsx: vmr 0, 0 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vreg_f64x2_v0, f64x2, "0", "v0", "vmr"); -// powerpc_vsx-LABEL: vreg_f32_v0: -// powerpc_vsx: #APP -// powerpc_vsx: vmr 0, 0 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vreg_f32_v0: -// powerpc64_vsx: #APP -// powerpc64_vsx: vmr 0, 0 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vreg_f32_v0: +// vsx: #APP +// vsx: vmr 0, 0 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vreg_f32_v0, f32, "0", "v0", "vmr"); -// powerpc_vsx-LABEL: vreg_f64_v0: -// powerpc_vsx: #APP -// powerpc_vsx: vmr 0, 0 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vreg_f64_v0: -// powerpc64_vsx: #APP -// powerpc64_vsx: vmr 0, 0 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vreg_f64_v0: +// vsx: #APP +// vsx: vmr 0, 0 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vreg_f64_v0, f64, "0", "v0", "vmr"); -// powerpc_altivec-LABEL: vreg_i8x16_v18: -// powerpc_altivec: #APP -// powerpc_altivec: vmr 18, 18 -// powerpc_altivec: #NO_APP -// powerpc64-LABEL: vreg_i8x16_v18: -// powerpc64: #APP -// powerpc64: vmr 18, 18 -// powerpc64: #NO_APP +// altivec-LABEL: vreg_i8x16_v18: +// altivec: #APP +// altivec: vmr 18, 18 +// altivec: #NO_APP #[cfg(altivec)] check_reg!(vreg_i8x16_v18, i8x16, "18", "v18", "vmr"); -// powerpc_altivec-LABEL: vreg_i16x8_v18: -// powerpc_altivec: #APP -// powerpc_altivec: vmr 18, 18 -// powerpc_altivec: #NO_APP -// powerpc64-LABEL: vreg_i16x8_v18: -// powerpc64: #APP -// powerpc64: vmr 18, 18 -// powerpc64: #NO_APP +// altivec-LABEL: vreg_i16x8_v18: +// altivec: #APP +// altivec: vmr 18, 18 +// altivec: #NO_APP #[cfg(altivec)] check_reg!(vreg_i16x8_v18, i16x8, "18", "v18", "vmr"); -// powerpc_altivec-LABEL: vreg_i32x4_v18: -// powerpc_altivec: #APP -// powerpc_altivec: vmr 18, 18 -// powerpc_altivec: #NO_APP -// powerpc64-LABEL: vreg_i32x4_v18: -// powerpc64: #APP -// powerpc64: vmr 18, 18 -// powerpc64: #NO_APP +// altivec-LABEL: vreg_i32x4_v18: +// altivec: #APP +// altivec: vmr 18, 18 +// altivec: #NO_APP #[cfg(altivec)] check_reg!(vreg_i32x4_v18, i32x4, "18", "v18", "vmr"); -// powerpc_vsx-LABEL: vreg_i64x2_v18: -// powerpc_vsx: #APP -// powerpc_vsx: vmr 18, 18 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vreg_i64x2_v18: -// powerpc64_vsx: #APP -// powerpc64_vsx: vmr 18, 18 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vreg_i64x2_v18: +// vsx: #APP +// vsx: vmr 18, 18 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vreg_i64x2_v18, i64x2, "18", "v18", "vmr"); -// powerpc_altivec-LABEL: vreg_f32x4_v18: -// powerpc_altivec: #APP -// powerpc_altivec: vmr 18, 18 -// powerpc_altivec: #NO_APP -// powerpc64-LABEL: vreg_f32x4_v18: -// powerpc64: #APP -// powerpc64: vmr 18, 18 -// powerpc64: #NO_APP +// altivec-LABEL: vreg_f32x4_v18: +// altivec: #APP +// altivec: vmr 18, 18 +// altivec: #NO_APP #[cfg(altivec)] check_reg!(vreg_f32x4_v18, f32x4, "18", "v18", "vmr"); -// powerpc_vsx-LABEL: vreg_f64x2_v18: -// powerpc_vsx: #APP -// powerpc_vsx: vmr 18, 18 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vreg_f64x2_v18: -// powerpc64_vsx: #APP -// powerpc64_vsx: vmr 18, 18 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vreg_f64x2_v18: +// vsx: #APP +// vsx: vmr 18, 18 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vreg_f64x2_v18, f64x2, "18", "v18", "vmr"); -// powerpc_vsx-LABEL: vreg_f32_v18: -// powerpc_vsx: #APP -// powerpc_vsx: vmr 18, 18 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vreg_f32_v18: -// powerpc64_vsx: #APP -// powerpc64_vsx: vmr 18, 18 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vreg_f32_v18: +// vsx: #APP +// vsx: vmr 18, 18 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vreg_f32_v18, f32, "18", "v18", "vmr"); -// powerpc_vsx-LABEL: vreg_f64_v18: -// powerpc_vsx: #APP -// powerpc_vsx: vmr 18, 18 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vreg_f64_v18: -// powerpc64_vsx: #APP -// powerpc64_vsx: vmr 18, 18 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vreg_f64_v18: +// vsx: #APP +// vsx: vmr 18, 18 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vreg_f64_v18, f64, "18", "v18", "vmr"); -// powerpc_vsx-LABEL: vsreg_i8x16_vs0: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp 0, 0 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_i8x16_vs0: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp 0, 0 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_i8x16_vs0: +// vsx: #APP +// vsx: xvsqrtdp 0, 0 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vsreg_i8x16_vs0, i8x16, "0", "vs0", "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_i16x8_vs0: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp 0, 0 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_i16x8_vs0: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp 0, 0 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_i16x8_vs0: +// vsx: #APP +// vsx: xvsqrtdp 0, 0 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vsreg_i16x8_vs0, i16x8, "0", "vs0", "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_i32x4_vs0: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp 0, 0 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_i32x4_vs0: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp 0, 0 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_i32x4_vs0: +// vsx: #APP +// vsx: xvsqrtdp 0, 0 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vsreg_i32x4_vs0, i32x4, "0", "vs0", "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_i64x2_vs0: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp 0, 0 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_i64x2_vs0: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp 0, 0 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_i64x2_vs0: +// vsx: #APP +// vsx: xvsqrtdp 0, 0 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vsreg_i64x2_vs0, i64x2, "0", "vs0", "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_f32x4_vs0: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp 0, 0 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_f32x4_vs0: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp 0, 0 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_f32x4_vs0: +// vsx: #APP +// vsx: xvsqrtdp 0, 0 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vsreg_f32x4_vs0, f32x4, "0", "vs0", "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_f64x2_vs0: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp 0, 0 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_f64x2_vs0: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp 0, 0 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_f64x2_vs0: +// vsx: #APP +// vsx: xvsqrtdp 0, 0 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vsreg_f64x2_vs0, f64x2, "0", "vs0", "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_f32_vs0: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp 0, 0 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_f32_vs0: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp 0, 0 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_f32_vs0: +// vsx: #APP +// vsx: xvsqrtdp 0, 0 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vsreg_f32_vs0, f32, "0", "vs0", "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_f64_vs0: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp 0, 0 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_f64_vs0: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp 0, 0 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_f64_vs0: +// vsx: #APP +// vsx: xvsqrtdp 0, 0 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vsreg_f64_vs0, f64, "0", "vs0", "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_i8x16_v40: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp 40, 40 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_i8x16_v40: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp 40, 40 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_i8x16_v40: +// vsx: #APP +// vsx: xvsqrtdp 40, 40 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vsreg_i8x16_v40, i8x16, "40", "vs40", "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_i16x8_v40: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp 40, 40 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_i16x8_v40: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp 40, 40 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_i16x8_v40: +// vsx: #APP +// vsx: xvsqrtdp 40, 40 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vsreg_i16x8_v40, i16x8, "40", "vs40", "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_i32x4_v40: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp 40, 40 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_i32x4_v40: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp 40, 40 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_i32x4_v40: +// vsx: #APP +// vsx: xvsqrtdp 40, 40 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vsreg_i32x4_v40, i32x4, "40", "vs40", "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_i64x2_v40: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp 40, 40 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_i64x2_v40: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp 40, 40 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_i64x2_v40: +// vsx: #APP +// vsx: xvsqrtdp 40, 40 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vsreg_i64x2_v40, i64x2, "40", "vs40", "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_f32x4_v40: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp 40, 40 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_f32x4_v40: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp 40, 40 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_f32x4_v40: +// vsx: #APP +// vsx: xvsqrtdp 40, 40 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vsreg_f32x4_v40, f32x4, "40", "vs40", "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_f64x2_v40: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp 40, 40 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_f64x2_v40: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp 40, 40 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_f64x2_v40: +// vsx: #APP +// vsx: xvsqrtdp 40, 40 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vsreg_f64x2_v40, f64x2, "40", "vs40", "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_f32_v40: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp 40, 40 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_f32_v40: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp 40, 40 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_f32_v40: +// vsx: #APP +// vsx: xvsqrtdp 40, 40 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vsreg_f32_v40, f32, "40", "vs40", "xvsqrtdp"); -// powerpc_vsx-LABEL: vsreg_f64_v40: -// powerpc_vsx: #APP -// powerpc_vsx: xvsqrtdp 40, 40 -// powerpc_vsx: #NO_APP -// powerpc64_vsx-LABEL: vsreg_f64_v40: -// powerpc64_vsx: #APP -// powerpc64_vsx: xvsqrtdp 40, 40 -// powerpc64_vsx: #NO_APP +// vsx-LABEL: vsreg_f64_v40: +// vsx: #APP +// vsx: xvsqrtdp 40, 40 +// vsx: #NO_APP #[cfg(vsx)] check_reg!(vsreg_f64_v40, f64, "40", "vs40", "xvsqrtdp"); From 3d9bfe9c51a8c9594321e7959368b5ab795fc9d1 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Tue, 4 Aug 2026 21:43:05 +0200 Subject: [PATCH 02/18] rustdoc: use anonymous constant for primitives/keywords/attribute docs --- .../src/attributes/rustc_internal.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 19 ++--- compiler/rustc_passes/src/diagnostics.rs | 12 +-- library/core/src/attribute_docs.rs | 28 +++---- library/core/src/keyword_docs.rs | 80 +++++++++---------- library/core/src/primitive_docs.rs | 54 ++++++------- src/doc/rustdoc/src/unstable-features.md | 4 +- src/librustdoc/clean/types.rs | 18 +++-- .../rustdoc/search-load-itemtype/foo.rs | 9 +-- tests/rustdoc-gui/src/test_docs/lib.rs | 4 +- .../rustdoc-html/auto/auto-impl-primitive.rs | 2 +- tests/rustdoc-html/doc-attribute.rs | 6 +- tests/rustdoc-html/doc-on-keyword.rs | 2 +- .../intra-doc/auxiliary/my-core.rs | 2 +- .../intra-doc/prim-methods-local.rs | 2 +- tests/rustdoc-html/intra-doc/prim-self.rs | 2 +- tests/rustdoc-html/keyword.rs | 6 +- ...-notable_trait-mut_t_is_not_an_iterator.rs | 2 +- .../doc-notable_trait-mut_t_is_not_ref_t.rs | 2 +- .../primitive/auxiliary/issue-15318.rs | 2 +- .../primitive/auxiliary/primitive-doc.rs | 14 +++- .../primitive/cross-crate-primitive-doc.rs | 11 +-- .../primitive/primitive-generic-impl.rs | 2 +- .../primitive-raw-pointer-dox-15318-3.rs | 2 +- ...ive-raw-pointer-link-no-inlined-15318-2.rs | 2 - .../primitive/primitive-reference.rs | 2 +- .../primitive/primitive-slice-auto-trait.rs | 2 +- .../primitive/primitive-tuple-auto-trait.rs | 2 +- .../primitive/primitive-unit-auto-trait.rs | 2 +- tests/rustdoc-html/primitive/primitive.rs | 8 +- ...h-index-primitive-inherent-method-23511.rs | 13 ++- .../rustdoc-html/sidebar/sidebar-all-page.rs | 2 +- .../check-source-code-urls-to-def.rs | 2 +- tests/rustdoc-html/stability.rs | 4 +- tests/rustdoc-html/tab_title.rs | 4 +- tests/rustdoc-html/titles.rs | 2 +- .../type-alias/primitive-local-link-121106.rs | 2 +- tests/rustdoc-json/doc_attribute.rs | 7 +- .../impls/local_for_local_primitive.rs | 2 +- tests/rustdoc-json/keyword.rs | 15 ++-- tests/rustdoc-json/keyword_private.rs | 19 +++-- .../primitives/local_primitive.rs | 16 ++-- .../primitives/primitive_impls.rs | 2 +- .../primitives/primitive_overloading.rs | 3 +- .../rustdoc-json/primitives/use_primitive.rs | 3 +- tests/rustdoc-ui/coverage/exotic.rs | 4 +- tests/rustdoc-ui/doc-attribute-unsupported.rs | 2 +- tests/rustdoc-ui/invalid-attribute.rs | 4 +- tests/rustdoc-ui/invalid-keyword.rs | 2 +- .../feature-gate-rustdoc_internals.rs | 4 +- tests/ui/rustdoc/doc_keyword.rs | 10 +-- tests/ui/rustdoc/doc_keyword.stderr | 18 ++--- .../ui/rustdoc/feature-gate-doc_primitive.rs | 2 +- 53 files changed, 206 insertions(+), 241 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index fe90b51c221a1..94d7d70d07afc 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -1132,7 +1132,7 @@ pub(crate) struct RustcDocPrimitiveParser; impl SingleAttributeParser for RustcDocPrimitiveParser { const PATH: &[Symbol] = &[sym::rustc_doc_primitive]; - const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Mod)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Const)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "primitive name"); const STABILITY: AttributeStability = unstable!( rustc_attrs, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 44c34a2abddd1..e035e16cabb91 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -44,7 +44,7 @@ use rustc_session::lint::builtin::{ MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, MISPLACED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES, }; use rustc_span::edition::Edition; -use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym}; +use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs}; use rustc_trait_selection::traits::{ObligationCtxt, TraitErrors}; @@ -1024,18 +1024,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { hir::Node::Item(item) => Some(&item.kind), _ => None, }; - match item_kind { - Some(ItemKind::Mod(_, module)) => { - if !module.item_ids.is_empty() { - self.dcx() - .emit_err(diagnostics::DocKeywordAttributeEmptyMod { span, attr_name }); - return; - } - } - _ => { - self.dcx().emit_err(diagnostics::DocKeywordAttributeNotMod { span, attr_name }); - return; - } + if let Some(ItemKind::Const(ident, _gen, _ty, _rhs)) = item_kind + && ident.name == kw::Underscore + { + } else { + self.dcx().emit_err(diagnostics::DocKeywordAttributeNotAnonConst { span, attr_name }); } } diff --git a/compiler/rustc_passes/src/diagnostics.rs b/compiler/rustc_passes/src/diagnostics.rs index 59b393fc8e68b..16a2cc4007318 100644 --- a/compiler/rustc_passes/src/diagnostics.rs +++ b/compiler/rustc_passes/src/diagnostics.rs @@ -73,16 +73,8 @@ pub(crate) struct DocAliasNotAnAlias { } #[derive(Diagnostic)] -#[diag("`#[doc({$attr_name} = \"...\")]` should be used on empty modules")] -pub(crate) struct DocKeywordAttributeEmptyMod { - #[primary_span] - pub span: Span, - pub attr_name: &'static str, -} - -#[derive(Diagnostic)] -#[diag("`#[doc({$attr_name} = \"...\")]` should be used on modules")] -pub(crate) struct DocKeywordAttributeNotMod { +#[diag("`#[doc({$attr_name} = \"...\")]` should be used on anonymous constants")] +pub(crate) struct DocKeywordAttributeNotAnonConst { #[primary_span] pub span: Span, pub attr_name: &'static str, diff --git a/library/core/src/attribute_docs.rs b/library/core/src/attribute_docs.rs index b30c449104ad5..584e1583c9bdb 100644 --- a/library/core/src/attribute_docs.rs +++ b/library/core/src/attribute_docs.rs @@ -82,7 +82,7 @@ /// /// [`unused_must_use`]: ../rustc/lints/listing/warn-by-default.html#unused-must-use /// [the `must_use` attribute]: ../reference/attributes/diagnostics.html#the-must_use-attribute -mod must_use_attribute {} +const _: () = (); #[doc(attribute = "allow")] // @@ -144,7 +144,7 @@ mod must_use_attribute {} /// [`forbid`]: ./attribute.forbid.html /// [`warn`]: ./attribute.warn.html /// [`deny`]: ./attribute.deny.html -mod allow_attribute {} +const _: () = (); #[doc(attribute = "cfg")] // @@ -192,7 +192,7 @@ mod allow_attribute {} /// [`cfg_attr`]: ../reference/conditional-compilation.html#the-cfg_attr-attribute /// [the `cfg` attribute]: ../reference/conditional-compilation.html#the-cfg-attribute /// [`if`]: ./keyword.if.html -mod cfg_attribute {} +const _: () = (); #[doc(attribute = "deny")] // @@ -240,7 +240,7 @@ mod cfg_attribute {} /// [`allow`]: ./attribute.allow.html /// [`warn`]: ./attribute.warn.html /// [`deny`]: ./attribute.deny.html -mod deny_attribute {} +const _: () = (); #[doc(attribute = "forbid")] // @@ -276,7 +276,7 @@ mod deny_attribute {} /// [the `forbid` attribute]: ../reference/attributes/diagnostics.html#lint-check-attributes /// [`allow`]: ./attribute.allow.html /// [`warn`]: ./attribute.warn.html -mod forbid_attribute {} +const _: () = (); #[doc(attribute = "deprecated")] // @@ -302,7 +302,7 @@ mod forbid_attribute {} /// For more information, see the Reference on [the `deprecated` attribute]. /// /// [the `deprecated` attribute]: ../reference/attributes/diagnostics.html#the-deprecated-attribute -mod deprecated_attribute {} +const _: () = (); #[doc(attribute = "warn")] // @@ -348,7 +348,7 @@ mod deprecated_attribute {} /// [`allow`]: ./attribute.allow.html /// [`deny`]: ./attribute.deny.html /// [`forbid`]: ./attribute.forbid.html -mod warn_attribute {} +const _: () = (); #[doc(attribute = "no_std")] // @@ -404,7 +404,7 @@ mod warn_attribute {} /// [`Option`]: option::Option /// [`Result`]: result::Result /// [the `no_std` attribute]: ../reference/names/preludes.html#the-no_std-attribute -mod no_std_attribute {} +const _: () = (); #[doc(attribute = "inline")] // @@ -444,7 +444,7 @@ mod no_std_attribute {} /// For more information, see the Reference on [the `inline` attribute]. /// /// [the `inline` attribute]: ../reference/attributes/codegen.html#the-inline-attribute -mod inline_attribute {} +const _: () = (); #[doc(attribute = "cold")] // @@ -474,7 +474,7 @@ mod inline_attribute {} /// For more information, see the Reference on [the `cold` attribute]. /// /// [the `cold` attribute]: ../reference/attributes/codegen.html#the-cold-attribute -mod cold_attribute {} +const _: () = (); #[doc(attribute = "track_caller")] // @@ -505,7 +505,7 @@ mod cold_attribute {} /// [`Location::caller`]: panic::Location::caller /// [`Option::unwrap`]: Option::unwrap /// [the `track_caller` attribute]: ../reference/attributes/codegen.html#the-track_caller-attribute -mod track_caller_attribute {} +const _: () = (); #[doc(attribute = "proc_macro")] // @@ -554,7 +554,7 @@ mod track_caller_attribute {} /// [`TokenStream`]: ../proc_macro/struct.TokenStream.html /// [function-like procedural macros]: ../reference/procedural-macros.html#the-proc_macro-attribute /// [`proc_macro`]: ../proc_macro/index.html -mod proc_macro_attribute {} +const _: () = (); #[doc(attribute = "link_section")] // @@ -580,7 +580,7 @@ mod proc_macro_attribute {} /// For more information, see the Reference on [the `link_section` attribute]. /// /// [the `link_section` attribute]: ../reference/abi.html#the-link_section-attribute -mod link_section_attribute {} +const _: () = (); #[doc(attribute = "non_exhaustive")] // @@ -632,4 +632,4 @@ mod link_section_attribute {} /// For more information, see the Reference on [the `non_exhaustive` attribute]. /// /// [the `non_exhaustive` attribute]: ../reference/attributes/type_system.html#the-non_exhaustive-attribute -mod non_exhaustive_attribute {} +const _: () = (); diff --git a/library/core/src/keyword_docs.rs b/library/core/src/keyword_docs.rs index 596765be5e2dd..3d914556fc65c 100644 --- a/library/core/src/keyword_docs.rs +++ b/library/core/src/keyword_docs.rs @@ -73,7 +73,7 @@ /// [`use`]: keyword.use.html /// [const-cast]: pointer::cast /// [mut-cast]: primitive.pointer.html#method.cast-1 -mod as_keyword {} +const _: () = (); #[doc(keyword = "break")] // @@ -171,7 +171,7 @@ mod as_keyword {} /// [Reference on "break expression"]: ../reference/expressions/loop-expr.html#break-expressions /// [Reference on "break and loop values"]: /// ../reference/expressions/loop-expr.html#break-and-loop-values -mod break_keyword {} +const _: () = (); #[doc(keyword = "const")] // @@ -248,7 +248,7 @@ mod break_keyword {} /// [Reference]: ../reference/items/constant-items.html /// [const-blocks]: ../reference/expressions/block-expr.html#const-blocks /// [const-eval]: ../reference/const_eval.html -mod const_keyword {} +const _: () = (); #[doc(keyword = "continue")] // @@ -288,7 +288,7 @@ mod const_keyword {} /// See [continue expressions] from the reference for more details. /// /// [continue expressions]: ../reference/expressions/loop-expr.html#continue-expressions -mod continue_keyword {} +const _: () = (); #[doc(keyword = "crate")] // @@ -325,7 +325,7 @@ mod continue_keyword {} /// module `foo`, from anywhere else in the same crate. /// /// [Reference]: ../reference/items/extern-crates.html -mod crate_keyword {} +const _: () = (); #[doc(keyword = "else")] // @@ -378,7 +378,7 @@ mod crate_keyword {} /// [`match`]: keyword.match.html /// [`false`]: keyword.false.html /// [`if`]: keyword.if.html -mod else_keyword {} +const _: () = (); #[doc(keyword = "enum")] // @@ -433,7 +433,7 @@ mod else_keyword {} /// [ADT]: https://en.wikipedia.org/wiki/Algebraic_data_type /// [Rust Book]: ../book/ch06-01-defining-an-enum.html /// [Reference]: ../reference/items/enumerations.html -mod enum_keyword {} +const _: () = (); #[doc(keyword = "extern")] // @@ -480,7 +480,7 @@ mod enum_keyword {} /// ../book/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code /// [Reference]: ../reference/items/external-blocks.html /// [`crate`]: keyword.crate.html -mod extern_keyword {} +const _: () = (); #[doc(keyword = "false")] // @@ -491,7 +491,7 @@ mod extern_keyword {} /// See the documentation for [`true`] for more information. /// /// [`true`]: keyword.true.html -mod false_keyword {} +const _: () = (); #[doc(keyword = "fn")] // @@ -558,7 +558,7 @@ mod false_keyword {} /// [`extern`]: keyword.extern.html /// [Rust book]: ../book/ch03-03-how-functions-work.html /// [Reference]: ../reference/items/functions.html -mod fn_keyword {} +const _: () = (); #[doc(keyword = "for")] // @@ -640,7 +640,7 @@ mod fn_keyword {} /// [Rust book]: /// ../book/ch03-05-control-flow.html#looping-through-a-collection-with-for /// [Reference]: ../reference/expressions/loop-expr.html#iterator-loops -mod for_keyword {} +const _: () = (); #[doc(keyword = "if")] // @@ -714,7 +714,7 @@ mod for_keyword {} /// /// [Rust book]: ../book/ch03-05-control-flow.html#if-expressions /// [Reference]: ../reference/expressions/if-expr.html -mod if_keyword {} +const _: () = (); #[doc(keyword = "impl")] // @@ -804,7 +804,7 @@ mod if_keyword {} /// [book1]: ../book/ch05-03-method-syntax.html /// [Reference]: ../reference/items/implementations.html /// [book2]: ../book/ch10-02-traits.html#returning-types-that-implement-traits -mod impl_keyword {} +const _: () = (); #[doc(keyword = "in")] // @@ -836,7 +836,7 @@ mod impl_keyword {} /// For more information, see the [Reference]. /// /// [Reference]: ../reference/visibility-and-privacy.html#pubin-path-pubcrate-pubsuper-and-pubself -mod in_keyword {} +const _: () = (); #[doc(keyword = "let")] // @@ -899,7 +899,7 @@ mod in_keyword {} /// [`if`]: keyword.if.html /// [book2]: ../book/ch18-01-all-the-places-for-patterns.html#let-statements /// [Reference]: ../reference/statements.html#let-statements -mod let_keyword {} +const _: () = (); #[doc(keyword = "loop")] // @@ -949,7 +949,7 @@ mod let_keyword {} /// [`for`]: keyword.for.html /// [`while`]: keyword.while.html /// [Reference]: ../reference/expressions/loop-expr.html -mod loop_keyword {} +const _: () = (); #[doc(keyword = "match")] // @@ -999,7 +999,7 @@ mod loop_keyword {} /// For more information on `match` and matching in general, see the [Reference]. /// /// [Reference]: ../reference/expressions/match-expr.html -mod match_keyword {} +const _: () = (); #[doc(keyword = "mod")] // @@ -1027,7 +1027,7 @@ mod match_keyword {} /// [`pub`]: keyword.pub.html /// [`struct`]: keyword.struct.html /// [modules]: ../reference/items/modules.html -mod mod_keyword {} +const _: () = (); #[doc(keyword = "move")] // @@ -1085,7 +1085,7 @@ mod mod_keyword {} /// /// [closure]: ../book/ch13-01-closures.html /// [threads]: ../book/ch16-01-threads.html#using-move-closures-with-threads -mod move_keyword {} +const _: () = (); #[doc(keyword = "mut")] // @@ -1143,7 +1143,7 @@ mod move_keyword {} /// More information on mutable references and pointers can be found in the [Reference]. /// /// [Reference]: ../reference/types/pointer.html#mutable-references-mut -mod mut_keyword {} +const _: () = (); #[doc(keyword = "pub")] // @@ -1158,7 +1158,7 @@ mod mut_keyword {} /// /// [reference]:../reference/visibility-and-privacy.html?highlight=pub#visibility-and-privacy /// [Rust by Example]:../rust-by-example/mod/visibility.html -mod pub_keyword {} +const _: () = (); #[doc(keyword = "ref")] // @@ -1208,7 +1208,7 @@ mod pub_keyword {} /// /// [`match`]: keyword.match.html /// [Reference]: ../reference/patterns.html#identifier-patterns -mod ref_keyword {} +const _: () = (); #[doc(keyword = "return")] // @@ -1272,7 +1272,7 @@ mod ref_keyword {} /// /// [closures]: ../book/ch13-01-closures.html /// [`async`]: ../std/keyword.async.html -mod return_keyword {} +const _: () = (); #[doc(keyword = "become")] // @@ -1376,7 +1376,7 @@ mod return_keyword {} /// let program = &[Inst::Inc, Inst::Inc, Inst::Dec, Inst::Inc]; /// assert_eq!(dispatch(program, 0), 2); /// ``` -mod become_keyword {} +const _: () = (); #[doc(keyword = "self")] // @@ -1469,7 +1469,7 @@ mod become_keyword {} /// /// [`use`]: keyword.use.html /// [Reference]: ../reference/items/associated-items.html#methods -mod self_keyword {} +const _: () = (); // FIXME: Once rustdoc can handle URL conflicts on case insensitive file systems, we can replace // these two lines with `#[doc(keyword = "Self")]` and update `is_doc_keyword` in @@ -1540,7 +1540,7 @@ mod self_keyword {} /// /// [`impl`]: keyword.impl.html /// [`trait`]: keyword.trait.html -mod self_upper_keyword {} +const _: () = (); #[doc(keyword = "static")] // @@ -1626,7 +1626,7 @@ mod self_upper_keyword {} /// [`RefCell`]: cell::RefCell /// [atomic]: sync::atomic /// [Reference]: ../reference/items/static-items.html -mod static_keyword {} +const _: () = (); #[doc(keyword = "struct")] // @@ -1734,7 +1734,7 @@ mod static_keyword {} /// [`PhantomData`]: marker::PhantomData /// [book]: ../book/ch05-01-defining-structs.html /// [reference]: ../reference/items/structs.html -mod struct_keyword {} +const _: () = (); #[doc(keyword = "super")] // @@ -1760,7 +1760,7 @@ mod struct_keyword {} /// /// [module]: ../reference/items/modules.html /// [Reference]: ../reference/paths.html#super -mod super_keyword {} +const _: () = (); #[doc(keyword = "trait")] // @@ -1945,7 +1945,7 @@ mod super_keyword {} /// [`unsafe`]: keyword.unsafe.html /// [Ref-Traits]: ../reference/items/traits.html /// [Ref-Trait-Objects]: ../reference/types/trait-object.html -mod trait_keyword {} +const _: () = (); #[doc(keyword = "true")] // @@ -1972,7 +1972,7 @@ mod trait_keyword {} /// [`while`]: keyword.while.html /// [`match`]: ../reference/expressions/match-expr.html#match-guards /// [`false`]: keyword.false.html -mod true_keyword {} +const _: () = (); #[doc(keyword = "type")] // @@ -2024,7 +2024,7 @@ mod true_keyword {} /// [`trait`]: keyword.trait.html /// [associated type]: ../reference/items/associated-items.html#associated-types /// [alias]: ../reference/items/type-aliases.html -mod type_keyword {} +const _: () = (); #[doc(keyword = "unsafe")] // @@ -2310,7 +2310,7 @@ mod type_keyword {} /// [soundness]: https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#soundness-of-code--of-a-library /// [Reference]: ../reference/unsafety.html /// [discussion on Rust Internals]: https://internals.rust-lang.org/t/what-does-unsafe-mean/6696 -mod unsafe_keyword {} +const _: () = (); #[doc(keyword = "use")] // @@ -2408,7 +2408,7 @@ mod unsafe_keyword {} /// [`super`]: keyword.super.html /// [ref-use-decls]: ../reference/items/use-declarations.html /// [ref-impl-trait]: ../reference/types/impl-trait.html -mod use_keyword {} +const _: () = (); #[doc(keyword = "where")] // @@ -2508,7 +2508,7 @@ mod use_keyword {} /// ``` /// /// [RFC]: https://github.com/rust-lang/rfcs/blob/master/text/0135-where.md -mod where_keyword {} +const _: () = (); #[doc(keyword = "while")] // @@ -2566,7 +2566,7 @@ mod where_keyword {} /// [`for`]: keyword.for.html /// [`loop`]: keyword.loop.html /// [reference]: ../reference/expressions/loop-expr.html#predicate-loops -mod while_keyword {} +const _: () = (); // 2018 Edition keywords @@ -2628,7 +2628,7 @@ mod while_keyword {} /// [never type]: ../reference/types/never.html /// [`Result`]: result::Result /// [async book blocks]: https://rust-lang.github.io/async-book/part-guide/more-async-await.html#async-blocks -mod async_keyword {} +const _: () = (); #[doc(keyword = "await")] // @@ -2648,7 +2648,7 @@ mod async_keyword {} /// [`Future`]: future::Future /// [async book]: https://rust-lang.github.io/async-book/ /// [`async`]: ../std/keyword.async.html -mod await_keyword {} +const _: () = (); #[doc(keyword = "dyn")] // @@ -2684,7 +2684,7 @@ mod await_keyword {} /// [ref-dyn-compat]: ../reference/items/traits.html#dyn-compatibility /// [erased]: https://en.wikipedia.org/wiki/Type_erasure /// [^1]: Formerly known as *object safe*. -mod dyn_keyword {} +const _: () = (); #[doc(keyword = "union")] // @@ -2758,4 +2758,4 @@ mod dyn_keyword {} /// /// [`struct`]: keyword.struct.html /// [union]: ../reference/items/unions.html -mod union_keyword {} +const _: () = (); diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index d80c55538055b..3e1596689e9d1 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -58,7 +58,7 @@ /// assert_eq!(false as i32, 0); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -mod prim_bool {} +const _: () = (); #[rustc_doc_primitive = "never"] #[doc(alias = "!")] @@ -312,7 +312,7 @@ mod prim_bool {} /// [2024 edition]: /// #[unstable(feature = "never_type", issue = "35121")] -mod prim_never {} +const _: () = (); // Required to make auto trait impls render. // See src/librustdoc/passes/collect_trait_impls.rs:collect_trait_impls @@ -448,7 +448,7 @@ impl ! {} /// assert_eq!(32, size_of_val(&v[..])); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -mod prim_char {} +const _: () = (); #[rustc_doc_primitive = "unit"] #[doc(alias = "(")] @@ -489,7 +489,7 @@ mod prim_char {} /// ``` /// #[stable(feature = "rust1", since = "1.0.0")] -mod prim_unit {} +const _: () = (); // Required to make auto trait impls render. // See src/librustdoc/passes/collect_trait_impls.rs:collect_trait_impls @@ -616,7 +616,7 @@ impl () {} /// [`write`]: ptr::write /// [valid]: ptr#safety #[stable(feature = "rust1", since = "1.0.0")] -mod prim_pointer {} +const _: () = (); #[rustc_doc_primitive = "array"] #[doc(alias = "[]")] @@ -828,7 +828,7 @@ mod prim_pointer {} /// [slice pattern]: ../reference/patterns.html#slice-patterns /// [`From`]: convert::From #[stable(feature = "rust1", since = "1.0.0")] -mod prim_array {} +const _: () = (); #[rustc_doc_primitive = "slice"] #[doc(alias = "[")] @@ -942,7 +942,7 @@ mod prim_array {} /// [`.chunks`]: slice::chunks /// [`.windows`]: slice::windows #[stable(feature = "rust1", since = "1.0.0")] -mod prim_slice {} +const _: () = (); #[rustc_doc_primitive = "str"] /// String slices. @@ -1015,7 +1015,7 @@ mod prim_slice {} /// called on a string slice may assume that it is valid UTF-8, which means that a non-UTF-8 string /// slice can lead to undefined behavior down the road. #[stable(feature = "rust1", since = "1.0.0")] -mod prim_str {} +const _: () = (); #[rustc_doc_primitive = "tuple"] #[doc(alias = "(")] @@ -1142,7 +1142,7 @@ mod prim_str {} /// ``` /// #[stable(feature = "rust1", since = "1.0.0")] -mod prim_tuple {} +const _: () = (); // Required to make auto trait impls render. // See src/librustdoc/passes/collect_trait_impls.rs:collect_trait_impls @@ -1167,7 +1167,7 @@ impl (T,) {} /// /// [wikipedia]: https://en.wikipedia.org/wiki/Half-precision_floating-point_format #[unstable(feature = "f16", issue = "116909")] -mod prim_f16 {} +const _: () = (); #[rustc_doc_primitive = "f32"] #[doc(alias = "single")] @@ -1380,7 +1380,7 @@ mod prim_f16 {} /// # } /// ``` #[stable(feature = "rust1", since = "1.0.0")] -mod prim_f32 {} +const _: () = (); #[rustc_doc_primitive = "f64"] #[doc(alias = "double")] @@ -1394,7 +1394,7 @@ mod prim_f32 {} /// /// [wikipedia]: https://en.wikipedia.org/wiki/Double-precision_floating-point_format #[stable(feature = "rust1", since = "1.0.0")] -mod prim_f64 {} +const _: () = (); #[rustc_doc_primitive = "f128"] #[doc(alias = "quad")] @@ -1417,31 +1417,31 @@ mod prim_f64 {} /// /// [wikipedia]: https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format #[unstable(feature = "f128", issue = "116909")] -mod prim_f128 {} +const _: () = (); #[rustc_doc_primitive = "i8"] // /// The 8-bit signed integer type. #[stable(feature = "rust1", since = "1.0.0")] -mod prim_i8 {} +const _: () = (); #[rustc_doc_primitive = "i16"] // /// The 16-bit signed integer type. #[stable(feature = "rust1", since = "1.0.0")] -mod prim_i16 {} +const _: () = (); #[rustc_doc_primitive = "i32"] // /// The 32-bit signed integer type. #[stable(feature = "rust1", since = "1.0.0")] -mod prim_i32 {} +const _: () = (); #[rustc_doc_primitive = "i64"] // /// The 64-bit signed integer type. #[stable(feature = "rust1", since = "1.0.0")] -mod prim_i64 {} +const _: () = (); #[rustc_doc_primitive = "i128"] // @@ -1459,31 +1459,31 @@ mod prim_i64 {} /// do not use the same alignment. `i128` is intended to always match `__int128` and does not /// attempt to match `_BitInt(128)` on platforms without `__int128`. #[stable(feature = "i128", since = "1.26.0")] -mod prim_i128 {} +const _: () = (); #[rustc_doc_primitive = "u8"] // /// The 8-bit unsigned integer type. #[stable(feature = "rust1", since = "1.0.0")] -mod prim_u8 {} +const _: () = (); #[rustc_doc_primitive = "u16"] // /// The 16-bit unsigned integer type. #[stable(feature = "rust1", since = "1.0.0")] -mod prim_u16 {} +const _: () = (); #[rustc_doc_primitive = "u32"] // /// The 32-bit unsigned integer type. #[stable(feature = "rust1", since = "1.0.0")] -mod prim_u32 {} +const _: () = (); #[rustc_doc_primitive = "u64"] // /// The 64-bit unsigned integer type. #[stable(feature = "rust1", since = "1.0.0")] -mod prim_u64 {} +const _: () = (); #[rustc_doc_primitive = "u128"] // @@ -1491,7 +1491,7 @@ mod prim_u64 {} /// /// Please see [the documentation for `i128`](prim@i128) for information on ABI compatibility. #[stable(feature = "i128", since = "1.26.0")] -mod prim_u128 {} +const _: () = (); #[rustc_doc_primitive = "isize"] // @@ -1501,7 +1501,7 @@ mod prim_u128 {} /// location in memory. For example, on a 32 bit target, this is 4 bytes /// and on a 64 bit target, this is 8 bytes. #[stable(feature = "rust1", since = "1.0.0")] -mod prim_isize {} +const _: () = (); #[rustc_doc_primitive = "usize"] // @@ -1511,7 +1511,7 @@ mod prim_isize {} /// location in memory. For example, on a 32 bit target, this is 4 bytes /// and on a 64 bit target, this is 8 bytes. #[stable(feature = "rust1", since = "1.0.0")] -mod prim_usize {} +const _: () = (); #[rustc_doc_primitive = "reference"] #[doc(alias = "&")] @@ -1672,7 +1672,7 @@ mod prim_usize {} /// /// [allocation]: ptr#allocation #[stable(feature = "rust1", since = "1.0.0")] -mod prim_ref {} +const _: () = (); #[rustc_doc_primitive = "fn"] // @@ -1947,7 +1947,7 @@ mod prim_ref {} /// In addition, all *safe* function pointers implement [`Fn`], [`FnMut`], and [`FnOnce`], because /// these traits are specially known to the compiler. #[stable(feature = "rust1", since = "1.0.0")] -mod prim_fn {} +const _: () = (); // Required to make auto trait impls render. // See src/librustdoc/passes/collect_trait_impls.rs:collect_trait_impls diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index ec03dba854578..3b5bf4ae080dc 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -130,7 +130,7 @@ To do so, the `#[doc(keyword = "...")]` attribute is used. Example: /// Some documentation about the keyword. #[doc(keyword = "break")] -mod empty_mod {} +const _: () = (); ``` ### Document builtin attributes @@ -147,7 +147,7 @@ To do so, the `#[doc(attribute = "...")]` attribute is used. Example: /// Some documentation about the attribute. #[doc(attribute = "repr")] -mod empty_mod {} +const _: () = (); ``` ### Use the Rust logo as the crate logo diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 201ae46fdeb28..a4388aba0bea9 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -236,7 +236,7 @@ impl ExternalCrate { .unwrap_or(Unknown) // Well, at least we tried. } - fn mapped_root_modules( + fn mapped_root_anon_consts( &self, tcx: TyCtxt<'_>, f: impl Fn(DefId, TyCtxt<'_>) -> Option<(DefId, T)>, @@ -248,7 +248,7 @@ impl ExternalCrate { tcx.hir_root_module() .item_ids .iter() - .filter(move |&&id| matches!(tcx.hir_item(id).kind, hir::ItemKind::Mod(..))) + .filter(move |&&id| matches!(tcx.hir_item(id).kind, hir::ItemKind::Const(..))) .filter_map(move |&id| f(id.owner_id.into(), tcx)), ) } else { @@ -256,7 +256,11 @@ impl ExternalCrate { tcx.module_children(root) .iter() .filter_map(|item| { - if let Res::Def(DefKind::Mod, did) = item.res { Some(did) } else { None } + if let Res::Def(DefKind::Const { is_type_const: false }, did) = item.res { + Some(did) + } else { + None + } }) .filter_map(move |did| f(did, tcx)), ) @@ -281,7 +285,7 @@ impl ExternalCrate { let as_target = move |did: DefId, tcx: TyCtxt<'_>| -> Option<(DefId, Symbol)> { find_attr!(tcx, did, Doc(d) => callback(d)).flatten().map(|value| (did, value)) }; - self.mapped_root_modules(tcx, as_target) + self.mapped_root_anon_consts(tcx, as_target) } pub(crate) fn primitives( @@ -316,7 +320,7 @@ impl ExternalCrate { Some((def_id, prim)) } - self.mapped_root_modules(tcx, as_primitive) + self.mapped_root_anon_consts(tcx, as_primitive) } } @@ -984,10 +988,10 @@ pub(crate) enum ItemKind { AssocTypeItem(Box, Vec), /// An item that has been stripped by a rustdoc pass StrippedItem(Box), - /// This item represents a module with a `#[doc(keyword = "...")]` attribute which is used + /// This item represents an anonymous constant with a `#[doc(keyword = "...")]` attribute which is used /// to generate documentation for Rust keywords. KeywordItem, - /// This item represents a module with a `#[doc(attribute = "...")]` attribute which is used + /// This item represents an anonymous constant with a `#[doc(attribute = "...")]` attribute which is used /// to generate documentation for Rust builtin attributes. AttributeItem, } diff --git a/tests/run-make/rustdoc/search-load-itemtype/foo.rs b/tests/run-make/rustdoc/search-load-itemtype/foo.rs index 93b372d10cbf9..ad580b2505cac 100644 --- a/tests/run-make/rustdoc/search-load-itemtype/foo.rs +++ b/tests/run-make/rustdoc/search-load-itemtype/foo.rs @@ -4,15 +4,13 @@ //@ has foo/keyword.while.html //@ hasraw search.index/name/*.js while -//@ !hasraw search.index/name/*.js w_keyword #[doc(keyword = "while")] -mod w_keyword {} +const _: () = (); //@ has foo/primitive.u32.html //@ hasraw search.index/name/*.js u32 -//@ !hasraw search.index/name/*.js u_primitive #[rustc_doc_primitive = "u32"] -mod u_primitive {} +const _: () = (); //@ has foo/x_mod/index.html //@ hasraw search.index/name/*.js x_mod @@ -114,6 +112,5 @@ pub trait ATraitAlias = ATrait; //@ has foo/attribute.doc.html //@ hasraw search.index/name/*.js doc -//@ !hasraw search.index/name/*.js aa_mod #[doc(attribute = "doc")] -mod aa_mod {} +const _: () = (); diff --git a/tests/rustdoc-gui/src/test_docs/lib.rs b/tests/rustdoc-gui/src/test_docs/lib.rs index bfdbe65f147f4..6a54690a3eb37 100644 --- a/tests/rustdoc-gui/src/test_docs/lib.rs +++ b/tests/rustdoc-gui/src/test_docs/lib.rs @@ -178,11 +178,11 @@ pub enum AnEnum { #[doc(keyword = "for")] /// Some keyword. -pub mod keyword {} +const _: () = (); #[doc(attribute = "forbid")] /// Some attribute. -pub mod repr {} +const _: () = (); /// Just some type alias. pub type SomeType = u32; diff --git a/tests/rustdoc-html/auto/auto-impl-primitive.rs b/tests/rustdoc-html/auto/auto-impl-primitive.rs index 3dab02506ca61..b9c9edc0c6bbc 100644 --- a/tests/rustdoc-html/auto/auto-impl-primitive.rs +++ b/tests/rustdoc-html/auto/auto-impl-primitive.rs @@ -7,4 +7,4 @@ pub use std::fs::File; //@ has 'foo/primitive.i16.html' '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementation' #[rustc_doc_primitive = "i16"] /// I love poneys! -mod prim {} +const _: () = (); diff --git a/tests/rustdoc-html/doc-attribute.rs b/tests/rustdoc-html/doc-attribute.rs index 47f2a7fccf6fe..289395c220ffd 100644 --- a/tests/rustdoc-html/doc-attribute.rs +++ b/tests/rustdoc-html/doc-attribute.rs @@ -11,14 +11,12 @@ //@ has foo/attribute.no_mangle.html '//h1' 'Attribute no_mangle' //@ has foo/attribute.no_mangle.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'this is a test!' //@ has foo/index.html '//a/@href' '../foo/index.html' -//@ !has foo/foo/index.html -//@ !has-dir foo/foo //@ !has foo/index.html '//span' '🔒' #[doc(attribute = "no_mangle")] /// this is a test! -mod foo{} +const _: () = (); //@ has foo/attribute.repr.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'hello' #[doc(attribute = "repr")] /// hello -mod bar {} +const _: () = (); diff --git a/tests/rustdoc-html/doc-on-keyword.rs b/tests/rustdoc-html/doc-on-keyword.rs index 0c62eda60a6b3..d622624cdaa21 100644 --- a/tests/rustdoc-html/doc-on-keyword.rs +++ b/tests/rustdoc-html/doc-on-keyword.rs @@ -10,4 +10,4 @@ #[doc(keyword = "trait")] // /// [`Send`] and [Sync] -mod bar {} +const _: () = (); diff --git a/tests/rustdoc-html/intra-doc/auxiliary/my-core.rs b/tests/rustdoc-html/intra-doc/auxiliary/my-core.rs index a33b0582b31a8..4e6686023ba9e 100644 --- a/tests/rustdoc-html/intra-doc/auxiliary/my-core.rs +++ b/tests/rustdoc-html/intra-doc/auxiliary/my-core.rs @@ -5,7 +5,7 @@ #[rustc_doc_primitive = "char"] /// Some char docs -mod char {} +const _: () = (); impl char { pub fn len_utf8(self) -> usize { diff --git a/tests/rustdoc-html/intra-doc/prim-methods-local.rs b/tests/rustdoc-html/intra-doc/prim-methods-local.rs index f6aa1ed215654..1a9ae0ed84bdf 100644 --- a/tests/rustdoc-html/intra-doc/prim-methods-local.rs +++ b/tests/rustdoc-html/intra-doc/prim-methods-local.rs @@ -11,7 +11,7 @@ //! A [prim@`char`] and its [`char::len_utf8`]. #[rustc_doc_primitive = "char"] -mod char {} +const _: () = (); impl char { pub fn len_utf8(self) -> usize { diff --git a/tests/rustdoc-html/intra-doc/prim-self.rs b/tests/rustdoc-html/intra-doc/prim-self.rs index 21368fab99358..7b5911abe3d1d 100644 --- a/tests/rustdoc-html/intra-doc/prim-self.rs +++ b/tests/rustdoc-html/intra-doc/prim-self.rs @@ -27,7 +27,7 @@ impl usize { #[rustc_doc_primitive = "usize"] /// This has some docs. -mod usize {} +const _: () = (); /// [S::f] /// [Self::f] diff --git a/tests/rustdoc-html/keyword.rs b/tests/rustdoc-html/keyword.rs index 8f86c8ffd380b..baa81725e6e58 100644 --- a/tests/rustdoc-html/keyword.rs +++ b/tests/rustdoc-html/keyword.rs @@ -9,14 +9,12 @@ //@ has foo/keyword.match.html '//h1' 'Keyword match' //@ has foo/keyword.match.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'this is a test!' //@ has foo/index.html '//a/@href' '../foo/index.html' -//@ !has foo/foo/index.html -//@ !has-dir foo/foo //@ !has foo/index.html '//span' '🔒' #[doc(keyword = "match")] /// this is a test! -mod foo{} +const _: () = (); //@ has foo/keyword.break.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'hello' #[doc(keyword = "break")] /// hello -mod bar {} +const _: () = (); diff --git a/tests/rustdoc-html/notable-trait/doc-notable_trait-mut_t_is_not_an_iterator.rs b/tests/rustdoc-html/notable-trait/doc-notable_trait-mut_t_is_not_an_iterator.rs index 043d787396d3d..c2935c10311cb 100644 --- a/tests/rustdoc-html/notable-trait/doc-notable_trait-mut_t_is_not_an_iterator.rs +++ b/tests/rustdoc-html/notable-trait/doc-notable_trait-mut_t_is_not_an_iterator.rs @@ -14,7 +14,7 @@ /// /// We need to put this in here, because notable traits /// that are implemented on foreign types don't show up. -mod reference {} +const _: () = (); //@ has doc_notable_trait_mut_t_is_not_an_iterator/fn.fn_no_matches.html //@ !has - '//code[@class="content"]' 'Iterator' diff --git a/tests/rustdoc-html/notable-trait/doc-notable_trait-mut_t_is_not_ref_t.rs b/tests/rustdoc-html/notable-trait/doc-notable_trait-mut_t_is_not_ref_t.rs index 6a9fbb9ac0bdd..50767e6a4da07 100644 --- a/tests/rustdoc-html/notable-trait/doc-notable_trait-mut_t_is_not_ref_t.rs +++ b/tests/rustdoc-html/notable-trait/doc-notable_trait-mut_t_is_not_ref_t.rs @@ -12,7 +12,7 @@ /// /// We need to put this in here, because notable traits /// that are implemented on foreign types don't show up. -mod reference {} +const _: () = (); //@ has doc_notable_trait_mut_t_is_not_ref_t/fn.fn_no_matches.html //@ !has - '//code[@class="content"]' "impl<'_, I> Iterator for &'_ mut I" diff --git a/tests/rustdoc-html/primitive/auxiliary/issue-15318.rs b/tests/rustdoc-html/primitive/auxiliary/issue-15318.rs index d3dc89113fc53..95a59a137b8c7 100644 --- a/tests/rustdoc-html/primitive/auxiliary/issue-15318.rs +++ b/tests/rustdoc-html/primitive/auxiliary/issue-15318.rs @@ -14,4 +14,4 @@ fn bar(_: &core::panic::PanicInfo) -> ! { loop {} } /// dox #[rustc_doc_primitive = "pointer"] -pub mod ptr {} +const _: () = (); diff --git a/tests/rustdoc-html/primitive/auxiliary/primitive-doc.rs b/tests/rustdoc-html/primitive/auxiliary/primitive-doc.rs index 859716c38e462..f985cee8c6366 100644 --- a/tests/rustdoc-html/primitive/auxiliary/primitive-doc.rs +++ b/tests/rustdoc-html/primitive/auxiliary/primitive-doc.rs @@ -2,10 +2,18 @@ //@ edition: 2018 #![feature(rustc_attrs)] -#![feature(no_core)] +#![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} + #[rustc_doc_primitive = "usize"] /// This is the built-in type `usize`. -mod usize { -} +const _: () = (); diff --git a/tests/rustdoc-html/primitive/cross-crate-primitive-doc.rs b/tests/rustdoc-html/primitive/cross-crate-primitive-doc.rs index 3c159d57f13f1..ca33dedcbaec7 100644 --- a/tests/rustdoc-html/primitive/cross-crate-primitive-doc.rs +++ b/tests/rustdoc-html/primitive/cross-crate-primitive-doc.rs @@ -2,18 +2,9 @@ //@ compile-flags: --extern-html-root-url=primitive_doc=../ -Z unstable-options //@ only-linux -#![feature(no_core, lang_items)] +#![feature(no_core)] #![no_core] -#[lang = "pointee_sized"] -pub trait PointeeSized {} - -#[lang = "meta_sized"] -pub trait MetaSized: PointeeSized {} - -#[lang = "sized"] -pub trait Sized: MetaSized {} - extern crate primitive_doc; //@ has 'cross_crate_primitive_doc/fn.foo.html' '//a[@href="../primitive_doc/primitive.usize.html"]' 'usize' diff --git a/tests/rustdoc-html/primitive/primitive-generic-impl.rs b/tests/rustdoc-html/primitive/primitive-generic-impl.rs index b342e977cf077..3363d1c966ef5 100644 --- a/tests/rustdoc-html/primitive/primitive-generic-impl.rs +++ b/tests/rustdoc-html/primitive/primitive-generic-impl.rs @@ -5,4 +5,4 @@ #[rustc_doc_primitive = "i32"] /// Some useless docs, wouhou! -mod i32 {} +const _: () = (); diff --git a/tests/rustdoc-html/primitive/primitive-raw-pointer-dox-15318-3.rs b/tests/rustdoc-html/primitive/primitive-raw-pointer-dox-15318-3.rs index 5520abf29250c..4f8b186b92a9c 100644 --- a/tests/rustdoc-html/primitive/primitive-raw-pointer-dox-15318-3.rs +++ b/tests/rustdoc-html/primitive/primitive-raw-pointer-dox-15318-3.rs @@ -6,4 +6,4 @@ /// dox #[rustc_doc_primitive = "pointer"] -pub mod ptr {} +const _: () = (); diff --git a/tests/rustdoc-html/primitive/primitive-raw-pointer-link-no-inlined-15318-2.rs b/tests/rustdoc-html/primitive/primitive-raw-pointer-link-no-inlined-15318-2.rs index 16b007e8bbda5..0629e62e6ade3 100644 --- a/tests/rustdoc-html/primitive/primitive-raw-pointer-link-no-inlined-15318-2.rs +++ b/tests/rustdoc-html/primitive/primitive-raw-pointer-link-no-inlined-15318-2.rs @@ -7,8 +7,6 @@ extern crate issue_15318; -pub use issue_15318::ptr; - //@ !has issue_15318_2/fn.bar.html \ // '//*[@href="primitive.pointer.html"]' \ // '*mut T' diff --git a/tests/rustdoc-html/primitive/primitive-reference.rs b/tests/rustdoc-html/primitive/primitive-reference.rs index bd6b2a32f754f..699585f828366 100644 --- a/tests/rustdoc-html/primitive/primitive-reference.rs +++ b/tests/rustdoc-html/primitive/primitive-reference.rs @@ -17,7 +17,7 @@ // 'impl Foo<&A> for &B' #[rustc_doc_primitive = "reference"] /// this is a test! -mod reference {} +const _: () = (); pub struct Bar; diff --git a/tests/rustdoc-html/primitive/primitive-slice-auto-trait.rs b/tests/rustdoc-html/primitive/primitive-slice-auto-trait.rs index 647c1cca94810..ce5c2319b09d4 100644 --- a/tests/rustdoc-html/primitive/primitive-slice-auto-trait.rs +++ b/tests/rustdoc-html/primitive/primitive-slice-auto-trait.rs @@ -11,4 +11,4 @@ //@ has - '//div[@id="synthetic-implementations-list"]//h3' 'impl Sync for [T]where T: Sync' #[rustc_doc_primitive = "slice"] /// this is a test! -mod slice_prim {} +const _: () = (); diff --git a/tests/rustdoc-html/primitive/primitive-tuple-auto-trait.rs b/tests/rustdoc-html/primitive/primitive-tuple-auto-trait.rs index 51300bd6b2fc6..74fe6d21eb41f 100644 --- a/tests/rustdoc-html/primitive/primitive-tuple-auto-trait.rs +++ b/tests/rustdoc-html/primitive/primitive-tuple-auto-trait.rs @@ -19,4 +19,4 @@ /// This header is hard-coded in the HTML format linking for `#[doc(fake_variadics)]`. /// To make sure it gets linked correctly, we need to make sure the hardcoded anchor /// in the code matches what rustdoc generates for the header. -mod tuple_prim {} +const _: () = (); diff --git a/tests/rustdoc-html/primitive/primitive-unit-auto-trait.rs b/tests/rustdoc-html/primitive/primitive-unit-auto-trait.rs index 7dada1f9832e6..8c80a450ae130 100644 --- a/tests/rustdoc-html/primitive/primitive-unit-auto-trait.rs +++ b/tests/rustdoc-html/primitive/primitive-unit-auto-trait.rs @@ -11,4 +11,4 @@ //@ has - '//div[@id="synthetic-implementations-list"]//h3' 'impl Sync for ()' #[rustc_doc_primitive = "unit"] /// this is a test! -mod unit_prim {} +const _: () = (); diff --git a/tests/rustdoc-html/primitive/primitive.rs b/tests/rustdoc-html/primitive/primitive.rs index b54c3dd1cd613..aef0dc15cd401 100644 --- a/tests/rustdoc-html/primitive/primitive.rs +++ b/tests/rustdoc-html/primitive/primitive.rs @@ -15,19 +15,19 @@ //@ !has foo/index.html '//span' '🔒' #[rustc_doc_primitive = "i32"] /// this is a test! -mod i32 {} +const _: () = (); //@ has foo/primitive.bool.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'hello' #[rustc_doc_primitive = "bool"] /// hello -mod bool {} +const _: () = (); //@ has foo/primitive.f16.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'hello' #[rustc_doc_primitive = "f16"] /// hello -mod f16 {} +const _: () = (); //@ has foo/primitive.f128.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'hello' #[rustc_doc_primitive = "f128"] /// hello -mod f128 {} +const _: () = (); diff --git a/tests/rustdoc-html/primitive/search-index-primitive-inherent-method-23511.rs b/tests/rustdoc-html/primitive/search-index-primitive-inherent-method-23511.rs index ea828e08d82cc..b5022f1b5cf81 100644 --- a/tests/rustdoc-html/primitive/search-index-primitive-inherent-method-23511.rs +++ b/tests/rustdoc-html/primitive/search-index-primitive-inherent-method-23511.rs @@ -5,12 +5,11 @@ // https://github.com/rust-lang/rust/issues/23511 #![crate_name="issue_23511"] -pub mod str { - #![rustc_doc_primitive = "str"] +#[rustc_doc_primitive = "str"] +const _: () = (); - impl str { - //@ hasraw search.index/name/*.js foo - #[rustc_allow_incoherent_impl] - pub fn foo(&self) {} - } +impl str { + //@ hasraw search.index/name/*.js foo + #[rustc_allow_incoherent_impl] + pub fn foo(&self) {} } diff --git a/tests/rustdoc-html/sidebar/sidebar-all-page.rs b/tests/rustdoc-html/sidebar/sidebar-all-page.rs index 1f97a41404867..609fb525e649c 100644 --- a/tests/rustdoc-html/sidebar/sidebar-all-page.rs +++ b/tests/rustdoc-html/sidebar/sidebar-all-page.rs @@ -31,4 +31,4 @@ pub type Type = u8; pub const FOO: u8 = 0; pub static BAR: u8 = 0; #[rustc_doc_primitive = "u8"] -mod u8 {} +const _: () = (); diff --git a/tests/rustdoc-html/source-code-pages/check-source-code-urls-to-def.rs b/tests/rustdoc-html/source-code-pages/check-source-code-urls-to-def.rs index a7b944fa2f6fc..9036961358787 100644 --- a/tests/rustdoc-html/source-code-pages/check-source-code-urls-to-def.rs +++ b/tests/rustdoc-html/source-code-pages/check-source-code-urls-to-def.rs @@ -68,4 +68,4 @@ pub fn foo4() { //@ has - '//pre[@class="rust"]//a[@href="../../foo/primitive.bool.html"]' 'bool' #[rustc_doc_primitive = "bool"] -mod whatever {} +const _: () = (); diff --git a/tests/rustdoc-html/stability.rs b/tests/rustdoc-html/stability.rs index 22cd4b9cd5952..4870c68dfe5e6 100644 --- a/tests/rustdoc-html/stability.rs +++ b/tests/rustdoc-html/stability.rs @@ -160,7 +160,7 @@ pub trait UnstableTraitWithStableMethod { // /// `i32` is always stable in 1.0, even if you look at it from core. #[stable(feature = "rust1", since = "1.0.0")] -mod prim_i32 {} +const _: () = (); //@ has stability/keyword.if.html \ // '//div[@class="main-heading"]//span[@class="since"]' '1.0.0' @@ -168,4 +168,4 @@ mod prim_i32 {} // /// We currently don't document stability for keywords, but let's test it anyway. #[stable(feature = "rust1", since = "1.0.0")] -mod if_keyword {} +const _: () = (); diff --git a/tests/rustdoc-html/tab_title.rs b/tests/rustdoc-html/tab_title.rs index 59914065c9121..4056da412d4ae 100644 --- a/tests/rustdoc-html/tab_title.rs +++ b/tests/rustdoc-html/tab_title.rs @@ -36,10 +36,10 @@ pub mod blah { //@ has foo/keyword.continue.html '//head/title' 'continue - Rust' #[doc(keyword = "continue")] -mod continue_keyword {} +const _: () = (); //@ has foo/primitive.u8.html '//head/title' 'u8 - Rust' //@ !has - '//head/title' 'foo' #[rustc_doc_primitive = "u8"] /// `u8` docs -mod u8 {} +const _: () = (); diff --git a/tests/rustdoc-html/titles.rs b/tests/rustdoc-html/titles.rs index 922068adc5927..23915b05c2709 100644 --- a/tests/rustdoc-html/titles.rs +++ b/tests/rustdoc-html/titles.rs @@ -52,7 +52,7 @@ macro_rules! foo_macro { //@ matches 'foo/primitive.bool.html' '//h1' 'Primitive Type bool' //@ count - '//*[@class="rustdoc-breadcrumbs"]' 0 #[rustc_doc_primitive = "bool"] -mod bool {} +const _: () = (); //@ matches 'foo/static.FOO_STATIC.html' '//h1' 'Static FOO_STATIC' //@ matches - '//*[@class="rustdoc-breadcrumbs"]' 'foo' diff --git a/tests/rustdoc-html/type-alias/primitive-local-link-121106.rs b/tests/rustdoc-html/type-alias/primitive-local-link-121106.rs index 3bdce3846c812..d4877e49a4125 100644 --- a/tests/rustdoc-html/type-alias/primitive-local-link-121106.rs +++ b/tests/rustdoc-html/type-alias/primitive-local-link-121106.rs @@ -5,7 +5,7 @@ //@ has foo/primitive.i32.html '//h1' 'Primitive Type i32' //@ has foo/index.html '//a/@href' '../foo/index.html' #[rustc_doc_primitive = "i32"] -mod i32 {} +const _: () = (); //@ has foo/struct.Node.html '//a/@href' 'primitive.i32.html' pub struct Node; diff --git a/tests/rustdoc-json/doc_attribute.rs b/tests/rustdoc-json/doc_attribute.rs index 9e1a711f0b7b5..1cb07e7a6debc 100644 --- a/tests/rustdoc-json/doc_attribute.rs +++ b/tests/rustdoc-json/doc_attribute.rs @@ -5,14 +5,11 @@ #![no_std] //@ !has "$.index[?(@.name=='repr')]" -//@ has "$.index[?(@.name=='foo')]" - #[doc(attribute = "repr")] /// this is a test! -pub mod foo {} +const _: () = (); //@ !has "$.index[?(@.name=='forbid')]" -//@ !has "$.index[?(@.name=='bar')]" #[doc(attribute = "forbid")] /// hello -mod bar {} +const _: () = (); diff --git a/tests/rustdoc-json/impls/local_for_local_primitive.rs b/tests/rustdoc-json/impls/local_for_local_primitive.rs index 859c0cb8ec82d..97ada2cf131bc 100644 --- a/tests/rustdoc-json/impls/local_for_local_primitive.rs +++ b/tests/rustdoc-json/impls/local_for_local_primitive.rs @@ -15,4 +15,4 @@ impl Local for bool {} //@ has "$.index[?(@.name=='bool')]" #[rustc_doc_primitive = "bool"] /// Boolean docs -mod prim_bool {} +const _: () = (); diff --git a/tests/rustdoc-json/keyword.rs b/tests/rustdoc-json/keyword.rs index 566b2c68bd5df..4f592745cf2b3 100644 --- a/tests/rustdoc-json/keyword.rs +++ b/tests/rustdoc-json/keyword.rs @@ -1,20 +1,17 @@ -// Regression test for . - -// Keywords should not be generated in rustdoc JSON output and this test -// ensures it. +//! Regression test for . +//! +//! Keywords should not be generated in rustdoc JSON output and this test +//! ensures it. #![feature(rustdoc_internals)] #![no_std] //@ !has "$.index[?(@.name=='match')]" -//@ has "$.index[?(@.name=='foo')]" - #[doc(keyword = "match")] /// this is a test! -pub mod foo {} +const _: () = (); //@ !has "$.index[?(@.name=='break')]" -//@ !has "$.index[?(@.name=='bar')]" #[doc(keyword = "break")] /// hello -mod bar {} +const _: () = (); diff --git a/tests/rustdoc-json/keyword_private.rs b/tests/rustdoc-json/keyword_private.rs index 3198fc2529ef8..d8da694f91465 100644 --- a/tests/rustdoc-json/keyword_private.rs +++ b/tests/rustdoc-json/keyword_private.rs @@ -1,20 +1,19 @@ -// Ensure keyword docs are present with --document-private-items +//! Regression test for . +//! +//! Keywords should not be generated in rustdoc JSON output and this test +//! ensures it. + +//@compile-flags: --document-private-items -//@ compile-flags: --document-private-items #![feature(rustdoc_internals)] +#![no_std] //@ !has "$.index[?(@.name=='match')]" -//@ has "$.index[?(@.name=='foo')]" -//@ is "$.index[?(@.name=='foo')].attrs[*].other" '"#[doc(keyword = \"match\")]"' -//@ is "$.index[?(@.name=='foo')].docs" '"this is a test!"' #[doc(keyword = "match")] /// this is a test! -pub mod foo {} +const _: () = (); //@ !has "$.index[?(@.name=='break')]" -//@ has "$.index[?(@.name=='bar')]" -//@ is "$.index[?(@.name=='bar')].attrs[*].other" '"#[doc(keyword = \"break\")]"' -//@ is "$.index[?(@.name=='bar')].docs" '"hello"' #[doc(keyword = "break")] /// hello -mod bar {} +const _: () = (); diff --git a/tests/rustdoc-json/primitives/local_primitive.rs b/tests/rustdoc-json/primitives/local_primitive.rs index b58120bae052f..e635cf12a6fb3 100644 --- a/tests/rustdoc-json/primitives/local_primitive.rs +++ b/tests/rustdoc-json/primitives/local_primitive.rs @@ -3,19 +3,25 @@ #![feature(no_core)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] +#![feature(lang_items)] #![no_core] #![rustc_coherence_is_core] //! Link to [i32][prim@i32] [i64][prim@i64] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} + #[rustc_doc_primitive = "i32"] -mod prim_i32 {} +const _: () = (); //@ set local_i32 = "$.index[?(@.name=='i32')].id" //@ has "$.index[?(@.name=='local_primitive')]" -//@ ismany "$.index[?(@.name=='local_primitive')].inner.module.items[*]" $local_i32 //@ is "$.index[?(@.name=='local_primitive')].links['prim@i32']" $local_i32 - -// Let's ensure the `prim_i32` module isn't present in the output JSON: -//@ !has "$.index[?(@.name=='prim_i32')]" diff --git a/tests/rustdoc-json/primitives/primitive_impls.rs b/tests/rustdoc-json/primitives/primitive_impls.rs index 2bdbb86862686..bb6f85a507696 100644 --- a/tests/rustdoc-json/primitives/primitive_impls.rs +++ b/tests/rustdoc-json/primitives/primitive_impls.rs @@ -35,7 +35,7 @@ impl Trait for i32 {} /// i32 #[rustc_doc_primitive = "i32"] -mod prim_i32 {} +const _: () = (); //@ set i32 = "$.index[?(@.docs=='i32')].id" //@ is "$.index[?(@.docs=='i32')].name" '"i32"' diff --git a/tests/rustdoc-json/primitives/primitive_overloading.rs b/tests/rustdoc-json/primitives/primitive_overloading.rs index ae0306843c56d..322411bcf4726 100644 --- a/tests/rustdoc-json/primitives/primitive_overloading.rs +++ b/tests/rustdoc-json/primitives/primitive_overloading.rs @@ -5,8 +5,7 @@ #![feature(rustc_attrs)] //@ has "$.index[?(@.name=='usize')]" -//@ has "$.index[?(@.name=='prim')]" #[rustc_doc_primitive = "usize"] /// This is the built-in type `usize`. -mod prim {} +const _: () = (); diff --git a/tests/rustdoc-json/primitives/use_primitive.rs b/tests/rustdoc-json/primitives/use_primitive.rs index 2991cc1e47c21..c3e3137bd0b2b 100644 --- a/tests/rustdoc-json/primitives/use_primitive.rs +++ b/tests/rustdoc-json/primitives/use_primitive.rs @@ -3,8 +3,7 @@ #![feature(rustc_attrs)] #[rustc_doc_primitive = "usize"] -mod usize {} - +const _: () = (); //@ set local_crate_id = "$.index[?(@.name=='use_primitive')].crate_id" //@ has "$.index[?(@.name=='ilog10')]" diff --git a/tests/rustdoc-ui/coverage/exotic.rs b/tests/rustdoc-ui/coverage/exotic.rs index 2beb890b21926..947ff43713b44 100644 --- a/tests/rustdoc-ui/coverage/exotic.rs +++ b/tests/rustdoc-ui/coverage/exotic.rs @@ -9,8 +9,8 @@ /// woo, check it out, we can write our own primitive docs lol #[rustc_doc_primitive = "unit"] -mod prim_unit {} +const _: () = (); /// keywords? sure, pile them on #[doc(keyword="where")] -mod where_keyword {} +const _: () = (); diff --git a/tests/rustdoc-ui/doc-attribute-unsupported.rs b/tests/rustdoc-ui/doc-attribute-unsupported.rs index 3bd153117a918..b709710644934 100644 --- a/tests/rustdoc-ui/doc-attribute-unsupported.rs +++ b/tests/rustdoc-ui/doc-attribute-unsupported.rs @@ -4,4 +4,4 @@ #[doc(attribute = "diagnostic::do_not_recommend")] //~ ERROR /// bla -mod yup {} +const _: () = (); diff --git a/tests/rustdoc-ui/invalid-attribute.rs b/tests/rustdoc-ui/invalid-attribute.rs index 2fc7be2cf341d..c229b067de6ef 100644 --- a/tests/rustdoc-ui/invalid-attribute.rs +++ b/tests/rustdoc-ui/invalid-attribute.rs @@ -4,7 +4,7 @@ #![feature(rustdoc_internals)] #[doc(attribute = "foo df")] //~ ERROR -mod foo {} +const _: () = (); #[doc(attribute = "fooyi")] //~ ERROR -mod foo2 {} +const _: () = (); diff --git a/tests/rustdoc-ui/invalid-keyword.rs b/tests/rustdoc-ui/invalid-keyword.rs index 2d70471c85e11..a9ff7d51ed2c2 100644 --- a/tests/rustdoc-ui/invalid-keyword.rs +++ b/tests/rustdoc-ui/invalid-keyword.rs @@ -1,4 +1,4 @@ #![feature(rustdoc_internals)] #[doc(keyword = "foo df")] //~ ERROR -mod foo {} +const _: () = (); diff --git a/tests/ui/feature-gates/feature-gate-rustdoc_internals.rs b/tests/ui/feature-gates/feature-gate-rustdoc_internals.rs index 0ad3b2aead481..7aa6dcbd5daac 100644 --- a/tests/ui/feature-gates/feature-gate-rustdoc_internals.rs +++ b/tests/ui/feature-gates/feature-gate-rustdoc_internals.rs @@ -1,10 +1,10 @@ #[doc(keyword = "match")] //~ ERROR: `#[doc(keyword)]` is meant for internal use only /// wonderful -mod foo {} +const _: () = (); #[doc(attribute = "repr")] //~ ERROR: `#[doc(attribute)]` is meant for internal use only /// wonderful -mod foo2 {} +const _: () = (); trait Mine {} diff --git a/tests/ui/rustdoc/doc_keyword.rs b/tests/ui/rustdoc/doc_keyword.rs index abf06d7a78663..003f90f8d0afb 100644 --- a/tests/ui/rustdoc/doc_keyword.rs +++ b/tests/ui/rustdoc/doc_keyword.rs @@ -3,21 +3,17 @@ #![doc(keyword = "match")] //~^ ERROR `#![doc(keyword = "...")]` isn't allowed as a crate-level attribute -#[doc(keyword = "match")] //~ ERROR `#[doc(keyword = "...")]` should be used on empty modules -mod foo { - fn hell() {} -} -#[doc(keyword = "match")] //~ ERROR `#[doc(keyword = "...")]` should be used on modules +#[doc(keyword = "match")] //~ ERROR `#[doc(keyword = "...")]` should be used on anonymous constants fn foo() {} // Regression test for the ICE described in #83512. trait Foo { #[doc(keyword = "match")] - //~^ ERROR: `#[doc(keyword = "...")]` should be used on modules + //~^ ERROR: `#[doc(keyword = "...")]` should be used on anonymous constants fn quux() {} } #[doc(keyword = "tadam")] //~ ERROR nonexistent keyword `tadam` -mod tadam {} +const _: () = (); diff --git a/tests/ui/rustdoc/doc_keyword.stderr b/tests/ui/rustdoc/doc_keyword.stderr index c8038cbf01969..016ec61924e8a 100644 --- a/tests/ui/rustdoc/doc_keyword.stderr +++ b/tests/ui/rustdoc/doc_keyword.stderr @@ -5,30 +5,24 @@ LL | #![doc(keyword = "match")] | ^^^^^^^ error: nonexistent keyword `tadam` used in `#[doc(keyword = "...")]` - --> $DIR/doc_keyword.rs:22:17 + --> $DIR/doc_keyword.rs:18:17 | LL | #[doc(keyword = "tadam")] | ^^^^^^^ | = help: only existing keywords are allowed in core/std -error: `#[doc(keyword = "...")]` should be used on empty modules - --> $DIR/doc_keyword.rs:6:7 +error: `#[doc(keyword = "...")]` should be used on anonymous constants + --> $DIR/doc_keyword.rs:7:7 | LL | #[doc(keyword = "match")] | ^^^^^^^ -error: `#[doc(keyword = "...")]` should be used on modules - --> $DIR/doc_keyword.rs:11:7 - | -LL | #[doc(keyword = "match")] - | ^^^^^^^ - -error: `#[doc(keyword = "...")]` should be used on modules - --> $DIR/doc_keyword.rs:17:11 +error: `#[doc(keyword = "...")]` should be used on anonymous constants + --> $DIR/doc_keyword.rs:13:11 | LL | #[doc(keyword = "match")] | ^^^^^^^ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/rustdoc/feature-gate-doc_primitive.rs b/tests/ui/rustdoc/feature-gate-doc_primitive.rs index 0ff8ce8c24bca..62f2c535edc17 100644 --- a/tests/ui/rustdoc/feature-gate-doc_primitive.rs +++ b/tests/ui/rustdoc/feature-gate-doc_primitive.rs @@ -3,6 +3,6 @@ //~| NOTE the `rustc_doc_primitive` attribute is an internal implementation detail that will never be stable //~| NOTE the `rustc_doc_primitive` attribute is used by the standard library to provide a way to generate documentation for primitive types /// Some docs -mod usize {} +const _: () = (); fn main() {} From 6a4b141fe80c7960119af1972b86521c0d76987d Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Tue, 11 Aug 2026 13:50:40 +0200 Subject: [PATCH 03/18] ensure anon consts themselves are not documented --- .../fake-items-doc-private-items.rs | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 tests/rustdoc-html/fake-items-doc-private-items.rs diff --git a/tests/rustdoc-html/fake-items-doc-private-items.rs b/tests/rustdoc-html/fake-items-doc-private-items.rs new file mode 100644 index 0000000000000..4d948fc606630 --- /dev/null +++ b/tests/rustdoc-html/fake-items-doc-private-items.rs @@ -0,0 +1,37 @@ +//! Test checking that these `_` constants don't show up +//@ compile-flags: --document-private-items + +//@ !has foo/constant._.html + +// both PUB_CONST and PRIV_CONST should show up, but not the anon consts +//@ count foo/index.html '//*[@class="constant"]' 2 +#![crate_name = "foo"] + +#![feature(rustdoc_internals)] +#![feature(rustc_attrs)] + +//@ has foo/attribute.no_mangle.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'hello attr' +#[doc(attribute = "no_mangle")] +/// hello attr +const _: () = (); + +//@ has foo/keyword.match.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'hello kw' +#[doc(keyword = "match")] +/// hello kw +const _: () = (); + +//@ has foo/primitive.i128.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'hello prim' +#[rustc_doc_primitive = "i128"] +/// hello prim +const _: () = (); + +/// regular anon const +const _: () = (); + +//@ has foo/constant.PUB_CONST.html +/// woop +pub const PUB_CONST: i32 = 42; + +//@ has foo/constant.PRIV_CONST.html +/// woop2 +const PRIV_CONST: i32 = 42; From 742c085b67af5d8ee4b930acdba19b01f6639f47 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 19 Jul 2026 18:24:50 +0200 Subject: [PATCH 04/18] Use 2 word unwinder_private_data on Emscripten The 20 word requirement was likely from the JS EH ABI which we no longer support. --- library/unwind/src/types.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/unwind/src/types.rs b/library/unwind/src/types.rs index 413cd677fe7e0..7634052c93f33 100644 --- a/library/unwind/src/types.rs +++ b/library/unwind/src/types.rs @@ -36,7 +36,6 @@ pub const unwinder_private_data_size: usize = cfg_select! { target_arch = "s390x" => 2, any(target_arch = "sparc", target_arch = "sparc64") => 2, any(target_arch = "riscv64", target_arch = "riscv32") => 2, - all(target_family = "wasm", target_os = "emscripten") => 20, target_family = "wasm" => 2, target_arch = "hexagon" => 5, any(target_arch = "loongarch32", target_arch = "loongarch64") => 2, From 1890b8287ab14fcc1e0229fdde7327e4842331df Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 3 Aug 2026 15:50:34 +0200 Subject: [PATCH 05/18] Move wasi libunwind link block to crate root This matches other targets. --- library/unwind/src/lib.rs | 4 ++++ library/unwind/src/libunwind.rs | 7 ------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index eba08aec4d109..cfe8a925052a4 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -215,6 +215,10 @@ cfg_select! { #[link(name = "gcc_s")] unsafe extern "C" {} +#[cfg(all(target_os = "wasi", panic = "unwind"))] +#[link(name = "unwind")] +unsafe extern "C" {} + #[cfg(all(target_os = "windows", target_env = "gnu", target_abi = "llvm"))] #[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))] #[link(name = "unwind", cfg(not(target_feature = "crt-static")))] diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs index bfa6b1b33008f..faf091e505e0b 100644 --- a/library/unwind/src/libunwind.rs +++ b/library/unwind/src/libunwind.rs @@ -26,13 +26,6 @@ pub enum _Unwind_Context {} all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux")), link(name = "unwind", kind = "static", modifiers = "-bundle") )] -// Explicitly link the `unwind` library on WASI targets. -// -// This is provided in the self-contained sysroot for WASI targets by default. -// Note that Rust defaults to `-Cpanic=abort` on WASI targets meaning that this -// doesn't end up getting used by default, but this does mean that with -// `-Zbuild-std` this'll automatically link it in. -#[cfg_attr(target_os = "wasi", link(name = "unwind"))] unsafe extern "C-unwind" { pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !; } From e08ce7fbbb3f98e5379b9f8be58f6f55d1550381 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 24 Jul 2026 15:32:31 +0200 Subject: [PATCH 06/18] Avoid defining dummy personality function for Motor OS --- library/std/src/sys/personality/mod.rs | 3 ++- library/unwind/src/lib.rs | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/personality/mod.rs b/library/std/src/sys/personality/mod.rs index daa53703994b0..31bd457adbe6b 100644 --- a/library/std/src/sys/personality/mod.rs +++ b/library/std/src/sys/personality/mod.rs @@ -14,7 +14,7 @@ mod dwarf; #[cfg(not(any(test, doctest)))] cfg_select! { - any(target_env = "msvc", target_family = "wasm", target_os = "motor") => { + any(target_env = "msvc", target_family = "wasm") => { // This is required by the compiler to exist (e.g., it's a lang item), // but it's never actually called by the compiler because // __CxxFrameHandler3 (msvc) / __gxx_wasm_personality_v0 (wasm) is the @@ -41,6 +41,7 @@ cfg_select! { // - os=uefi // - os=espidf // - os=hermit + // - os=motor // - nvptx64-nvidia-cuda // - arch=avr } diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index cfe8a925052a4..69b5e81a39215 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -48,6 +48,7 @@ cfg_select! { // no unwinder on the system! // - os=none ("bare metal" targets) // - os=hermit + // - os=motor // - os=uefi // - os=cuda // - nvptx64-nvidia-cuda From 37831ee36e6ef86915c1f8cbb2202a2122981f20 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 28 Jul 2026 13:54:27 +0200 Subject: [PATCH 07/18] Use dummy panic_unwind impl for Hermit And change the dummy impl to use __rust_abort to match panic_abort. --- library/panic_unwind/src/dummy.rs | 11 ++++++++--- library/panic_unwind/src/hermit.rs | 20 -------------------- library/panic_unwind/src/lib.rs | 5 +---- 3 files changed, 9 insertions(+), 27 deletions(-) delete mode 100644 library/panic_unwind/src/hermit.rs diff --git a/library/panic_unwind/src/dummy.rs b/library/panic_unwind/src/dummy.rs index a0d6876691833..3ba0bec71b7bf 100644 --- a/library/panic_unwind/src/dummy.rs +++ b/library/panic_unwind/src/dummy.rs @@ -4,12 +4,17 @@ use alloc::boxed::Box; use core::any::Any; -use core::intrinsics; + +unsafe extern "Rust" { + // This is defined in std::rt + #[rustc_std_internal_symbol] + safe fn __rust_abort() -> !; +} pub(crate) unsafe fn cleanup(_ptr: *mut u8) -> Box { - intrinsics::abort() + __rust_abort() } pub(crate) unsafe fn panic(_data: Box) -> u32 { - intrinsics::abort() + __rust_abort() } diff --git a/library/panic_unwind/src/hermit.rs b/library/panic_unwind/src/hermit.rs deleted file mode 100644 index b36d1a019fddb..0000000000000 --- a/library/panic_unwind/src/hermit.rs +++ /dev/null @@ -1,20 +0,0 @@ -//! Unwinding for *hermit* target. -//! -//! Right now we don't support this, so this is just stubs. - -use alloc::boxed::Box; -use core::any::Any; - -unsafe extern "Rust" { - // This is defined in std::rt - #[rustc_std_internal_symbol] - safe fn __rust_abort() -> !; -} - -pub(crate) unsafe fn cleanup(_ptr: *mut u8) -> Box { - __rust_abort() -} - -pub(crate) unsafe fn panic(_data: Box) -> u32 { - __rust_abort() -} diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs index 1644a2495d97e..3f409be039567 100644 --- a/library/panic_unwind/src/lib.rs +++ b/library/panic_unwind/src/lib.rs @@ -32,10 +32,6 @@ use core::any::Any; use core::panic::PanicPayload; cfg_select! { - target_os = "hermit" => { - #[path = "hermit.rs"] - mod imp; - } any( all(target_family = "windows", target_env = "gnu"), target_os = "psp", @@ -64,6 +60,7 @@ cfg_select! { // - os=none ("bare metal" targets) // - os=uefi // - os=espidf + // - os=hermit // - nvptx64-nvidia-cuda // - arch=avr #[path = "dummy.rs"] From 5b66cc1ab24491e50fbc7be04b21e00ca6a8f41f Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 4 Jul 2026 20:30:00 +0200 Subject: [PATCH 08/18] add `Complex` type --- compiler/rustc_attr_ir/src/lang_items.rs | 2 ++ compiler/rustc_span/src/symbol.rs | 1 + library/core/src/num/complex.rs | 20 ++++++++++++++++++++ library/core/src/num/mod.rs | 3 +++ library/std/src/num/mod.rs | 2 ++ tests/auxiliary/minicore.rs | 13 +++++++++++++ 6 files changed, 41 insertions(+) create mode 100644 library/core/src/num/complex.rs diff --git a/compiler/rustc_attr_ir/src/lang_items.rs b/compiler/rustc_attr_ir/src/lang_items.rs index 34f4fba5b0eea..e45621689558e 100644 --- a/compiler/rustc_attr_ir/src/lang_items.rs +++ b/compiler/rustc_attr_ir/src/lang_items.rs @@ -232,6 +232,8 @@ language_item_table! { VaArgSafe, sym::va_arg_safe, va_arg_safe, Target::Trait, GenericRequirement::None; VaList, sym::va_list, va_list, Target::Struct, GenericRequirement::None; + Complex, sym::complex, complex, Target::Struct, GenericRequirement::Exact(1); + Deref, sym::deref, deref_trait, Target::Trait, GenericRequirement::Exact(0); DerefMut, sym::deref_mut, deref_mut_trait, Target::Trait, GenericRequirement::Exact(0); DerefPure, sym::deref_pure, deref_pure_trait, Target::Trait, GenericRequirement::Exact(0); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 85f0ce7e6af00..d045f2ab3801b 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -654,6 +654,7 @@ symbols! { compiler_copy, compiler_fence, compiler_move, + complex, concat, concat_bytes, conservative_impl_trait, diff --git a/library/core/src/num/complex.rs b/library/core/src/num/complex.rs new file mode 100644 index 0000000000000..9321718899cdd --- /dev/null +++ b/library/core/src/num/complex.rs @@ -0,0 +1,20 @@ +/// A complex number. +#[derive(Clone, Copy, Debug, PartialEq)] +#[unstable(feature = "complex_numbers", issue = "154023")] +#[repr(C)] +#[lang = "complex"] +pub struct Complex { + /// The real component. + pub re: T, + /// The imaginary component. + pub im: T, +} + +#[unstable(feature = "complex_numbers", issue = "154023")] +impl Complex { + /// Create a new complex number from a real and imaginary component. + #[must_use] + pub fn new(re: T, im: T) -> Complex { + Complex { re, im } + } +} diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 478af470637d7..793222538ba41 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -42,6 +42,7 @@ mod int_macros; // import int_impl! #[macro_use] mod uint_macros; // import uint_impl! +mod complex; mod error; #[cfg(not(no_fp_fmt_parse))] mod float_parse; @@ -54,6 +55,8 @@ mod wrapping; #[doc(hidden)] pub mod niche_types; +#[unstable(feature = "complex_numbers", issue = "154023")] +pub use complex::Complex; #[stable(feature = "int_error_matching", since = "1.55.0")] pub use error::IntErrorKind; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/num/mod.rs b/library/std/src/num/mod.rs index ffb8789c906ef..5aa6c1492ec65 100644 --- a/library/std/src/num/mod.rs +++ b/library/std/src/num/mod.rs @@ -6,6 +6,8 @@ #![stable(feature = "rust1", since = "1.0.0")] #![allow(missing_docs)] +#[unstable(feature = "complex_numbers", issue = "154023")] +pub use core::num::Complex; #[stable(feature = "int_error_matching", since = "1.55.0")] pub use core::num::IntErrorKind; #[stable(feature = "generic_nonzero", since = "1.79.0")] diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs index e8bfdf80c98e8..b732088553bb3 100644 --- a/tests/auxiliary/minicore.rs +++ b/tests/auxiliary/minicore.rs @@ -391,6 +391,19 @@ pub mod hint { } } +pub mod num { + use super::Copy; + + #[repr(C)] + #[lang = "complex"] + pub struct Complex { + pub re: T, + pub im: T, + } + + impl Copy for Complex {} +} + #[lang = "c_void"] #[repr(u8)] pub enum c_void { From d7ec10329604304dfaf8b9f7a436d983f6db5176 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 12 Aug 2026 22:53:03 +0200 Subject: [PATCH 09/18] update hygiene test the new `sym::complex` in the previous commit pushes some symbol from 999 to 1000, which causes the formatting change here --- tests/ui/hygiene/unpretty-debug-lifetimes.stdout | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ui/hygiene/unpretty-debug-lifetimes.stdout b/tests/ui/hygiene/unpretty-debug-lifetimes.stdout index 689453326c0b5..c75cc7b2179d3 100644 --- a/tests/ui/hygiene/unpretty-debug-lifetimes.stdout +++ b/tests/ui/hygiene/unpretty-debug-lifetimes.stdout @@ -15,8 +15,8 @@ macro lifetime_hygiene /* 0#0 */ { - ($f /* 0#0 */:ident /* 0#0 */<$a /* 0#0 */:lifetime /* 0#0 */>) - => + ($f /* 0#0 */:ident /* 0#0 */<$a /* 0#0 */:lifetime /* 0#0 + */>) => { fn /* 0#0 */ $f /* 0#0 */<$a /* 0#0 */, 'a /* 0#0 */>() {} } } fn f /* 0#0 */<'a /* 0#0 */, 'a /* 0#1 */>() {} From 592e1384d427d33246b4f1de630543725d51dd8a Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 12 Aug 2026 15:33:31 +0200 Subject: [PATCH 10/18] define `Ty::is_complex` --- compiler/rustc_abi/src/layout/ty.rs | 8 ++++++++ compiler/rustc_middle/src/ty/layout.rs | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index 11aa18cdb224d..06bcb2b132597 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -120,6 +120,7 @@ pub trait TyAbiInterface<'a, C>: Sized + std::fmt::Debug + std::fmt::Display { fn is_tuple(this: TyAndLayout<'a, Self>) -> bool; fn is_unit(this: TyAndLayout<'a, Self>) -> bool; fn is_transparent(this: TyAndLayout<'a, Self>) -> bool; + fn is_complex_number(this: TyAndLayout<'a, Self>, cx: &C) -> bool; fn is_scalable_vector(this: TyAndLayout<'a, Self>) -> bool; /// See [`TyAndLayout::pass_indirectly_in_non_rustic_abis`] for details. fn is_pass_indirectly_in_non_rustic_abis_flag_set(this: TyAndLayout<'a, Self>) -> bool; @@ -227,6 +228,13 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { Ty::is_transparent(self) } + pub fn is_complex_number(self, cx: &C) -> bool + where + Ty: TyAbiInterface<'a, C> + Copy, + { + Ty::is_complex_number(self.peel_transparent_wrappers(cx), cx) + } + pub fn is_scalable_vector(self) -> bool where Ty: TyAbiInterface<'a, C>, diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 562a40f182312..af2481f47c9ba 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1213,6 +1213,20 @@ where matches!(this.ty.kind(), ty::Adt(def, _) if def.repr().transparent()) } + /// Does this type have a layout compatible with C `_Complex`? + /// + /// The value must be of type `core::num::Complex` where `T` is numeric. + fn is_complex_number(this: TyAndLayout<'tcx>, cx: &C) -> bool { + let ty::Adt(def, generic_args) = this.ty.kind() else { return false }; + + if !cx.tcx().is_lang_item(def.did(), LangItem::Complex) { + return false; + } + + // Only Complex<{ float }> and Complex<{ integer }> have special layout. + generic_args.type_at(0).is_numeric() + } + fn is_scalable_vector(this: TyAndLayout<'tcx>) -> bool { this.ty.is_scalable_vector() } From 05e82596bfb8add2cca573b864e935f31da7be36 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 6 Jul 2026 22:55:47 +0200 Subject: [PATCH 11/18] add `complex-abi.rs` test --- tests/codegen-llvm/complex-abi.rs | 69 +++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 tests/codegen-llvm/complex-abi.rs diff --git a/tests/codegen-llvm/complex-abi.rs b/tests/codegen-llvm/complex-abi.rs new file mode 100644 index 0000000000000..db99d6f421c5f --- /dev/null +++ b/tests/codegen-llvm/complex-abi.rs @@ -0,0 +1,69 @@ +//! Checks that `#[repr(complex)]` `Complex` matches the C `_Complex` ABI in `extern "C"` +//! functions. This is the rustc side of `tests/run-make/complex-c-abi`, which additionally +//! checks these signatures against clang. Revisions are grouped by LLVM component. + +//@ add-minicore +//@ compile-flags: -C no-prepopulate-passes -Z codegen-source-order + +#![feature(no_core, lang_items, repr_complex, f16, f128)] +#![no_core] +#![allow(improper_ctypes)] // only Complex<{float}> is guaranteed to be ABI-compatible for now +#![crate_type = "lib"] + +extern crate minicore; +use minicore::num::Complex; + +#[no_mangle] +pub extern "C" fn cplx_f16(x: Complex) -> Complex { + // CHECK: cplx_f16 + x +} + +#[no_mangle] +pub extern "C" fn cplx_f32(x: Complex) -> Complex { + x +} + +#[no_mangle] +pub extern "C" fn cplx_f64(x: Complex) -> Complex { + x +} + +#[no_mangle] +pub extern "C" fn cplx_f128(x: Complex) -> Complex { + x +} + +#[no_mangle] +pub extern "C" fn cplx_i8(x: Complex) -> Complex { + x +} + +#[no_mangle] +pub extern "C" fn cplx_i16(x: Complex) -> Complex { + x +} + +#[no_mangle] +pub extern "C" fn cplx_i32(x: Complex) -> Complex { + x +} + +#[no_mangle] +pub extern "C" fn cplx_i64(x: Complex) -> Complex { + x +} + +#[repr(transparent)] +struct Wrapper(T); + +#[no_mangle] +pub extern "C" fn wrapper_cplx_i64(x: Wrapper>) -> Wrapper> { + // I686: define{{.*}} void @wrapper_cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) + // WIN32_GNU: define{{.*}} void @wrapper_cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) + // WIN32_MSVC: define{{.*}} void @wrapper_cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) + // WINDOWS_GNU: define{{.*}} void @wrapper_cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) + // WINDOWS_MSVC: define{{.*}} void @wrapper_cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) + // X86_64: define{{.*}} { i64, i64 } @wrapper_cplx_i64({ i64, i64 } {{.*}}) + x +} From 34fab67efb755761113e6dc76fb88322e0b44149 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 6 Jul 2026 23:21:20 +0200 Subject: [PATCH 12/18] add CHECK lines and revisions --- tests/codegen-llvm/complex-abi.rs | 284 +++++++++++++++++++++++++++++- 1 file changed, 282 insertions(+), 2 deletions(-) diff --git a/tests/codegen-llvm/complex-abi.rs b/tests/codegen-llvm/complex-abi.rs index db99d6f421c5f..aa33659ae8d37 100644 --- a/tests/codegen-llvm/complex-abi.rs +++ b/tests/codegen-llvm/complex-abi.rs @@ -5,7 +5,91 @@ //@ add-minicore //@ compile-flags: -C no-prepopulate-passes -Z codegen-source-order -#![feature(no_core, lang_items, repr_complex, f16, f128)] +//@ revisions: X86_64 I686 WINDOWS_MSVC WINDOWS_GNU WIN32_MSVC WIN32_GNU +//@ [X86_64] compile-flags: --target x86_64-unknown-linux-gnu +//@ [X86_64] needs-llvm-components: x86 +//@ [I686] compile-flags: --target i686-unknown-linux-gnu +//@ [I686] needs-llvm-components: x86 +//@ [WINDOWS_MSVC] compile-flags: --target x86_64-pc-windows-msvc +//@ [WINDOWS_MSVC] needs-llvm-components: x86 +//@ [WINDOWS_GNU] compile-flags: --target x86_64-pc-windows-gnu +//@ [WINDOWS_GNU] needs-llvm-components: x86 +//@ [WIN32_MSVC] compile-flags: --target i686-pc-windows-msvc +//@ [WIN32_MSVC] needs-llvm-components: x86 +//@ [WIN32_GNU] compile-flags: --target i686-pc-windows-gnu +//@ [WIN32_GNU] needs-llvm-components: x86 + +//@ revisions: AARCH64 AARCH64_DARWIN AARCH64_MSVC ARM64EC +//@ [AARCH64] compile-flags: --target aarch64-unknown-linux-gnu +//@ [AARCH64] needs-llvm-components: aarch64 +//@ [AARCH64_DARWIN] compile-flags: --target aarch64-apple-darwin +//@ [AARCH64_DARWIN] needs-llvm-components: aarch64 +//@ [AARCH64_MSVC] compile-flags: --target aarch64-pc-windows-msvc +//@ [AARCH64_MSVC] needs-llvm-components: aarch64 +//@ [ARM64EC] compile-flags: --target arm64ec-pc-windows-msvc +//@ [ARM64EC] needs-llvm-components: aarch64 + +//@ revisions: ARM +//@ [ARM] compile-flags: --target arm-unknown-linux-gnueabihf +//@ [ARM] needs-llvm-components: arm + +//@ revisions: RISCV64 RISCV32 +//@ [RISCV64] compile-flags: --target riscv64gc-unknown-linux-gnu +//@ [RISCV64] needs-llvm-components: riscv +//@ [RISCV32] compile-flags: --target riscv32gc-unknown-linux-gnu +//@ [RISCV32] needs-llvm-components: riscv + +//@ revisions: LOONGARCH64 LOONGARCH32 +//@ [LOONGARCH64] compile-flags: --target loongarch64-unknown-linux-gnu +//@ [LOONGARCH64] needs-llvm-components: loongarch +//@ [LOONGARCH32] compile-flags: --target loongarch32-unknown-none +//@ [LOONGARCH32] needs-llvm-components: loongarch + +//@ revisions: SPARC64 SPARC +//@ [SPARC64] compile-flags: --target sparc64-unknown-linux-gnu +//@ [SPARC64] needs-llvm-components: sparc +//@ [SPARC] compile-flags: --target sparc-unknown-linux-gnu +//@ [SPARC] needs-llvm-components: sparc + +//@ revisions: S390X +//@ [S390X] compile-flags: --target s390x-unknown-linux-gnu +//@ [S390X] needs-llvm-components: systemz + +//@ revisions: POWERPC POWERPC64LE POWERPC64 AIX +//@ [POWERPC] compile-flags: --target powerpc-unknown-linux-gnu +//@ [POWERPC] needs-llvm-components: powerpc +//@ [POWERPC64LE] compile-flags: --target powerpc64le-unknown-linux-gnu +//@ [POWERPC64LE] needs-llvm-components: powerpc +//@ [POWERPC64] compile-flags: --target powerpc64-unknown-linux-gnu +//@ [POWERPC64] needs-llvm-components: powerpc +//@ [AIX] compile-flags: --target powerpc64-ibm-aix +//@ [AIX] needs-llvm-components: powerpc + +//@ revisions: MIPS64EL MIPS +//@ [MIPS64EL] compile-flags: --target mips64el-unknown-linux-gnuabi64 +//@ [MIPS64EL] needs-llvm-components: mips +//@ [MIPS] compile-flags: --target mips-unknown-linux-gnu +//@ [MIPS] needs-llvm-components: mips + +//@ revisions: WASM32 WASM64 +//@ [WASM32] compile-flags: --target wasm32-unknown-unknown +//@ [WASM32] needs-llvm-components: webassembly +//@ [WASM64] compile-flags: --target wasm64-unknown-unknown +//@ [WASM64] needs-llvm-components: webassembly + +//@ revisions: CSKY +//@ [CSKY] compile-flags: --target csky-unknown-linux-gnuabiv2 +//@ [CSKY] needs-llvm-components: csky + +//@ revisions: NVPTX +//@ [NVPTX] compile-flags: --target nvptx64-nvidia-cuda +//@ [NVPTX] needs-llvm-components: nvptx + +//@ revisions: BPF +//@ [BPF] compile-flags: --target bpfel-unknown-none +//@ [BPF] needs-llvm-components: bpf + +#![feature(no_core, lang_items, f16, f128)] #![no_core] #![allow(improper_ctypes)] // only Complex<{float}> is guaranteed to be ABI-compatible for now #![crate_type = "lib"] @@ -15,42 +99,238 @@ use minicore::num::Complex; #[no_mangle] pub extern "C" fn cplx_f16(x: Complex) -> Complex { - // CHECK: cplx_f16 + // AARCH64: define{{.*}} { half, half } @cplx_f16([2 x half] {{.*}}) + // AARCH64_DARWIN: define{{.*}} { half, half } @cplx_f16([2 x half] {{.*}}) + // AARCH64_MSVC: define{{.*}} { half, half } @cplx_f16([2 x half] {{.*}}) + // ARM64EC: define{{.*}} { half, half } @cplx_f16([2 x half] {{.*}}) + // ARM: define{{.*}} i32 @cplx_f16([1 x i32] {{.*}}) + // I686: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval({ half, half }) {{.*}}) + // LOONGARCH32: define{{.*}} { half, half } @cplx_f16(half {{.*}}, half {{.*}}) + // LOONGARCH64: define{{.*}} { half, half } @cplx_f16(half {{.*}}, half {{.*}}) + // NVPTX: define{{.*}} { half, half } @cplx_f16(ptr {{.*}} byval({ half, half }) {{.*}}) + // RISCV32: define{{.*}} { half, half } @cplx_f16(half {{.*}}, half {{.*}}) + // RISCV64: define{{.*}} { half, half } @cplx_f16(half {{.*}}, half {{.*}}) + // S390X: define{{.*}} void @cplx_f16(ptr {{.*}} sret({ half, half }) {{.*}}, ptr {{.*}}) + // WIN32_GNU: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval({ half, half }) {{.*}}) + // WIN32_MSVC: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval({ half, half }) {{.*}}) + // WINDOWS_GNU: define{{.*}} i32 @cplx_f16(i32 {{.*}}) + // WINDOWS_MSVC: define{{.*}} i32 @cplx_f16(i32 {{.*}}) + // X86_64: define{{.*}} <2 x half> @cplx_f16(<2 x half> {{.*}}) x } #[no_mangle] pub extern "C" fn cplx_f32(x: Complex) -> Complex { + // AARCH64: define{{.*}} { float, float } @cplx_f32([2 x float] {{.*}}) + // AARCH64_DARWIN: define{{.*}} { float, float } @cplx_f32([2 x float] {{.*}}) + // AARCH64_MSVC: define{{.*}} { float, float } @cplx_f32([2 x float] {{.*}}) + // AIX: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) + // ARM64EC: define{{.*}} { float, float } @cplx_f32([2 x float] {{.*}}) + // ARM: define{{.*}} { float, float } @cplx_f32({ float, float } {{.*}}) + // BPF: define{{.*}} void @cplx_f32(ptr {{.*}} sret({ float, float }) {{.*}}, i64 {{.*}}) + // CSKY: define{{.*}} [2 x i32] @cplx_f32([2 x i32] {{.*}}) + // I686: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) + // LOONGARCH32: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) + // LOONGARCH64: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) + // MIPS64EL: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) + // MIPS: define{{.*}} { float, float } @cplx_f32(i32 {{.*}}, i32 {{.*}}) + // NVPTX: define{{.*}} { float, float } @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) + // POWERPC64: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) + // POWERPC64LE: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) + // POWERPC: define{{.*}} void @cplx_f32(ptr {{.*}} sret({ float, float }) {{.*}}, ptr {{.*}} byval({ float, float }) {{.*}}) + // RISCV32: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) + // RISCV64: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) + // S390X: define{{.*}} void @cplx_f32(ptr {{.*}} sret({ float, float }) {{.*}}, ptr {{.*}}) + // SPARC64: define{{.*}} {{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) + // SPARC: define{{.*}} { float, float } @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) + // WASM32: define{{.*}} void @cplx_f32(ptr {{.*}} sret({ float, float }) {{.*}}, ptr {{.*}} byval({ float, float }) {{.*}}) + // WASM64: define{{.*}} void @cplx_f32(ptr {{.*}} sret({ float, float }) {{.*}}, ptr {{.*}} byval({ float, float }) {{.*}}) + // WIN32_GNU: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) + // WIN32_MSVC: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) + // WINDOWS_GNU: define{{.*}} i64 @cplx_f32(i64 {{.*}}) + // WINDOWS_MSVC: define{{.*}} i64 @cplx_f32(i64 {{.*}}) + // X86_64: define{{.*}} <2 x float> @cplx_f32(<2 x float> {{.*}}) x } #[no_mangle] pub extern "C" fn cplx_f64(x: Complex) -> Complex { + // AARCH64: define{{.*}} { double, double } @cplx_f64([2 x double] {{.*}}) + // AARCH64_DARWIN: define{{.*}} { double, double } @cplx_f64([2 x double] {{.*}}) + // AARCH64_MSVC: define{{.*}} { double, double } @cplx_f64([2 x double] {{.*}}) + // AIX: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // ARM64EC: define{{.*}} { double, double } @cplx_f64([2 x double] {{.*}}) + // ARM: define{{.*}} { double, double } @cplx_f64({ double, double } {{.*}}) + // BPF: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, [2 x i64] {{.*}}) + // CSKY: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, [4 x i32] {{.*}}) + // I686: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) + // LOONGARCH32: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // LOONGARCH64: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // MIPS64EL: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // MIPS: define{{.*}} { double, double } @cplx_f64(i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}) + // NVPTX: define{{.*}} { double, double } @cplx_f64(ptr {{.*}} byval({ double, double }) {{.*}}) + // POWERPC64: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // POWERPC64LE: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // POWERPC: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) + // RISCV32: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // RISCV64: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // S390X: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}}) + // SPARC64: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // SPARC: define{{.*}} { double, double } @cplx_f64(ptr {{.*}} byval({ double, double }) {{.*}}) + // WASM32: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) + // WASM64: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) + // WIN32_GNU: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) + // WIN32_MSVC: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) + // WINDOWS_GNU: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}}) + // WINDOWS_MSVC: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}}) + // X86_64: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) x } #[no_mangle] pub extern "C" fn cplx_f128(x: Complex) -> Complex { + // I686: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) + // WASM32: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) + // WASM64: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) + // WIN32_GNU: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) + // WINDOWS_GNU: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}}) + // X86_64: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) x } #[no_mangle] pub extern "C" fn cplx_i8(x: Complex) -> Complex { + // AARCH64: define{{.*}} i16 @cplx_i8(i64{{.*}}) + // AARCH64_DARWIN: define{{.*}} i16 @cplx_i8(i64{{.*}}) + // AARCH64_MSVC: define{{.*}} i16 @cplx_i8(i64{{.*}}) + // AIX: define{{.*}} { i8, i8 } @cplx_i8(i8 {{.*}}, i8 {{.*}}) + // ARM64EC: define{{.*}} i16 @cplx_i8(i64{{.*}}) + // ARM: define{{.*}} i16 @cplx_i8([1 x i32]{{.*}}) + // BPF: define{{.*}} void @cplx_i8(ptr {{.*}} sret({ i8, i8 }) {{.*}}, i16 {{.*}}) + // CSKY: define{{.*}} {{.*}} i32 @cplx_i8(i32{{.*}}) + // I686: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // LOONGARCH32: define{{.*}} {{.*}} i32 @cplx_i8(i32{{.*}}) + // LOONGARCH64: define{{.*}} {{.*}} i64 @cplx_i8(i64{{.*}}) + // MIPS64EL: define{{.*}} { i8, i8 } @cplx_i8(i16 {{.*}}) + // MIPS: define{{.*}} { i8, i8 } @cplx_i8(i16 {{.*}}) + // NVPTX: define{{.*}} { i8, i8 } @cplx_i8(ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // POWERPC64: define{{.*}} { i8, i8 } @cplx_i8(i8 {{.*}}, i8 {{.*}}) + // POWERPC64LE: define{{.*}} { i8, i8 } @cplx_i8(i8 {{.*}}, i8 {{.*}}) + // POWERPC: define{{.*}} void @cplx_i8(ptr {{.*}} sret({ i8, i8 }) {{.*}}, ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // RISCV32: define{{.*}} {{.*}} i32 @cplx_i8(i32{{.*}}) + // RISCV64: define{{.*}} {{.*}} i64 @cplx_i8(i64{{.*}}) + // S390X: define{{.*}} void @cplx_i8(ptr {{.*}} sret({ i8, i8 }) {{.*}}, ptr {{.*}}) + // SPARC64: define{{.*}} {{.*}} i64 @cplx_i8(i64{{.*}}) + // SPARC: define{{.*}} { i8, i8 } @cplx_i8(ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // WASM32: define{{.*}} void @cplx_i8(ptr {{.*}} sret({ i8, i8 }) {{.*}}, ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // WASM64: define{{.*}} void @cplx_i8(ptr {{.*}} sret({ i8, i8 }) {{.*}}, ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // WIN32_GNU: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // WIN32_MSVC: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // WINDOWS_GNU: define{{.*}} i16 @cplx_i8(i16 {{.*}}) + // WINDOWS_MSVC: define{{.*}} i16 @cplx_i8(i16 {{.*}}) + // X86_64: define{{.*}} i16 @cplx_i8(i16 {{.*}}) x } #[no_mangle] pub extern "C" fn cplx_i16(x: Complex) -> Complex { + // AARCH64: define{{.*}} i32 @cplx_i16(i64{{.*}}) + // AARCH64_DARWIN: define{{.*}} i32 @cplx_i16(i64{{.*}}) + // AARCH64_MSVC: define{{.*}} i32 @cplx_i16(i64{{.*}}) + // AIX: define{{.*}} { i16, i16 } @cplx_i16(i16 {{.*}}, i16 {{.*}}) + // ARM64EC: define{{.*}} i32 @cplx_i16(i64{{.*}}) + // ARM: define{{.*}} i32 @cplx_i16([1 x i32] {{.*}}) + // BPF: define{{.*}} void @cplx_i16(ptr {{.*}} sret({ i16, i16 }) {{.*}}, i32 {{.*}}) + // CSKY: define{{.*}} i32 @cplx_i16(i32 {{.*}}) + // I686: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // LOONGARCH32: define{{.*}} i32 @cplx_i16(i32 {{.*}}) + // LOONGARCH64: define{{.*}} {{.*}} i64 @cplx_i16(i64{{.*}}) + // MIPS64EL: define{{.*}} { i16, i16 } @cplx_i16(i32 {{.*}}) + // MIPS: define{{.*}} { i16, i16 } @cplx_i16(i32 {{.*}}) + // NVPTX: define{{.*}} { i16, i16 } @cplx_i16(ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // POWERPC64: define{{.*}} { i16, i16 } @cplx_i16(i16 {{.*}}, i16 {{.*}}) + // POWERPC64LE: define{{.*}} { i16, i16 } @cplx_i16(i16 {{.*}}, i16 {{.*}}) + // POWERPC: define{{.*}} void @cplx_i16(ptr {{.*}} sret({ i16, i16 }) {{.*}}, ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // RISCV32: define{{.*}} i32 @cplx_i16(i32 {{.*}}) + // RISCV64: define{{.*}} {{.*}} i64 @cplx_i16(i64{{.*}}) + // S390X: define{{.*}} void @cplx_i16(ptr {{.*}} sret({ i16, i16 }) {{.*}}, ptr {{.*}}) + // SPARC64: define{{.*}} {{.*}} i64 @cplx_i16(i64{{.*}}) + // SPARC: define{{.*}} { i16, i16 } @cplx_i16(ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // WASM32: define{{.*}} void @cplx_i16(ptr {{.*}} sret({ i16, i16 }) {{.*}}, ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // WASM64: define{{.*}} void @cplx_i16(ptr {{.*}} sret({ i16, i16 }) {{.*}}, ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // WIN32_GNU: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // WIN32_MSVC: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // WINDOWS_GNU: define{{.*}} i32 @cplx_i16(i32 {{.*}}) + // WINDOWS_MSVC: define{{.*}} i32 @cplx_i16(i32 {{.*}}) + // X86_64: define{{.*}} i32 @cplx_i16(i32 {{.*}}) x } #[no_mangle] pub extern "C" fn cplx_i32(x: Complex) -> Complex { + // AARCH64: define{{.*}} i64 @cplx_i32(i64 {{.*}}) + // AARCH64_DARWIN: define{{.*}} i64 @cplx_i32(i64 {{.*}}) + // AARCH64_MSVC: define{{.*}} i64 @cplx_i32(i64 {{.*}}) + // AIX: define{{.*}} { i32, i32 } @cplx_i32(i32 {{.*}}, i32 {{.*}}) + // ARM64EC: define{{.*}} i64 @cplx_i32(i64 {{.*}}) + // ARM: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, [2 x i32] {{.*}}) + // BPF: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, i64 {{.*}}) + // CSKY: define{{.*}} [2 x i32] @cplx_i32([2 x i32] {{.*}}) + // I686: define{{.*}} i64 @cplx_i32(ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // LOONGARCH32: define{{.*}} [2 x i32] @cplx_i32([2 x i32] {{.*}}) + // LOONGARCH64: define{{.*}} i64 @cplx_i32(i64 {{.*}}) + // MIPS64EL: define{{.*}} { i32, i32 } @cplx_i32(i64 {{.*}}) + // MIPS: define{{.*}} { i32, i32 } @cplx_i32(i32 {{.*}}, i32 {{.*}}) + // NVPTX: define{{.*}} { i32, i32 } @cplx_i32(ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // POWERPC64: define{{.*}} { i32, i32 } @cplx_i32(i32 {{.*}}, i32 {{.*}}) + // POWERPC64LE: define{{.*}} { i32, i32 } @cplx_i32(i32 {{.*}}, i32 {{.*}}) + // POWERPC: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // RISCV32: define{{.*}} [2 x i32] @cplx_i32([2 x i32] {{.*}}) + // RISCV64: define{{.*}} i64 @cplx_i32(i64 {{.*}}) + // S390X: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, ptr {{.*}}) + // SPARC64: define{{.*}} i64 @cplx_i32(i64 {{.*}}) + // SPARC: define{{.*}} { i32, i32 } @cplx_i32(ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // WASM32: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // WASM64: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // WIN32_GNU: define{{.*}} i64 @cplx_i32(ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // WIN32_MSVC: define{{.*}} i64 @cplx_i32(ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // WINDOWS_GNU: define{{.*}} i64 @cplx_i32(i64 {{.*}}) + // WINDOWS_MSVC: define{{.*}} i64 @cplx_i32(i64 {{.*}}) + // X86_64: define{{.*}} i64 @cplx_i32(i64 {{.*}}) x } #[no_mangle] pub extern "C" fn cplx_i64(x: Complex) -> Complex { + // AARCH64: define{{.*}} [2 x i64] @cplx_i64([2 x i64] {{.*}}) + // AARCH64_DARWIN: define{{.*}} [2 x i64] @cplx_i64([2 x i64] {{.*}}) + // AARCH64_MSVC: define{{.*}} [2 x i64] @cplx_i64([2 x i64] {{.*}}) + // AIX: define{{.*}} { i64, i64 } @cplx_i64(i64 {{.*}}, i64 {{.*}}) + // ARM64EC: define{{.*}} [2 x i64] @cplx_i64([2 x i64] {{.*}}) + // ARM: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, [2 x i64] {{.*}}) + // BPF: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, [2 x i64] {{.*}}) + // CSKY: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, [4 x i32] {{.*}}) + // I686: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // LOONGARCH32: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}}) + // LOONGARCH64: define{{.*}} [2 x i64] @cplx_i64([2 x i64] {{.*}}) + // MIPS64EL: define{{.*}} { i64, i64 } @cplx_i64(i64 {{.*}}, i64 {{.*}}) + // MIPS: define{{.*}} { i64, i64 } @cplx_i64(i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}) + // NVPTX: define{{.*}} { i64, i64 } @cplx_i64(ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // POWERPC64: define{{.*}} { i64, i64 } @cplx_i64(i64 {{.*}}, i64 {{.*}}) + // POWERPC64LE: define{{.*}} { i64, i64 } @cplx_i64(i64 {{.*}}, i64 {{.*}}) + // POWERPC: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // RISCV32: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}}) + // RISCV64: define{{.*}} [2 x i64] @cplx_i64([2 x i64] {{.*}}) + // S390X: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}}) + // SPARC64: define{{.*}} { i64, i64 } @cplx_i64(i64 {{.*}}, i64 {{.*}}) + // SPARC: define{{.*}} { i64, i64 } @cplx_i64(ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // WASM32: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // WASM64: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // WIN32_GNU: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // WIN32_MSVC: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // WINDOWS_GNU: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}}) + // WINDOWS_MSVC: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}}) + // X86_64: define{{.*}} { i64, i64 } @cplx_i64(i64 {{.*}}, i64 {{.*}}) x } From 4213ac72da22a5710d7b6210bfd420cc36d8c931 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 6 Jul 2026 23:25:14 +0200 Subject: [PATCH 13/18] disable most revisions --- tests/codegen-llvm/complex-abi.rs | 134 +++++++++++++++--------------- 1 file changed, 69 insertions(+), 65 deletions(-) diff --git a/tests/codegen-llvm/complex-abi.rs b/tests/codegen-llvm/complex-abi.rs index aa33659ae8d37..86a921592412e 100644 --- a/tests/codegen-llvm/complex-abi.rs +++ b/tests/codegen-llvm/complex-abi.rs @@ -5,89 +5,93 @@ //@ add-minicore //@ compile-flags: -C no-prepopulate-passes -Z codegen-source-order -//@ revisions: X86_64 I686 WINDOWS_MSVC WINDOWS_GNU WIN32_MSVC WIN32_GNU +//@ revisions: X86_64 WINDOWS_MSVC WINDOWS_GNU //@ [X86_64] compile-flags: --target x86_64-unknown-linux-gnu //@ [X86_64] needs-llvm-components: x86 -//@ [I686] compile-flags: --target i686-unknown-linux-gnu -//@ [I686] needs-llvm-components: x86 //@ [WINDOWS_MSVC] compile-flags: --target x86_64-pc-windows-msvc //@ [WINDOWS_MSVC] needs-llvm-components: x86 //@ [WINDOWS_GNU] compile-flags: --target x86_64-pc-windows-gnu //@ [WINDOWS_GNU] needs-llvm-components: x86 -//@ [WIN32_MSVC] compile-flags: --target i686-pc-windows-msvc -//@ [WIN32_MSVC] needs-llvm-components: x86 -//@ [WIN32_GNU] compile-flags: --target i686-pc-windows-gnu -//@ [WIN32_GNU] needs-llvm-components: x86 -//@ revisions: AARCH64 AARCH64_DARWIN AARCH64_MSVC ARM64EC -//@ [AARCH64] compile-flags: --target aarch64-unknown-linux-gnu -//@ [AARCH64] needs-llvm-components: aarch64 -//@ [AARCH64_DARWIN] compile-flags: --target aarch64-apple-darwin -//@ [AARCH64_DARWIN] needs-llvm-components: aarch64 -//@ [AARCH64_MSVC] compile-flags: --target aarch64-pc-windows-msvc -//@ [AARCH64_MSVC] needs-llvm-components: aarch64 -//@ [ARM64EC] compile-flags: --target arm64ec-pc-windows-msvc -//@ [ARM64EC] needs-llvm-components: aarch64 +// FIXME: the below revisions are deliberately disabled for now. -//@ revisions: ARM -//@ [ARM] compile-flags: --target arm-unknown-linux-gnueabihf -//@ [ARM] needs-llvm-components: arm +// revisions: I686 WIN32_MSVC WIN32_GNU +// [I686] compile-flags: --target i686-unknown-linux-gnu +// [I686] needs-llvm-components: x86 +// [WIN32_MSVC] compile-flags: --target i686-pc-windows-msvc +// [WIN32_MSVC] needs-llvm-components: x86 +// [WIN32_GNU] compile-flags: --target i686-pc-windows-gnu +// [WIN32_GNU] needs-llvm-components: x86 -//@ revisions: RISCV64 RISCV32 -//@ [RISCV64] compile-flags: --target riscv64gc-unknown-linux-gnu -//@ [RISCV64] needs-llvm-components: riscv -//@ [RISCV32] compile-flags: --target riscv32gc-unknown-linux-gnu -//@ [RISCV32] needs-llvm-components: riscv +// revisions: AARCH64 AARCH64_DARWIN AARCH64_MSVC ARM64EC +// [AARCH64] compile-flags: --target aarch64-unknown-linux-gnu +// [AARCH64] needs-llvm-components: aarch64 +// [AARCH64_DARWIN] compile-flags: --target aarch64-apple-darwin +// [AARCH64_DARWIN] needs-llvm-components: aarch64 +// [AARCH64_MSVC] compile-flags: --target aarch64-pc-windows-msvc +// [AARCH64_MSVC] needs-llvm-components: aarch64 +// [ARM64EC] compile-flags: --target arm64ec-pc-windows-msvc +// [ARM64EC] needs-llvm-components: aarch64 -//@ revisions: LOONGARCH64 LOONGARCH32 -//@ [LOONGARCH64] compile-flags: --target loongarch64-unknown-linux-gnu -//@ [LOONGARCH64] needs-llvm-components: loongarch -//@ [LOONGARCH32] compile-flags: --target loongarch32-unknown-none -//@ [LOONGARCH32] needs-llvm-components: loongarch +// revisions: ARM +// [ARM] compile-flags: --target arm-unknown-linux-gnueabihf +// [ARM] needs-llvm-components: arm -//@ revisions: SPARC64 SPARC -//@ [SPARC64] compile-flags: --target sparc64-unknown-linux-gnu -//@ [SPARC64] needs-llvm-components: sparc -//@ [SPARC] compile-flags: --target sparc-unknown-linux-gnu -//@ [SPARC] needs-llvm-components: sparc +// revisions: RISCV64 RISCV32 +// [RISCV64] compile-flags: --target riscv64gc-unknown-linux-gnu +// [RISCV64] needs-llvm-components: riscv +// [RISCV32] compile-flags: --target riscv32gc-unknown-linux-gnu +// [RISCV32] needs-llvm-components: riscv -//@ revisions: S390X -//@ [S390X] compile-flags: --target s390x-unknown-linux-gnu -//@ [S390X] needs-llvm-components: systemz +// revisions: LOONGARCH64 LOONGARCH32 +// [LOONGARCH64] compile-flags: --target loongarch64-unknown-linux-gnu +// [LOONGARCH64] needs-llvm-components: loongarch +// [LOONGARCH32] compile-flags: --target loongarch32-unknown-none +// [LOONGARCH32] needs-llvm-components: loongarch -//@ revisions: POWERPC POWERPC64LE POWERPC64 AIX -//@ [POWERPC] compile-flags: --target powerpc-unknown-linux-gnu -//@ [POWERPC] needs-llvm-components: powerpc -//@ [POWERPC64LE] compile-flags: --target powerpc64le-unknown-linux-gnu -//@ [POWERPC64LE] needs-llvm-components: powerpc -//@ [POWERPC64] compile-flags: --target powerpc64-unknown-linux-gnu -//@ [POWERPC64] needs-llvm-components: powerpc -//@ [AIX] compile-flags: --target powerpc64-ibm-aix -//@ [AIX] needs-llvm-components: powerpc +// revisions: SPARC64 SPARC +// [SPARC64] compile-flags: --target sparc64-unknown-linux-gnu +// [SPARC64] needs-llvm-components: sparc +// [SPARC] compile-flags: --target sparc-unknown-linux-gnu +// [SPARC] needs-llvm-components: sparc -//@ revisions: MIPS64EL MIPS -//@ [MIPS64EL] compile-flags: --target mips64el-unknown-linux-gnuabi64 -//@ [MIPS64EL] needs-llvm-components: mips -//@ [MIPS] compile-flags: --target mips-unknown-linux-gnu -//@ [MIPS] needs-llvm-components: mips +// revisions: S390X +// [S390X] compile-flags: --target s390x-unknown-linux-gnu +// [S390X] needs-llvm-components: systemz -//@ revisions: WASM32 WASM64 -//@ [WASM32] compile-flags: --target wasm32-unknown-unknown -//@ [WASM32] needs-llvm-components: webassembly -//@ [WASM64] compile-flags: --target wasm64-unknown-unknown -//@ [WASM64] needs-llvm-components: webassembly +// revisions: POWERPC POWERPC64LE POWERPC64 AIX +// [POWERPC] compile-flags: --target powerpc-unknown-linux-gnu +// [POWERPC] needs-llvm-components: powerpc +// [POWERPC64LE] compile-flags: --target powerpc64le-unknown-linux-gnu +// [POWERPC64LE] needs-llvm-components: powerpc +// [POWERPC64] compile-flags: --target powerpc64-unknown-linux-gnu +// [POWERPC64] needs-llvm-components: powerpc +// [AIX] compile-flags: --target powerpc64-ibm-aix +// [AIX] needs-llvm-components: powerpc -//@ revisions: CSKY -//@ [CSKY] compile-flags: --target csky-unknown-linux-gnuabiv2 -//@ [CSKY] needs-llvm-components: csky +// revisions: MIPS64EL MIPS +// [MIPS64EL] compile-flags: --target mips64el-unknown-linux-gnuabi64 +// [MIPS64EL] needs-llvm-components: mips +// [MIPS] compile-flags: --target mips-unknown-linux-gnu +// [MIPS] needs-llvm-components: mips -//@ revisions: NVPTX -//@ [NVPTX] compile-flags: --target nvptx64-nvidia-cuda -//@ [NVPTX] needs-llvm-components: nvptx +// revisions: WASM32 WASM64 +// [WASM32] compile-flags: --target wasm32-unknown-unknown +// [WASM32] needs-llvm-components: webassembly +// [WASM64] compile-flags: --target wasm64-unknown-unknown +// [WASM64] needs-llvm-components: webassembly -//@ revisions: BPF -//@ [BPF] compile-flags: --target bpfel-unknown-none -//@ [BPF] needs-llvm-components: bpf +// revisions: CSKY +// [CSKY] compile-flags: --target csky-unknown-linux-gnuabiv2 +// [CSKY] needs-llvm-components: csky + +// revisions: NVPTX +// [NVPTX] compile-flags: --target nvptx64-nvidia-cuda +// [NVPTX] needs-llvm-components: nvptx + +// revisions: BPF +// [BPF] compile-flags: --target bpfel-unknown-none +// [BPF] needs-llvm-components: bpf #![feature(no_core, lang_items, f16, f128)] #![no_core] From 5e8cc87124b6dd3fbf40fff08f2a1dd8e9f0b7ff Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 6 Jul 2026 23:41:57 +0200 Subject: [PATCH 14/18] Implement and test x86_64 Complex --- tests/codegen-llvm/complex-abi.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/codegen-llvm/complex-abi.rs b/tests/codegen-llvm/complex-abi.rs index 86a921592412e..7175b2ec6813b 100644 --- a/tests/codegen-llvm/complex-abi.rs +++ b/tests/codegen-llvm/complex-abi.rs @@ -119,7 +119,7 @@ pub extern "C" fn cplx_f16(x: Complex) -> Complex { // WIN32_MSVC: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval({ half, half }) {{.*}}) // WINDOWS_GNU: define{{.*}} i32 @cplx_f16(i32 {{.*}}) // WINDOWS_MSVC: define{{.*}} i32 @cplx_f16(i32 {{.*}}) - // X86_64: define{{.*}} <2 x half> @cplx_f16(<2 x half> {{.*}}) + // X86_64: define{{.*}} float @cplx_f16(float {{.*}}) x } @@ -153,7 +153,7 @@ pub extern "C" fn cplx_f32(x: Complex) -> Complex { // WIN32_MSVC: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) // WINDOWS_GNU: define{{.*}} i64 @cplx_f32(i64 {{.*}}) // WINDOWS_MSVC: define{{.*}} i64 @cplx_f32(i64 {{.*}}) - // X86_64: define{{.*}} <2 x float> @cplx_f32(<2 x float> {{.*}}) + // X86_64: define{{.*}} double @cplx_f32(double {{.*}}) x } @@ -185,9 +185,9 @@ pub extern "C" fn cplx_f64(x: Complex) -> Complex { // WASM64: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) // WIN32_GNU: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) // WIN32_MSVC: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) - // WINDOWS_GNU: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}}) - // WINDOWS_MSVC: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}}) - // X86_64: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // WINDOWS_GNU: define{{.*}} void @cplx_f64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) + // WINDOWS_MSVC: define{{.*}} void @cplx_f64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) + // X86_64: define{{.*}} { double, double } @cplx_f64({ double, double } {{.*}}) x } @@ -197,8 +197,8 @@ pub extern "C" fn cplx_f128(x: Complex) -> Complex { // WASM32: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) // WASM64: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) // WIN32_GNU: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) - // WINDOWS_GNU: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}}) - // X86_64: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) + // WINDOWS_GNU: define{{.*}} void @cplx_f128(ptr {{.*}} sret([32 x i8]) {{.*}}, ptr {{.*}}) + // X86_64: define{{.*}} void @cplx_f128(ptr {{.*}} sret([32 x i8]) {{.*}}, ptr {{.*}} byval([32 x i8]) {{.*}}) x } @@ -332,9 +332,9 @@ pub extern "C" fn cplx_i64(x: Complex) -> Complex { // WASM64: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) // WIN32_GNU: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) // WIN32_MSVC: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) - // WINDOWS_GNU: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}}) - // WINDOWS_MSVC: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}}) - // X86_64: define{{.*}} { i64, i64 } @cplx_i64(i64 {{.*}}, i64 {{.*}}) + // WINDOWS_GNU: define{{.*}} void @cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) + // WINDOWS_MSVC: define{{.*}} void @cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) + // X86_64: define{{.*}} { i64, i64 } @cplx_i64({ i64, i64 } {{.*}}) x } From daf4a0eac168b6f06b1c8e77669eb0136ad23017 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 22 Jul 2026 01:26:49 +0200 Subject: [PATCH 15/18] `Complex` return on `x86` --- compiler/rustc_abi/src/layout/ty.rs | 20 ++++++ compiler/rustc_target/src/callconv/x86.rs | 11 +++- .../rustc_target/src/callconv/x86_win32.rs | 8 ++- tests/codegen-llvm/complex-abi.rs | 62 +++++++++---------- 4 files changed, 66 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index 06bcb2b132597..b835909d2c2ca 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -299,6 +299,26 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { found } + pub fn complex_float(&self, cx: &C) -> Option + where + Ty: TyAbiInterface<'a, C> + Copy, + { + if !Ty::is_complex_number(*self, cx) { + return None; + } + + let BackendRepr::ScalarPair { a, b, .. } = self.backend_repr else { + return None; + }; + + debug_assert_eq!(a, b); + + match a.primitive() { + Primitive::Float(f) => Some(f), + _ => None, + } + } + /// Whether this type/layout has any padding that is dependent on a variant, i.e. has bytes that /// are padding for some, but not all, valid values of this type. pub fn has_variant_dependent_padding(&self, cx: &C) -> bool diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs index a80088e41cd31..fd608fcf62919 100644 --- a/compiler/rustc_target/src/callconv/x86.rs +++ b/compiler/rustc_target/src/callconv/x86.rs @@ -1,5 +1,5 @@ use rustc_abi::{ - AddressSpace, Align, BackendRepr, HasDataLayout, Primitive, Reg, RegKind, TyAndLayout, + AddressSpace, Align, BackendRepr, Float, HasDataLayout, Primitive, Reg, RegKind, TyAndLayout, }; use crate::callconv::{ArgAttribute, FnAbi, PassMode, TyAbiInterface}; @@ -32,7 +32,14 @@ where // https://www.angelcode.com/dev/callconv/callconv.html // Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp let t = cx.target_spec(); - if t.abi_return_struct_as_int || opts.reg_struct_return { + if let Some(Float::F16) = fn_abi.ret.layout.complex_float(cx) { + // `_Complex _Float16` is returned as `<2 x half>`. + let kind = RegKind::Vector { hint_vector_elem: Primitive::Float(Float::F16) }; + fn_abi.ret.cast_to(Reg { kind, size: fn_abi.ret.layout.size }); + } else if t.abi_return_struct_as_int + || opts.reg_struct_return + || fn_abi.ret.layout.is_complex_number(cx) + { // According to Clang, everyone but MSVC returns single-element // float aggregates directly in a floating-point register. if fn_abi.ret.layout.is_single_fp_element(cx) { diff --git a/compiler/rustc_target/src/callconv/x86_win32.rs b/compiler/rustc_target/src/callconv/x86_win32.rs index 824e7cc098a46..9303711b7f6ad 100644 --- a/compiler/rustc_target/src/callconv/x86_win32.rs +++ b/compiler/rustc_target/src/callconv/x86_win32.rs @@ -1,4 +1,4 @@ -use rustc_abi::{Align, HasDataLayout, Reg, TyAbiInterface}; +use rustc_abi::{Align, Float, HasDataLayout, Primitive, Reg, RegKind, TyAbiInterface}; use crate::callconv::FnAbi; use crate::spec::HasTargetSpec; @@ -25,7 +25,11 @@ pub(crate) fn compute_abi_info<'a, Ty, C>( // GCC used to apply the SysV rule here, breaking windows-gnu's ABI, but was fixed: // - reported in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82028 // - fixed in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85667 - if t.abi_return_struct_as_int || opts.reg_struct_return { + if let Some(Float::F16) = fn_abi.ret.layout.complex_float(cx) { + // `_Complex _Float16` is returned as `<2 x half>`. + let kind = RegKind::Vector { hint_vector_elem: Primitive::Float(Float::F16) }; + fn_abi.ret.cast_to(Reg { kind, size: fn_abi.ret.layout.size }); + } else if t.abi_return_struct_as_int || opts.reg_struct_return { match fn_abi.ret.layout.size.bytes() { 1 => fn_abi.ret.cast_to(Reg::i8()), 2 => fn_abi.ret.cast_to(Reg::i16()), diff --git a/tests/codegen-llvm/complex-abi.rs b/tests/codegen-llvm/complex-abi.rs index 7175b2ec6813b..c3e873c6fca93 100644 --- a/tests/codegen-llvm/complex-abi.rs +++ b/tests/codegen-llvm/complex-abi.rs @@ -13,15 +13,15 @@ //@ [WINDOWS_GNU] compile-flags: --target x86_64-pc-windows-gnu //@ [WINDOWS_GNU] needs-llvm-components: x86 -// FIXME: the below revisions are deliberately disabled for now. +//@ revisions: I686 WIN32_MSVC WIN32_GNU +//@ [I686] compile-flags: --target i686-unknown-linux-gnu +//@ [I686] needs-llvm-components: x86 +//@ [WIN32_MSVC] compile-flags: --target i686-pc-windows-msvc +//@ [WIN32_MSVC] needs-llvm-components: x86 +//@ [WIN32_GNU] compile-flags: --target i686-pc-windows-gnu +//@ [WIN32_GNU] needs-llvm-components: x86 -// revisions: I686 WIN32_MSVC WIN32_GNU -// [I686] compile-flags: --target i686-unknown-linux-gnu -// [I686] needs-llvm-components: x86 -// [WIN32_MSVC] compile-flags: --target i686-pc-windows-msvc -// [WIN32_MSVC] needs-llvm-components: x86 -// [WIN32_GNU] compile-flags: --target i686-pc-windows-gnu -// [WIN32_GNU] needs-llvm-components: x86 +// FIXME: the below revisions are deliberately disabled for now. // revisions: AARCH64 AARCH64_DARWIN AARCH64_MSVC ARM64EC // [AARCH64] compile-flags: --target aarch64-unknown-linux-gnu @@ -108,15 +108,15 @@ pub extern "C" fn cplx_f16(x: Complex) -> Complex { // AARCH64_MSVC: define{{.*}} { half, half } @cplx_f16([2 x half] {{.*}}) // ARM64EC: define{{.*}} { half, half } @cplx_f16([2 x half] {{.*}}) // ARM: define{{.*}} i32 @cplx_f16([1 x i32] {{.*}}) - // I686: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval({ half, half }) {{.*}}) + // I686: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval([4 x i8]) {{.*}}) // LOONGARCH32: define{{.*}} { half, half } @cplx_f16(half {{.*}}, half {{.*}}) // LOONGARCH64: define{{.*}} { half, half } @cplx_f16(half {{.*}}, half {{.*}}) // NVPTX: define{{.*}} { half, half } @cplx_f16(ptr {{.*}} byval({ half, half }) {{.*}}) // RISCV32: define{{.*}} { half, half } @cplx_f16(half {{.*}}, half {{.*}}) // RISCV64: define{{.*}} { half, half } @cplx_f16(half {{.*}}, half {{.*}}) // S390X: define{{.*}} void @cplx_f16(ptr {{.*}} sret({ half, half }) {{.*}}, ptr {{.*}}) - // WIN32_GNU: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval({ half, half }) {{.*}}) - // WIN32_MSVC: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval({ half, half }) {{.*}}) + // WIN32_GNU: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval([4 x i8]) {{.*}}) + // WIN32_MSVC: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval([4 x i8]) {{.*}}) // WINDOWS_GNU: define{{.*}} i32 @cplx_f16(i32 {{.*}}) // WINDOWS_MSVC: define{{.*}} i32 @cplx_f16(i32 {{.*}}) // X86_64: define{{.*}} float @cplx_f16(float {{.*}}) @@ -133,7 +133,7 @@ pub extern "C" fn cplx_f32(x: Complex) -> Complex { // ARM: define{{.*}} { float, float } @cplx_f32({ float, float } {{.*}}) // BPF: define{{.*}} void @cplx_f32(ptr {{.*}} sret({ float, float }) {{.*}}, i64 {{.*}}) // CSKY: define{{.*}} [2 x i32] @cplx_f32([2 x i32] {{.*}}) - // I686: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) + // I686: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval([8 x i8]) {{.*}}) // LOONGARCH32: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) // LOONGARCH64: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) // MIPS64EL: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) @@ -149,8 +149,8 @@ pub extern "C" fn cplx_f32(x: Complex) -> Complex { // SPARC: define{{.*}} { float, float } @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) // WASM32: define{{.*}} void @cplx_f32(ptr {{.*}} sret({ float, float }) {{.*}}, ptr {{.*}} byval({ float, float }) {{.*}}) // WASM64: define{{.*}} void @cplx_f32(ptr {{.*}} sret({ float, float }) {{.*}}, ptr {{.*}} byval({ float, float }) {{.*}}) - // WIN32_GNU: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) - // WIN32_MSVC: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) + // WIN32_GNU: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval([8 x i8]) {{.*}}) + // WIN32_MSVC: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval([8 x i8]) {{.*}}) // WINDOWS_GNU: define{{.*}} i64 @cplx_f32(i64 {{.*}}) // WINDOWS_MSVC: define{{.*}} i64 @cplx_f32(i64 {{.*}}) // X86_64: define{{.*}} double @cplx_f32(double {{.*}}) @@ -167,7 +167,7 @@ pub extern "C" fn cplx_f64(x: Complex) -> Complex { // ARM: define{{.*}} { double, double } @cplx_f64({ double, double } {{.*}}) // BPF: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, [2 x i64] {{.*}}) // CSKY: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, [4 x i32] {{.*}}) - // I686: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) + // I686: define{{.*}} void @cplx_f64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) // LOONGARCH32: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) // LOONGARCH64: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) // MIPS64EL: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) @@ -183,8 +183,8 @@ pub extern "C" fn cplx_f64(x: Complex) -> Complex { // SPARC: define{{.*}} { double, double } @cplx_f64(ptr {{.*}} byval({ double, double }) {{.*}}) // WASM32: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) // WASM64: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) - // WIN32_GNU: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) - // WIN32_MSVC: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) + // WIN32_GNU: define{{.*}} void @cplx_f64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) + // WIN32_MSVC: define{{.*}} void @cplx_f64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) // WINDOWS_GNU: define{{.*}} void @cplx_f64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) // WINDOWS_MSVC: define{{.*}} void @cplx_f64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) // X86_64: define{{.*}} { double, double } @cplx_f64({ double, double } {{.*}}) @@ -193,10 +193,10 @@ pub extern "C" fn cplx_f64(x: Complex) -> Complex { #[no_mangle] pub extern "C" fn cplx_f128(x: Complex) -> Complex { - // I686: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) + // I686: define{{.*}} void @cplx_f128(ptr {{.*}} sret([32 x i8]) {{.*}}, ptr {{.*}} byval([32 x i8]) {{.*}}) // WASM32: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) // WASM64: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) - // WIN32_GNU: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) + // WIN32_GNU: define{{.*}} void @cplx_f128(ptr {{.*}} sret([32 x i8]) {{.*}}, ptr {{.*}} byval([32 x i8]) {{.*}}) // WINDOWS_GNU: define{{.*}} void @cplx_f128(ptr {{.*}} sret([32 x i8]) {{.*}}, ptr {{.*}}) // X86_64: define{{.*}} void @cplx_f128(ptr {{.*}} sret([32 x i8]) {{.*}}, ptr {{.*}} byval([32 x i8]) {{.*}}) x @@ -212,7 +212,7 @@ pub extern "C" fn cplx_i8(x: Complex) -> Complex { // ARM: define{{.*}} i16 @cplx_i8([1 x i32]{{.*}}) // BPF: define{{.*}} void @cplx_i8(ptr {{.*}} sret({ i8, i8 }) {{.*}}, i16 {{.*}}) // CSKY: define{{.*}} {{.*}} i32 @cplx_i8(i32{{.*}}) - // I686: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // I686: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval([2 x i8]) {{.*}}) // LOONGARCH32: define{{.*}} {{.*}} i32 @cplx_i8(i32{{.*}}) // LOONGARCH64: define{{.*}} {{.*}} i64 @cplx_i8(i64{{.*}}) // MIPS64EL: define{{.*}} { i8, i8 } @cplx_i8(i16 {{.*}}) @@ -228,8 +228,8 @@ pub extern "C" fn cplx_i8(x: Complex) -> Complex { // SPARC: define{{.*}} { i8, i8 } @cplx_i8(ptr {{.*}} byval({ i8, i8 }) {{.*}}) // WASM32: define{{.*}} void @cplx_i8(ptr {{.*}} sret({ i8, i8 }) {{.*}}, ptr {{.*}} byval({ i8, i8 }) {{.*}}) // WASM64: define{{.*}} void @cplx_i8(ptr {{.*}} sret({ i8, i8 }) {{.*}}, ptr {{.*}} byval({ i8, i8 }) {{.*}}) - // WIN32_GNU: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval({ i8, i8 }) {{.*}}) - // WIN32_MSVC: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // WIN32_GNU: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval([2 x i8]) {{.*}}) + // WIN32_MSVC: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval([2 x i8]) {{.*}}) // WINDOWS_GNU: define{{.*}} i16 @cplx_i8(i16 {{.*}}) // WINDOWS_MSVC: define{{.*}} i16 @cplx_i8(i16 {{.*}}) // X86_64: define{{.*}} i16 @cplx_i8(i16 {{.*}}) @@ -246,7 +246,7 @@ pub extern "C" fn cplx_i16(x: Complex) -> Complex { // ARM: define{{.*}} i32 @cplx_i16([1 x i32] {{.*}}) // BPF: define{{.*}} void @cplx_i16(ptr {{.*}} sret({ i16, i16 }) {{.*}}, i32 {{.*}}) // CSKY: define{{.*}} i32 @cplx_i16(i32 {{.*}}) - // I686: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // I686: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval([4 x i8]) {{.*}}) // LOONGARCH32: define{{.*}} i32 @cplx_i16(i32 {{.*}}) // LOONGARCH64: define{{.*}} {{.*}} i64 @cplx_i16(i64{{.*}}) // MIPS64EL: define{{.*}} { i16, i16 } @cplx_i16(i32 {{.*}}) @@ -262,8 +262,8 @@ pub extern "C" fn cplx_i16(x: Complex) -> Complex { // SPARC: define{{.*}} { i16, i16 } @cplx_i16(ptr {{.*}} byval({ i16, i16 }) {{.*}}) // WASM32: define{{.*}} void @cplx_i16(ptr {{.*}} sret({ i16, i16 }) {{.*}}, ptr {{.*}} byval({ i16, i16 }) {{.*}}) // WASM64: define{{.*}} void @cplx_i16(ptr {{.*}} sret({ i16, i16 }) {{.*}}, ptr {{.*}} byval({ i16, i16 }) {{.*}}) - // WIN32_GNU: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval({ i16, i16 }) {{.*}}) - // WIN32_MSVC: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // WIN32_GNU: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval([4 x i8]) {{.*}}) + // WIN32_MSVC: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval([4 x i8]) {{.*}}) // WINDOWS_GNU: define{{.*}} i32 @cplx_i16(i32 {{.*}}) // WINDOWS_MSVC: define{{.*}} i32 @cplx_i16(i32 {{.*}}) // X86_64: define{{.*}} i32 @cplx_i16(i32 {{.*}}) @@ -280,7 +280,7 @@ pub extern "C" fn cplx_i32(x: Complex) -> Complex { // ARM: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, [2 x i32] {{.*}}) // BPF: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, i64 {{.*}}) // CSKY: define{{.*}} [2 x i32] @cplx_i32([2 x i32] {{.*}}) - // I686: define{{.*}} i64 @cplx_i32(ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // I686: define{{.*}} i64 @cplx_i32(ptr {{.*}} byval([8 x i8]) {{.*}}) // LOONGARCH32: define{{.*}} [2 x i32] @cplx_i32([2 x i32] {{.*}}) // LOONGARCH64: define{{.*}} i64 @cplx_i32(i64 {{.*}}) // MIPS64EL: define{{.*}} { i32, i32 } @cplx_i32(i64 {{.*}}) @@ -296,8 +296,8 @@ pub extern "C" fn cplx_i32(x: Complex) -> Complex { // SPARC: define{{.*}} { i32, i32 } @cplx_i32(ptr {{.*}} byval({ i32, i32 }) {{.*}}) // WASM32: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, ptr {{.*}} byval({ i32, i32 }) {{.*}}) // WASM64: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, ptr {{.*}} byval({ i32, i32 }) {{.*}}) - // WIN32_GNU: define{{.*}} i64 @cplx_i32(ptr {{.*}} byval({ i32, i32 }) {{.*}}) - // WIN32_MSVC: define{{.*}} i64 @cplx_i32(ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // WIN32_GNU: define{{.*}} i64 @cplx_i32(ptr {{.*}} byval([8 x i8]) {{.*}}) + // WIN32_MSVC: define{{.*}} i64 @cplx_i32(ptr {{.*}} byval([8 x i8]) {{.*}}) // WINDOWS_GNU: define{{.*}} i64 @cplx_i32(i64 {{.*}}) // WINDOWS_MSVC: define{{.*}} i64 @cplx_i32(i64 {{.*}}) // X86_64: define{{.*}} i64 @cplx_i32(i64 {{.*}}) @@ -314,7 +314,7 @@ pub extern "C" fn cplx_i64(x: Complex) -> Complex { // ARM: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, [2 x i64] {{.*}}) // BPF: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, [2 x i64] {{.*}}) // CSKY: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, [4 x i32] {{.*}}) - // I686: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // I686: define{{.*}} void @cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) // LOONGARCH32: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}}) // LOONGARCH64: define{{.*}} [2 x i64] @cplx_i64([2 x i64] {{.*}}) // MIPS64EL: define{{.*}} { i64, i64 } @cplx_i64(i64 {{.*}}, i64 {{.*}}) @@ -330,8 +330,8 @@ pub extern "C" fn cplx_i64(x: Complex) -> Complex { // SPARC: define{{.*}} { i64, i64 } @cplx_i64(ptr {{.*}} byval({ i64, i64 }) {{.*}}) // WASM32: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) // WASM64: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) - // WIN32_GNU: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) - // WIN32_MSVC: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // WIN32_GNU: define{{.*}} void @cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) + // WIN32_MSVC: define{{.*}} void @cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) // WINDOWS_GNU: define{{.*}} void @cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) // WINDOWS_MSVC: define{{.*}} void @cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) // X86_64: define{{.*}} { i64, i64 } @cplx_i64({ i64, i64 } {{.*}}) From fd86d6de55128f9faf2457ca3bfdb8b9358d14df Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 7 Jul 2026 16:50:00 +0000 Subject: [PATCH 16/18] x86_64-win: Enable f128 on LLVM 23+ LLVM23 includes the ABI fix to make f128 work [1]. That version isn't yet stable, but at least the type will start getting picked up in top-of-tree CI. While addressing this, also update the comment regarding f16. [1]: https://github.com/llvm/llvm-project/commit/aa47e59245e24edb6d0c7d5f91b3a1c5a7bb35f1 --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index feccbd953cc1c..298b58dd0007f 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -374,7 +374,8 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { cfg.has_reliable_f16 = match (target_arch, target_os) { // Unsupported (fixed in llvm22) (Arch::Arm64EC, _) if major < 22 => false, - // MinGW ABI bugs + // MinGW ABI bugs resolved in GCC 16 + // but our toolchain hasn't been updated. (Arch::X86_64, Os::Windows) if *target_env == Env::Gnu && *target_abi != CfgAbi::Llvm => { false } @@ -401,8 +402,10 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { (Arch::PowerPC | Arch::PowerPC64, _) => false, // ABI unsupported (fixed in llvm22) (Arch::Sparc, _) if major < 22 => false, - // MinGW ABI bugs - (Arch::X86_64, Os::Windows) if *target_env == Env::Gnu && *target_abi != CfgAbi::Llvm => { + // MinGW ABI bugs (fixed in llvm23) + (Arch::X86_64, Os::Windows) + if *target_env == Env::Gnu && *target_abi != CfgAbi::Llvm && major < 23 => + { false } // There are no known problems on other platforms, so the only requirement is that symbols From 55650a293fdde121b7b766e403035a6f606bb522 Mon Sep 17 00:00:00 2001 From: Yukang Date: Thu, 13 Aug 2026 09:46:31 +0800 Subject: [PATCH 17/18] Add regression test for try block label suggestions --- .../invalid-label-suggestion-issue-160987.rs | 14 ++++++++++++++ .../invalid-label-suggestion-issue-160987.stderr | 15 +++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 tests/ui/try-block/invalid-label-suggestion-issue-160987.rs create mode 100644 tests/ui/try-block/invalid-label-suggestion-issue-160987.stderr diff --git a/tests/ui/try-block/invalid-label-suggestion-issue-160987.rs b/tests/ui/try-block/invalid-label-suggestion-issue-160987.rs new file mode 100644 index 0000000000000..01e03bc03e9e7 --- /dev/null +++ b/tests/ui/try-block/invalid-label-suggestion-issue-160987.rs @@ -0,0 +1,14 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/160987. +//! A label suggested for a try block must use valid syntax. + +//@ edition: 2024 + +#![feature(try_blocks)] + +fn main() { + try { + break; + //~^ ERROR `break` outside of a loop or labeled block + None?; + }; +} diff --git a/tests/ui/try-block/invalid-label-suggestion-issue-160987.stderr b/tests/ui/try-block/invalid-label-suggestion-issue-160987.stderr new file mode 100644 index 0000000000000..4d539e176a453 --- /dev/null +++ b/tests/ui/try-block/invalid-label-suggestion-issue-160987.stderr @@ -0,0 +1,15 @@ +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/invalid-label-suggestion-issue-160987.rs:10:9 + | +LL | break; + | ^^^^^ cannot `break` outside of a loop or labeled block + | +help: consider labeling this block to be able to break within it + | +LL ~ try 'block: { +LL ~ break 'block; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0268`. From 54a639147e9700f9b4f3d4b0d8502f6771db8102 Mon Sep 17 00:00:00 2001 From: Yukang Date: Thu, 13 Aug 2026 10:20:09 +0800 Subject: [PATCH 18/18] Fix invalid suggestion from try unlabled block --- compiler/rustc_hir_typeck/src/diagnostics.rs | 5 +++- compiler/rustc_hir_typeck/src/loops.rs | 29 ++++++++++++++----- ...nvalid-label-suggestion-issue-160987.fixed | 16 ++++++++++ .../invalid-label-suggestion-issue-160987.rs | 2 ++ ...valid-label-suggestion-issue-160987.stderr | 7 +++-- 5 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 tests/ui/try-block/invalid-label-suggestion-issue-160987.fixed diff --git a/compiler/rustc_hir_typeck/src/diagnostics.rs b/compiler/rustc_hir_typeck/src/diagnostics.rs index 722dfb0794ec1..fd74693e7f9fb 100644 --- a/compiler/rustc_hir_typeck/src/diagnostics.rs +++ b/compiler/rustc_hir_typeck/src/diagnostics.rs @@ -819,10 +819,13 @@ pub(crate) struct OutsideLoop<'a> { applicability = "maybe-incorrect" )] pub(crate) struct OutsideLoopSuggestion { - #[suggestion_part(code = "'block: ")] + #[suggestion_part(code = "{block_prefix}")] pub block_span: Span, #[suggestion_part(code = " 'block")] pub break_spans: Vec, + #[suggestion_part(code = " }}")] + pub wrap_end: Option, + pub block_prefix: &'static str, } #[derive(Diagnostic)] diff --git a/compiler/rustc_hir_typeck/src/loops.rs b/compiler/rustc_hir_typeck/src/loops.rs index 21aad64f58d38..ea01744d5b64e 100644 --- a/compiler/rustc_hir_typeck/src/loops.rs +++ b/compiler/rustc_hir_typeck/src/loops.rs @@ -31,7 +31,10 @@ enum Context { kind: hir::CoroutineDesugaring, source: hir::CoroutineSource, }, - UnlabeledBlock(Span), + UnlabeledBlock { + label_span: Span, + wrap_end: Option, + }, UnlabeledIfBlock(Span), LabeledBlock, /// E.g. The labeled block inside `['_'; 'block: { break 'block 1 + 2; }]`. @@ -50,6 +53,7 @@ struct BlockInfo { name: String, spans: Vec, suggs: Vec, + wrap_end: Option, } #[derive(PartialEq)] @@ -118,7 +122,7 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> { ck_loop.cx_stack.last(), Some(&Normal) | Some(&AnonConst) - | Some(&UnlabeledBlock(_)) + | Some(&UnlabeledBlock { .. }) | Some(&UnlabeledIfBlock(_)) ) { @@ -177,10 +181,16 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> { None, ) if matches!( self.cx_stack.last(), - Some(&Normal) | Some(&AnonConst) | Some(&UnlabeledBlock(_)) + Some(&Normal) | Some(&AnonConst) | Some(&UnlabeledBlock { .. }) ) => { - self.with_context(UnlabeledBlock(b.span.shrink_to_lo()), |v| v.visit_block(b)); + // An unlabeled block targeted by `break` may comes from a `try` block. + // Since `try 'block: {}` is invalid, nest a labeled block inside its body. + let wrap_end = b.targeted_by_break.then(|| b.span.shrink_to_hi()); + self.with_context( + UnlabeledBlock { label_span: b.span.shrink_to_lo(), wrap_end }, + |v| v.visit_block(b), + ); } hir::ExprKind::Break(break_destination, ref opt_expr) => { if let Some(e) = opt_expr { @@ -365,13 +375,14 @@ impl<'hir> CheckLoopVisitor<'hir> { source, }); } - UnlabeledBlock(block_span) - if br_cx_kind == BreakContextKind::Break && block_span.eq_ctxt(break_span) => + UnlabeledBlock { label_span, wrap_end } + if br_cx_kind == BreakContextKind::Break && label_span.eq_ctxt(break_span) => { - let block = self.block_breaks.entry(block_span).or_insert_with(|| BlockInfo { + let block = self.block_breaks.entry(label_span).or_insert_with(|| BlockInfo { name: br_cx_kind.to_string(), spans: vec![], suggs: vec![], + wrap_end, }); block.spans.push(span); block.suggs.push(break_span); @@ -379,7 +390,7 @@ impl<'hir> CheckLoopVisitor<'hir> { UnlabeledIfBlock(_) if br_cx_kind == BreakContextKind::Break => { self.require_break_cx(br_cx_kind, span, break_span, cx_pos - 1); } - Normal | AnonConst | Fn | UnlabeledBlock(_) | UnlabeledIfBlock(_) | ConstBlock => { + Normal | AnonConst | Fn | UnlabeledBlock { .. } | UnlabeledIfBlock(_) | ConstBlock => { self.tcx.dcx().emit_err(OutsideLoop { spans: vec![span], name: &br_cx_kind.to_string(), @@ -415,6 +426,8 @@ impl<'hir> CheckLoopVisitor<'hir> { suggestion: Some(OutsideLoopSuggestion { block_span: *s, break_spans: block.suggs.clone(), + block_prefix: if block.wrap_end.is_some() { "{ 'block: " } else { "'block: " }, + wrap_end: block.wrap_end, }), }); } diff --git a/tests/ui/try-block/invalid-label-suggestion-issue-160987.fixed b/tests/ui/try-block/invalid-label-suggestion-issue-160987.fixed new file mode 100644 index 0000000000000..c0b9eeb1189e9 --- /dev/null +++ b/tests/ui/try-block/invalid-label-suggestion-issue-160987.fixed @@ -0,0 +1,16 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/160987. +//! A label suggested for a try block must use valid syntax. + +//@ edition: 2024 +//@ run-rustfix + +#![feature(try_blocks)] +#![allow(unreachable_code)] + +fn main() { + try { 'block: { + break 'block; + //~^ ERROR `break` outside of a loop or labeled block + None?; + } }; +} diff --git a/tests/ui/try-block/invalid-label-suggestion-issue-160987.rs b/tests/ui/try-block/invalid-label-suggestion-issue-160987.rs index 01e03bc03e9e7..aab9c98313c91 100644 --- a/tests/ui/try-block/invalid-label-suggestion-issue-160987.rs +++ b/tests/ui/try-block/invalid-label-suggestion-issue-160987.rs @@ -2,8 +2,10 @@ //! A label suggested for a try block must use valid syntax. //@ edition: 2024 +//@ run-rustfix #![feature(try_blocks)] +#![allow(unreachable_code)] fn main() { try { diff --git a/tests/ui/try-block/invalid-label-suggestion-issue-160987.stderr b/tests/ui/try-block/invalid-label-suggestion-issue-160987.stderr index 4d539e176a453..55e57242ac686 100644 --- a/tests/ui/try-block/invalid-label-suggestion-issue-160987.stderr +++ b/tests/ui/try-block/invalid-label-suggestion-issue-160987.stderr @@ -1,13 +1,16 @@ error[E0268]: `break` outside of a loop or labeled block - --> $DIR/invalid-label-suggestion-issue-160987.rs:10:9 + --> $DIR/invalid-label-suggestion-issue-160987.rs:12:9 | LL | break; | ^^^^^ cannot `break` outside of a loop or labeled block | help: consider labeling this block to be able to break within it | -LL ~ try 'block: { +LL ~ try { 'block: { LL ~ break 'block; +LL | +LL | None?; +LL ~ } }; | error: aborting due to 1 previous error