1
Fork 0

Auto merge of #131098 - GuillaumeGomez:rollup-kk74was, r=GuillaumeGomez

Rollup of 5 pull requests

Successful merges:

 - #130630 (Support clobber_abi and vector/access registers (clobber-only) in s390x inline assembly)
 - #131042 (Instantiate binders in `supertrait_vtable_slot`)
 - #131079 (Update wasm-component-ld to 0.5.9)
 - #131085 (make test_lots_of_insertions test take less long in Miri)
 - #131088 (add fixme to remove LLVM_ENABLE_TERMINFO when minimal llvm version is 19)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-10-01 16:32:19 +00:00
commit c817d5dc20
14 changed files with 316 additions and 71 deletions

View file

@ -5768,16 +5768,16 @@ checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
[[package]] [[package]]
name = "wasm-component-ld" name = "wasm-component-ld"
version = "0.5.8" version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb17cdbc91766d4ea0bcd6026c36ba77a21b5c8199aeb1f0993461fe6a6bec2b" checksum = "fde17bc96539700198e12516230c76095cc215c84ef39ad206e1af3f84243e0f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
"lexopt", "lexopt",
"tempfile", "tempfile",
"wasi-preview1-component-adapter-provider", "wasi-preview1-component-adapter-provider",
"wasmparser 0.217.0", "wasmparser 0.218.0",
"wat", "wat",
"wit-component", "wit-component",
"wit-parser", "wit-parser",
@ -5801,19 +5801,19 @@ dependencies = [
[[package]] [[package]]
name = "wasm-encoder" name = "wasm-encoder"
version = "0.217.0" version = "0.218.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b88b0814c9a2b323a9b46c687e726996c255ac8b64aa237dd11c81ed4854760" checksum = "22b896fa8ceb71091ace9bcb81e853f54043183a1c9667cf93422c40252ffa0a"
dependencies = [ dependencies = [
"leb128", "leb128",
"wasmparser 0.217.0", "wasmparser 0.218.0",
] ]
[[package]] [[package]]
name = "wasm-metadata" name = "wasm-metadata"
version = "0.217.0" version = "0.218.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65a146bf9a60e9264f0548a2599aa9656dba9a641eff9ab88299dc2a637e483c" checksum = "aa5eeb071abe8a2132fdd5565dabffee70775ee8c24fc7e300ac43f51f4a8a91"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"indexmap", "indexmap",
@ -5821,8 +5821,8 @@ dependencies = [
"serde_derive", "serde_derive",
"serde_json", "serde_json",
"spdx", "spdx",
"wasm-encoder 0.217.0", "wasm-encoder 0.218.0",
"wasmparser 0.217.0", "wasmparser 0.218.0",
] ]
[[package]] [[package]]
@ -5837,9 +5837,9 @@ dependencies = [
[[package]] [[package]]
name = "wasmparser" name = "wasmparser"
version = "0.217.0" version = "0.218.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca917a21307d3adf2b9857b94dd05ebf8496bdcff4437a9b9fb3899d3e6c74e7" checksum = "b09e46c7fceceaa72b2dd1a8a137ea7fd8f93dfaa69806010a709918e496c5dc"
dependencies = [ dependencies = [
"ahash", "ahash",
"bitflags 2.6.0", "bitflags 2.6.0",
@ -5851,22 +5851,22 @@ dependencies = [
[[package]] [[package]]
name = "wast" name = "wast"
version = "217.0.0" version = "218.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79004ecebded92d3c710d4841383368c7f04b63d0992ddd6b0c7d5029b7629b7" checksum = "8a53cd1f0fa505df97557e36a58bddb8296e2fcdcd089529545ebfdb18a1b9d7"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"leb128", "leb128",
"memchr", "memchr",
"unicode-width", "unicode-width",
"wasm-encoder 0.217.0", "wasm-encoder 0.218.0",
] ]
[[package]] [[package]]
name = "wat" name = "wat"
version = "1.217.0" version = "1.218.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c126271c3d92ca0f7c63e4e462e40c69cca52fd4245fcda730d1cf558fb55088" checksum = "4f87f8e14e776762e07927c27c2054d2cf678aab9aae2d431a79b3e31e4dd391"
dependencies = [ dependencies = [
"wast", "wast",
] ]
@ -6143,9 +6143,9 @@ dependencies = [
[[package]] [[package]]
name = "wit-component" name = "wit-component"
version = "0.217.0" version = "0.218.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7117809905e49db716d81e794f79590c052bf2fdbbcda1731ca0fb28f6f3ddf" checksum = "aa53aa7e6bf2b3e8ccaffbcc963fbdb672a603dc0af393a481b6cec24c266406"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bitflags 2.6.0", "bitflags 2.6.0",
@ -6154,17 +6154,17 @@ dependencies = [
"serde", "serde",
"serde_derive", "serde_derive",
"serde_json", "serde_json",
"wasm-encoder 0.217.0", "wasm-encoder 0.218.0",
"wasm-metadata", "wasm-metadata",
"wasmparser 0.217.0", "wasmparser 0.218.0",
"wit-parser", "wit-parser",
] ]
[[package]] [[package]]
name = "wit-parser" name = "wit-parser"
version = "0.217.0" version = "0.218.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb893dcd6d370cfdf19a0d9adfcd403efb8e544e1a0ea3a8b81a21fe392eaa78" checksum = "0d3d1066ab761b115f97fef2b191090faabcb0f37b555b758d3caf42d4ed9e55"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"id-arena", "id-arena",
@ -6175,7 +6175,7 @@ dependencies = [
"serde_derive", "serde_derive",
"serde_json", "serde_json",
"unicode-xid", "unicode-xid",
"wasmparser 0.217.0", "wasmparser 0.218.0",
] ]
[[package]] [[package]]

View file

@ -682,6 +682,11 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r", InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a", InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a",
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f", InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f",
InlineAsmRegClass::S390x(
S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg,
) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::Err => unreachable!(), InlineAsmRegClass::Err => unreachable!(),
}, },
}; };
@ -757,6 +762,9 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr, S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr,
) => cx.type_i32(), ) => cx.type_i32(),
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(), InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(),
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(), InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(),
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(),
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(), InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(),

View file

@ -708,6 +708,9 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
S390x(S390xInlineAsmRegClass::reg) => "r", S390x(S390xInlineAsmRegClass::reg) => "r",
S390x(S390xInlineAsmRegClass::reg_addr) => "a", S390x(S390xInlineAsmRegClass::reg_addr) => "a",
S390x(S390xInlineAsmRegClass::freg) => "f", S390x(S390xInlineAsmRegClass::freg) => "f",
S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => {
unreachable!("clobber-only")
}
Msp430(Msp430InlineAsmRegClass::reg) => "r", Msp430(Msp430InlineAsmRegClass::reg) => "r",
M68k(M68kInlineAsmRegClass::reg) => "r", M68k(M68kInlineAsmRegClass::reg) => "r",
M68k(M68kInlineAsmRegClass::reg_addr) => "a", M68k(M68kInlineAsmRegClass::reg_addr) => "a",
@ -866,6 +869,9 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
Avr(AvrInlineAsmRegClass::reg_ptr) => cx.type_i16(), Avr(AvrInlineAsmRegClass::reg_ptr) => cx.type_i16(),
S390x(S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr) => cx.type_i32(), S390x(S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr) => cx.type_i32(),
S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(), S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(),
S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => {
unreachable!("clobber-only")
}
Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(), Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(),
M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(), M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(),
M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(), M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(),

View file

@ -411,6 +411,7 @@ symbols! {
arbitrary_enum_discriminant, arbitrary_enum_discriminant,
arbitrary_self_types, arbitrary_self_types,
arbitrary_self_types_pointers, arbitrary_self_types_pointers,
areg,
args, args,
arith_offset, arith_offset,
arm, arm,

View file

@ -439,7 +439,7 @@ impl InlineAsmReg {
Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))), Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))),
Self::LoongArch(_) => cb(self), Self::LoongArch(_) => cb(self),
Self::Mips(_) => cb(self), Self::Mips(_) => cb(self),
Self::S390x(_) => cb(self), Self::S390x(r) => r.overlapping_regs(|r| cb(Self::S390x(r))),
Self::Bpf(r) => r.overlapping_regs(|r| cb(Self::Bpf(r))), Self::Bpf(r) => r.overlapping_regs(|r| cb(Self::Bpf(r))),
Self::Avr(r) => r.overlapping_regs(|r| cb(Self::Avr(r))), Self::Avr(r) => r.overlapping_regs(|r| cb(Self::Avr(r))),
Self::Msp430(_) => cb(self), Self::Msp430(_) => cb(self),
@ -892,6 +892,7 @@ pub enum InlineAsmClobberAbi {
AArch64NoX18, AArch64NoX18,
RiscV, RiscV,
LoongArch, LoongArch,
S390x,
} }
impl InlineAsmClobberAbi { impl InlineAsmClobberAbi {
@ -941,6 +942,10 @@ impl InlineAsmClobberAbi {
"C" | "system" => Ok(InlineAsmClobberAbi::LoongArch), "C" | "system" => Ok(InlineAsmClobberAbi::LoongArch),
_ => Err(&["C", "system"]), _ => Err(&["C", "system"]),
}, },
InlineAsmArch::S390x => match name {
"C" | "system" => Ok(InlineAsmClobberAbi::S390x),
_ => Err(&["C", "system"]),
},
_ => Err(&[]), _ => Err(&[]),
} }
} }
@ -1098,6 +1103,28 @@ impl InlineAsmClobberAbi {
f16, f17, f18, f19, f20, f21, f22, f23, f16, f17, f18, f19, f20, f21, f22, f23,
} }
}, },
InlineAsmClobberAbi::S390x => clobbered_regs! {
S390x S390xInlineAsmReg {
r0, r1, r2, r3, r4, r5,
r14,
// f0-f7, v0-v7
f0, f1, f2, f3, f4, f5, f6, f7,
v0, v1, v2, v3, v4, v5, v6, v7,
// Technically the left halves of v8-v15 (i.e., f8-f15) are saved, but
// we have no way of expressing this using clobbers.
v8, v9, v10, v11, v12, v13, v14, v15,
// Other vector registers are volatile
v16, v17, v18, v19, v20, v21, v22, v23,
v24, v25, v26, v27, v28, v29, v30, v31,
// a0-a1 are reserved, other access registers are volatile
a2, a3, a4, a5, a6, a7,
a8, a9, a10, a11, a12, a13, a14, a15,
}
},
} }
} }
} }

View file

@ -9,6 +9,8 @@ def_reg_class! {
reg, reg,
reg_addr, reg_addr,
freg, freg,
vreg,
areg,
} }
} }
@ -35,11 +37,13 @@ impl S390xInlineAsmRegClass {
pub fn supported_types( pub fn supported_types(
self, self,
arch: InlineAsmArch, _arch: InlineAsmArch,
) -> &'static [(InlineAsmType, Option<Symbol>)] { ) -> &'static [(InlineAsmType, Option<Symbol>)] {
match (self, arch) { match self {
(Self::reg | Self::reg_addr, _) => types! { _: I8, I16, I32, I64; }, Self::reg | Self::reg_addr => types! { _: I8, I16, I32, I64; },
(Self::freg, _) => types! { _: F32, F64; }, Self::freg => types! { _: F32, F64; },
Self::vreg => &[],
Self::areg => &[],
} }
} }
} }
@ -76,6 +80,52 @@ def_regs! {
f13: freg = ["f13"], f13: freg = ["f13"],
f14: freg = ["f14"], f14: freg = ["f14"],
f15: freg = ["f15"], f15: freg = ["f15"],
v0: vreg = ["v0"],
v1: vreg = ["v1"],
v2: vreg = ["v2"],
v3: vreg = ["v3"],
v4: vreg = ["v4"],
v5: vreg = ["v5"],
v6: vreg = ["v6"],
v7: vreg = ["v7"],
v8: vreg = ["v8"],
v9: vreg = ["v9"],
v10: vreg = ["v10"],
v11: vreg = ["v11"],
v12: vreg = ["v12"],
v13: vreg = ["v13"],
v14: vreg = ["v14"],
v15: vreg = ["v15"],
v16: vreg = ["v16"],
v17: vreg = ["v17"],
v18: vreg = ["v18"],
v19: vreg = ["v19"],
v20: vreg = ["v20"],
v21: vreg = ["v21"],
v22: vreg = ["v22"],
v23: vreg = ["v23"],
v24: vreg = ["v24"],
v25: vreg = ["v25"],
v26: vreg = ["v26"],
v27: vreg = ["v27"],
v28: vreg = ["v28"],
v29: vreg = ["v29"],
v30: vreg = ["v30"],
v31: vreg = ["v31"],
a2: areg = ["a2"],
a3: areg = ["a3"],
a4: areg = ["a4"],
a5: areg = ["a5"],
a6: areg = ["a6"],
a7: areg = ["a7"],
a8: areg = ["a8"],
a9: areg = ["a9"],
a10: areg = ["a10"],
a11: areg = ["a11"],
a12: areg = ["a12"],
a13: areg = ["a13"],
a14: areg = ["a14"],
a15: areg = ["a15"],
#error = ["r11"] => #error = ["r11"] =>
"The frame pointer cannot be used as an operand for inline asm", "The frame pointer cannot be used as an operand for inline asm",
#error = ["r15"] => #error = ["r15"] =>
@ -87,13 +137,8 @@ def_regs! {
"c12", "c13", "c14", "c15" "c12", "c13", "c14", "c15"
] => ] =>
"control registers are reserved by the kernel and cannot be used as operands for inline asm", "control registers are reserved by the kernel and cannot be used as operands for inline asm",
#error = [ #error = ["a0", "a1"] =>
"a0", "a1", "a2", "a3", "a0 and a1 are reserved for system use and cannot be used as operands for inline asm",
"a4", "a5", "a6", "a7",
"a8", "a9", "a10", "a11",
"a12", "a13", "a14", "a15"
] =>
"access registers are not supported and cannot be used as operands for inline asm",
} }
} }
@ -106,4 +151,48 @@ impl S390xInlineAsmReg {
) -> fmt::Result { ) -> fmt::Result {
write!(out, "%{}", self.name()) write!(out, "%{}", self.name())
} }
pub fn overlapping_regs(self, mut cb: impl FnMut(S390xInlineAsmReg)) {
macro_rules! reg_conflicts {
(
$(
$full:ident : $($field:ident)*
),*;
) => {
match self {
$(
Self::$full => {
cb(Self::$full);
$(cb(Self::$field);)*
}
$(Self::$field)|* => {
cb(Self::$full);
cb(self);
}
)*
r => cb(r),
}
};
}
// The left halves of v0-v15 are aliased to f0-f15.
reg_conflicts! {
v0 : f0,
v1 : f1,
v2 : f2,
v3 : f3,
v4 : f4,
v5 : f5,
v6 : f6,
v7 : f7,
v8 : f8,
v9 : f9,
v10 : f10,
v11 : f11,
v12 : f12,
v13 : f13,
v14 : f14,
v15 : f15;
}
}
} }

View file

@ -9,12 +9,13 @@ use rustc_infer::infer::canonical::{
Canonical, CanonicalQueryResponse, CanonicalVarValues, QueryResponse, Canonical, CanonicalQueryResponse, CanonicalVarValues, QueryResponse,
}; };
use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk, RegionResolutionError}; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk, RegionResolutionError, TypeTrace};
use rustc_macros::extension; use rustc_macros::extension;
use rustc_middle::arena::ArenaAllocatable; use rustc_middle::arena::ArenaAllocatable;
use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::query::NoSolution;
use rustc_middle::ty::error::TypeError; use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast, Variance}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast, Variance};
use rustc_type_ir::relate::Relate;
use super::{FromSolverError, FulfillmentContext, ScrubbedTraitError, TraitEngine}; use super::{FromSolverError, FulfillmentContext, ScrubbedTraitError, TraitEngine};
use crate::error_reporting::InferCtxtErrorExt; use crate::error_reporting::InferCtxtErrorExt;
@ -133,6 +134,20 @@ where
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
} }
pub fn eq_trace<T: Relate<TyCtxt<'tcx>>>(
&self,
cause: &ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
trace: TypeTrace<'tcx>,
expected: T,
actual: T,
) -> Result<(), TypeError<'tcx>> {
self.infcx
.at(cause, param_env)
.eq_trace(DefineOpaqueTypes::Yes, trace, expected, actual)
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
}
/// Checks whether `expected` is a subtype of `actual`: `expected <: actual`. /// Checks whether `expected` is a subtype of `actual`: `expected <: actual`.
pub fn sub<T: ToTrace<'tcx>>( pub fn sub<T: ToTrace<'tcx>>(
&self, &self,

View file

@ -2,6 +2,9 @@ use std::fmt::Debug;
use std::ops::ControlFlow; use std::ops::ControlFlow;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_infer::infer::at::ToTrace;
use rustc_infer::infer::{BoundRegionConversionTime, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause;
use rustc_infer::traits::util::PredicateSet; use rustc_infer::traits::util::PredicateSet;
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::query::Providers; use rustc_middle::query::Providers;
@ -13,7 +16,7 @@ use smallvec::{SmallVec, smallvec};
use tracing::debug; use tracing::debug;
use crate::errors::DumpVTableEntries; use crate::errors::DumpVTableEntries;
use crate::traits::{impossible_predicates, is_vtable_safe_method}; use crate::traits::{ObligationCtxt, impossible_predicates, is_vtable_safe_method};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum VtblSegment<'tcx> { pub enum VtblSegment<'tcx> {
@ -22,6 +25,8 @@ pub enum VtblSegment<'tcx> {
} }
/// Prepare the segments for a vtable /// Prepare the segments for a vtable
// FIXME: This should take a `PolyExistentialTraitRef`, since we don't care
// about our `Self` type here.
pub fn prepare_vtable_segments<'tcx, T>( pub fn prepare_vtable_segments<'tcx, T>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>,
@ -327,14 +332,10 @@ pub(crate) fn first_method_vtable_slot<'tcx>(tcx: TyCtxt<'tcx>, key: ty::TraitRe
let ty::Dynamic(source, _, _) = *key.self_ty().kind() else { let ty::Dynamic(source, _, _) = *key.self_ty().kind() else {
bug!(); bug!();
}; };
let source_principal = tcx let source_principal =
.normalize_erasing_regions(ty::ParamEnv::reveal_all(), source.principal().unwrap()) source.principal().unwrap().with_self_ty(tcx, tcx.types.trait_object_dummy_self);
.with_self_ty(tcx, tcx.types.trait_object_dummy_self);
let target_principal = tcx let target_principal = ty::Binder::dummy(ty::ExistentialTraitRef::erase_self_ty(tcx, key));
.normalize_erasing_regions(ty::ParamEnv::reveal_all(), key)
// We don't care about the self type, since it will always be the same thing.
.with_self_ty(tcx, tcx.types.trait_object_dummy_self);
let vtable_segment_callback = { let vtable_segment_callback = {
let mut vptr_offset = 0; let mut vptr_offset = 0;
@ -343,15 +344,18 @@ pub(crate) fn first_method_vtable_slot<'tcx>(tcx: TyCtxt<'tcx>, key: ty::TraitRe
VtblSegment::MetadataDSA => { VtblSegment::MetadataDSA => {
vptr_offset += TyCtxt::COMMON_VTABLE_ENTRIES.len(); vptr_offset += TyCtxt::COMMON_VTABLE_ENTRIES.len();
} }
VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => { VtblSegment::TraitOwnEntries { trait_ref: vtable_principal, emit_vptr } => {
if tcx if trait_refs_are_compatible(
.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), trait_ref) tcx,
== target_principal vtable_principal
{ .map_bound(|t| ty::ExistentialTraitRef::erase_self_ty(tcx, t)),
target_principal,
) {
return ControlFlow::Break(vptr_offset); return ControlFlow::Break(vptr_offset);
} }
vptr_offset += tcx.own_existential_vtable_entries(trait_ref.def_id()).len(); vptr_offset +=
tcx.own_existential_vtable_entries(vtable_principal.def_id()).len();
if emit_vptr { if emit_vptr {
vptr_offset += 1; vptr_offset += 1;
@ -383,17 +387,14 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
let ty::Dynamic(target, _, _) = *target.kind() else { let ty::Dynamic(target, _, _) = *target.kind() else {
bug!(); bug!();
}; };
let target_principal = tcx let target_principal = target.principal()?;
.normalize_erasing_regions(ty::ParamEnv::reveal_all(), target.principal()?)
.with_self_ty(tcx, tcx.types.trait_object_dummy_self);
// Given that we have a target principal, it is a bug for there not to be a source principal. // Given that we have a target principal, it is a bug for there not to be a source principal.
let ty::Dynamic(source, _, _) = *source.kind() else { let ty::Dynamic(source, _, _) = *source.kind() else {
bug!(); bug!();
}; };
let source_principal = tcx let source_principal =
.normalize_erasing_regions(ty::ParamEnv::reveal_all(), source.principal().unwrap()) source.principal().unwrap().with_self_ty(tcx, tcx.types.trait_object_dummy_self);
.with_self_ty(tcx, tcx.types.trait_object_dummy_self);
let vtable_segment_callback = { let vtable_segment_callback = {
let mut vptr_offset = 0; let mut vptr_offset = 0;
@ -402,11 +403,15 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
VtblSegment::MetadataDSA => { VtblSegment::MetadataDSA => {
vptr_offset += TyCtxt::COMMON_VTABLE_ENTRIES.len(); vptr_offset += TyCtxt::COMMON_VTABLE_ENTRIES.len();
} }
VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => { VtblSegment::TraitOwnEntries { trait_ref: vtable_principal, emit_vptr } => {
vptr_offset += tcx.own_existential_vtable_entries(trait_ref.def_id()).len(); vptr_offset +=
if tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), trait_ref) tcx.own_existential_vtable_entries(vtable_principal.def_id()).len();
== target_principal if trait_refs_are_compatible(
{ tcx,
vtable_principal
.map_bound(|t| ty::ExistentialTraitRef::erase_self_ty(tcx, t)),
target_principal,
) {
if emit_vptr { if emit_vptr {
return ControlFlow::Break(Some(vptr_offset)); return ControlFlow::Break(Some(vptr_offset));
} else { } else {
@ -426,6 +431,41 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
prepare_vtable_segments(tcx, source_principal, vtable_segment_callback).unwrap() prepare_vtable_segments(tcx, source_principal, vtable_segment_callback).unwrap()
} }
fn trait_refs_are_compatible<'tcx>(
tcx: TyCtxt<'tcx>,
hr_vtable_principal: ty::PolyExistentialTraitRef<'tcx>,
hr_target_principal: ty::PolyExistentialTraitRef<'tcx>,
) -> bool {
if hr_vtable_principal.def_id() != hr_target_principal.def_id() {
return false;
}
let infcx = tcx.infer_ctxt().build();
let param_env = ty::ParamEnv::reveal_all();
let ocx = ObligationCtxt::new(&infcx);
let hr_source_principal =
ocx.normalize(&ObligationCause::dummy(), param_env, hr_vtable_principal);
let hr_target_principal =
ocx.normalize(&ObligationCause::dummy(), param_env, hr_target_principal);
infcx.enter_forall(hr_target_principal, |target_principal| {
let source_principal = infcx.instantiate_binder_with_fresh_vars(
DUMMY_SP,
BoundRegionConversionTime::HigherRankedType,
hr_source_principal,
);
let Ok(()) = ocx.eq_trace(
&ObligationCause::dummy(),
param_env,
ToTrace::to_trace(&ObligationCause::dummy(), hr_target_principal, hr_source_principal),
target_principal,
source_principal,
) else {
return false;
};
ocx.select_all_or_error().is_empty()
})
}
pub(super) fn provide(providers: &mut Providers) { pub(super) fn provide(providers: &mut Providers) {
*providers = Providers { *providers = Providers {
own_existential_vtable_entries, own_existential_vtable_entries,

View file

@ -274,7 +274,7 @@ fn test_lots_of_insertions() {
for _ in 0..loops { for _ in 0..loops {
assert!(m.is_empty()); assert!(m.is_empty());
let count = if cfg!(miri) { 101 } else { 1001 }; let count = if cfg!(miri) { 66 } else { 1001 };
for i in 1..count { for i in 1..count {
assert!(m.insert(i, i).is_none()); assert!(m.insert(i, i).is_none());

View file

@ -344,6 +344,7 @@ impl Step for Llvm {
.define("LLVM_INCLUDE_DOCS", "OFF") .define("LLVM_INCLUDE_DOCS", "OFF")
.define("LLVM_INCLUDE_BENCHMARKS", "OFF") .define("LLVM_INCLUDE_BENCHMARKS", "OFF")
.define("LLVM_INCLUDE_TESTS", enable_tests) .define("LLVM_INCLUDE_TESTS", enable_tests)
// FIXME: remove this when minimal llvm is 19
.define("LLVM_ENABLE_TERMINFO", "OFF") .define("LLVM_ENABLE_TERMINFO", "OFF")
.define("LLVM_ENABLE_LIBEDIT", "OFF") .define("LLVM_ENABLE_LIBEDIT", "OFF")
.define("LLVM_ENABLE_BINDINGS", "OFF") .define("LLVM_ENABLE_BINDINGS", "OFF")

View file

@ -51,7 +51,10 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
| CSKY | `reg` | `r[0-31]` | `r` | | CSKY | `reg` | `r[0-31]` | `r` |
| CSKY | `freg` | `f[0-31]` | `f` | | CSKY | `freg` | `f[0-31]` | `f` |
| s390x | `reg` | `r[0-10]`, `r[12-14]` | `r` | | s390x | `reg` | `r[0-10]`, `r[12-14]` | `r` |
| s390x | `reg_addr` | `r[1-10]`, `r[12-14]` | `a` |
| s390x | `freg` | `f[0-15]` | `f` | | s390x | `freg` | `f[0-15]` | `f` |
| s390x | `vreg` | `v[0-31]` | Only clobbers |
| s390x | `areg` | `a[2-15]` | Only clobbers |
| Arm64EC | `reg` | `x[0-12]`, `x[15-22]`, `x[25-27]`, `x30` | `r` | | Arm64EC | `reg` | `x[0-12]`, `x[15-22]`, `x[25-27]`, `x30` | `r` |
| Arm64EC | `vreg` | `v[0-15]` | `w` | | Arm64EC | `vreg` | `v[0-15]` | `w` |
| Arm64EC | `vreg_low16` | `v[0-15]` | `x` | | Arm64EC | `vreg_low16` | `v[0-15]` | `x` |
@ -90,6 +93,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
| CSKY | `freg` | None | `f32`, | | CSKY | `freg` | None | `f32`, |
| s390x | `reg`, `reg_addr` | None | `i8`, `i16`, `i32`, `i64` | | s390x | `reg`, `reg_addr` | None | `i8`, `i16`, `i32`, `i64` |
| s390x | `freg` | None | `f32`, `f64` | | s390x | `freg` | None | `f32`, `f64` |
| s390x | `vreg` | N/A | Only clobbers |
| s390x | `areg` | N/A | Only clobbers |
| Arm64EC | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` | | Arm64EC | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
| Arm64EC | `vreg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64`, <br> `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2`, `f64x1`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | | Arm64EC | `vreg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64`, <br> `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2`, `f64x1`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` |
@ -157,6 +162,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
| CSKY | `r15` | This is the link register. | | CSKY | `r15` | This is the link register. |
| CSKY | `r[26-30]` | Reserved by its ABI. | | CSKY | `r[26-30]` | Reserved by its ABI. |
| CSKY | `r31` | This is the TLS register. | | CSKY | `r31` | This is the TLS register. |
| s390x | `c[0-15]` | Reserved by the kernel. |
| s390x | `a[0-1]` | Reserved for system use. |
| Arm64EC | `xzr` | This is a constant zero register which can't be modified. | | Arm64EC | `xzr` | This is a constant zero register which can't be modified. |
| Arm64EC | `x18` | This is an OS-reserved register. | | Arm64EC | `x18` | This is an OS-reserved register. |
| Arm64EC | `x13`, `x14`, `x23`, `x24`, `x28`, `v[16-31]` | These are AArch64 registers that are not supported for Arm64EC. | | Arm64EC | `x13`, `x14`, `x23`, `x24`, `x28`, `v[16-31]` | These are AArch64 registers that are not supported for Arm64EC. |

View file

@ -10,4 +10,4 @@ name = "wasm-component-ld"
path = "src/main.rs" path = "src/main.rs"
[dependencies] [dependencies]
wasm-component-ld = "0.5.4" wasm-component-ld = "0.5.9"

View file

@ -0,0 +1,50 @@
//@ revisions: s390x
//@[s390x] compile-flags: --target s390x-unknown-linux-gnu
//@[s390x] needs-llvm-components: systemz
#![crate_type = "rlib"]
#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)]
#![no_core]
#[lang = "sized"]
trait Sized {}
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
// CHECK-LABEL: @cc_clobber
// CHECK: call void asm sideeffect "", "~{cc}"()
#[no_mangle]
pub unsafe fn cc_clobber() {
asm!("", options(nostack, nomem));
}
// CHECK-LABEL: @no_clobber
// CHECK: call void asm sideeffect "", ""()
#[no_mangle]
pub unsafe fn no_clobber() {
asm!("", options(nostack, nomem, preserves_flags));
}
// CHECK-LABEL: @a2_clobber
// CHECK: call void asm sideeffect "", "~{a2}"()
#[no_mangle]
pub unsafe fn a2_clobber() {
asm!("", out("a2") _, options(nostack, nomem, preserves_flags));
}
// CHECK-LABEL: @v0_clobber
// CHECK: call void asm sideeffect "", "~{v0}"()
#[no_mangle]
pub unsafe fn v0_clobber() {
asm!("", out("v0") _, options(nostack, nomem, preserves_flags));
}
// CHECK-LABEL: @clobber_abi
// CHECK: asm sideeffect "", "={r0},={r1},={r2},={r3},={r4},={r5},={r14},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31},~{a2},~{a3},~{a4},~{a5},~{a6},~{a7},~{a8},~{a9},~{a10},~{a11},~{a12},~{a13},~{a14},~{a15}"()
#[no_mangle]
pub unsafe fn clobber_abi() {
asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
}

View file

@ -1,21 +1,22 @@
//@ revisions: current next //@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions) //@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver //@[next] compile-flags: -Znext-solver
//@ check-pass //@ build-pass
// We should be able to instantiate a binder during trait upcasting. // Check that we are able to instantiate a binder during trait upcasting,
// This test could be `check-pass`, but we should make sure that we // and that it doesn't cause any issues with codegen either.
// do so in both trait solvers.
#![feature(trait_upcasting)] #![feature(trait_upcasting)]
trait Supertrait<'a, 'b> {} trait Supertrait<'a, 'b> {}
trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {} trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {}
impl<'a> Supertrait<'a, 'a> for () {} impl Supertrait<'_, '_> for () {}
impl<'a> Subtrait<'a, 'a> for () {} impl Subtrait<'_, '_> for () {}
fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> { fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> {
x x
} }
fn main() {} fn main() {
ok(&());
}