Remove all support for wasm's legacy ABI

This commit is contained in:
bjorn3 2024-12-06 09:06:51 +00:00
parent 64033a4ee5
commit 3e944fa391
19 changed files with 28 additions and 481 deletions

View file

@ -30,7 +30,7 @@ use rustc_middle::ty::{self, AtomicOrdering, Instance, Ty, TyCtxt};
use rustc_span::Span;
use rustc_span::def_id::DefId;
use rustc_target::callconv::FnAbi;
use rustc_target::spec::{HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, Target, WasmCAbi, X86Abi};
use rustc_target::spec::{HasTargetSpec, HasX86AbiOpt, Target, X86Abi};
use crate::common::{SignType, TypeReflection, type_is_pointer};
use crate::context::CodegenCx;
@ -2394,12 +2394,6 @@ impl<'tcx> HasTargetSpec for Builder<'_, '_, 'tcx> {
}
}
impl<'tcx> HasWasmCAbiOpt for Builder<'_, '_, 'tcx> {
fn wasm_c_abi_opt(&self) -> WasmCAbi {
self.cx.wasm_c_abi_opt()
}
}
impl<'tcx> HasX86AbiOpt for Builder<'_, '_, 'tcx> {
fn x86_abi_opt(&self) -> X86Abi {
self.cx.x86_abi_opt()

View file

@ -19,9 +19,7 @@ use rustc_middle::ty::{self, ExistentialTraitRef, Instance, Ty, TyCtxt};
use rustc_session::Session;
use rustc_span::source_map::respan;
use rustc_span::{DUMMY_SP, Span};
use rustc_target::spec::{
HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, Target, TlsModel, WasmCAbi, X86Abi,
};
use rustc_target::spec::{HasTargetSpec, HasX86AbiOpt, Target, TlsModel, X86Abi};
#[cfg(feature = "master")]
use crate::abi::conv_to_fn_attribute;
@ -512,12 +510,6 @@ impl<'gcc, 'tcx> HasTargetSpec for CodegenCx<'gcc, 'tcx> {
}
}
impl<'gcc, 'tcx> HasWasmCAbiOpt for CodegenCx<'gcc, 'tcx> {
fn wasm_c_abi_opt(&self) -> WasmCAbi {
self.tcx.sess.opts.unstable_opts.wasm_c_abi
}
}
impl<'gcc, 'tcx> HasX86AbiOpt for CodegenCx<'gcc, 'tcx> {
fn x86_abi_opt(&self) -> X86Abi {
X86Abi {

View file

@ -1,14 +1,13 @@
use rustc_abi::{BackendRepr, Float, Integer, Primitive, RegKind};
use rustc_attr_data_structures::InstructionSetAttr;
use rustc_hir::def_id::DefId;
use rustc_middle::mir::mono::{Linkage, MonoItemData, Visibility};
use rustc_middle::mir::{InlineAsmOperand, START_BLOCK};
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
use rustc_middle::ty::{Instance, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::{bug, span_bug, ty};
use rustc_middle::{bug, ty};
use rustc_span::sym;
use rustc_target::callconv::{ArgAbi, FnAbi, PassMode};
use rustc_target::spec::{BinaryFormat, WasmCAbi};
use rustc_target::spec::BinaryFormat;
use crate::common;
use crate::mir::AsmCodegenMethods;
@ -287,12 +286,7 @@ fn prefix_and_suffix<'tcx>(
writeln!(begin, "{}", arch_prefix).unwrap();
}
writeln!(begin, "{asm_name}:").unwrap();
writeln!(
begin,
".functype {asm_name} {}",
wasm_functype(tcx, fn_abi, instance.def_id())
)
.unwrap();
writeln!(begin, ".functype {asm_name} {}", wasm_functype(tcx, fn_abi)).unwrap();
writeln!(end).unwrap();
// .size is ignored for function symbols, so we can skip it
@ -333,7 +327,7 @@ fn prefix_and_suffix<'tcx>(
/// The webassembly type signature for the given function.
///
/// Used by the `.functype` directive on wasm targets.
fn wasm_functype<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, def_id: DefId) -> String {
fn wasm_functype<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> String {
let mut signature = String::with_capacity(64);
let ptr_type = match tcx.data_layout.pointer_size.bits() {
@ -342,17 +336,6 @@ fn wasm_functype<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, def_id
other => bug!("wasm pointer size cannot be {other} bits"),
};
// FIXME: remove this once the wasm32-unknown-unknown ABI is fixed
// please also add `wasm32-unknown-unknown` back in `tests/assembly/wasm32-naked-fn.rs`
// basically the commit introducing this comment should be reverted
if let PassMode::Pair { .. } = fn_abi.ret.mode {
let _ = WasmCAbi::Legacy { with_lint: true };
span_bug!(
tcx.def_span(def_id),
"cannot return a pair (the wasm32-unknown-unknown ABI is broken, see https://github.com/rust-lang/rust/issues/115666"
);
}
let hidden_return = matches!(fn_abi.ret.mode, PassMode::Indirect { .. });
signature.push('(');
@ -366,7 +349,7 @@ fn wasm_functype<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, def_id
let mut it = fn_abi.args.iter().peekable();
while let Some(arg_abi) = it.next() {
wasm_type(tcx, &mut signature, arg_abi, ptr_type, def_id);
wasm_type(&mut signature, arg_abi, ptr_type);
if it.peek().is_some() {
signature.push_str(", ");
}
@ -375,7 +358,7 @@ fn wasm_functype<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, def_id
signature.push_str(") -> (");
if !hidden_return {
wasm_type(tcx, &mut signature, &fn_abi.ret, ptr_type, def_id);
wasm_type(&mut signature, &fn_abi.ret, ptr_type);
}
signature.push(')');
@ -383,27 +366,13 @@ fn wasm_functype<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, def_id
signature
}
fn wasm_type<'tcx>(
tcx: TyCtxt<'tcx>,
signature: &mut String,
arg_abi: &ArgAbi<'_, Ty<'tcx>>,
ptr_type: &'static str,
def_id: DefId,
) {
fn wasm_type<'tcx>(signature: &mut String, arg_abi: &ArgAbi<'_, Ty<'tcx>>, ptr_type: &'static str) {
match arg_abi.mode {
PassMode::Ignore => { /* do nothing */ }
PassMode::Direct(_) => {
let direct_type = match arg_abi.layout.backend_repr {
BackendRepr::Scalar(scalar) => wasm_primitive(scalar.primitive(), ptr_type),
BackendRepr::SimdVector { .. } => "v128",
BackendRepr::Memory { .. } => {
// FIXME: remove this branch once the wasm32-unknown-unknown ABI is fixed
let _ = WasmCAbi::Legacy { with_lint: true };
span_bug!(
tcx.def_span(def_id),
"cannot use memory args (the wasm32-unknown-unknown ABI is broken, see https://github.com/rust-lang/rust/issues/115666"
);
}
other => unreachable!("unexpected BackendRepr: {:?}", other),
};

View file

@ -27,7 +27,7 @@ use rustc_span::source_map::{RealFileLoader, SourceMapInputs};
use rustc_span::{FileName, SourceFileHashAlgorithm, sym};
use rustc_target::spec::{
CodeModel, FramePointer, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy,
RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel, WasmCAbi,
RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel,
};
use crate::interface::{initialize_checked_jobserver, parse_cfg};
@ -882,7 +882,6 @@ fn test_unstable_options_tracking_hash() {
tracked!(verify_llvm_ir, true);
tracked!(virtual_function_elimination, true);
tracked!(wasi_exec_model, Some(WasiExecModel::Reactor));
tracked!(wasm_c_abi, WasmCAbi::Spec);
// tidy-alphabetical-end
macro_rules! tracked_no_crate_hash {

View file

@ -623,6 +623,7 @@ fn register_builtins(store: &mut LintStore) {
"converted into hard error, \
see <https://github.com/rust-lang/rust/issues/40107> for more information",
);
store.register_removed("wasm_c_abi", "the wasm C ABI has been fixed");
}
fn register_internals(store: &mut LintStore) {

View file

@ -140,7 +140,6 @@ declare_lint_pass! {
UNUSED_VARIABLES,
USELESS_DEPRECATED,
WARNINGS,
WASM_C_ABI,
// tidy-alphabetical-end
]
}
@ -4980,50 +4979,6 @@ declare_lint! {
crate_level_only
}
declare_lint! {
/// The `wasm_c_abi` lint detects usage of the `extern "C"` ABI of wasm that is affected
/// by a planned ABI change that has the goal of aligning Rust with the standard C ABI
/// of this target.
///
/// ### Example
///
/// ```rust,ignore (needs wasm32-unknown-unknown)
/// #[repr(C)]
/// struct MyType(i32, i32);
///
/// extern "C" my_fun(x: MyType) {}
/// ```
///
/// This will produce:
///
/// ```text
/// error: this function function definition is affected by the wasm ABI transition: it passes an argument of non-scalar type `MyType`
/// --> $DIR/wasm_c_abi_transition.rs:17:1
/// |
/// | pub extern "C" fn my_fun(_x: MyType) {}
/// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/// |
/// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
/// = note: for more information, see issue #138762 <https://github.com/rust-lang/rust/issues/138762>
/// = help: the "C" ABI Rust uses on wasm32-unknown-unknown will change to align with the standard "C" ABI for this target
/// ```
///
/// ### Explanation
///
/// Rust has historically implemented a non-spec-compliant C ABI on wasm32-unknown-unknown. This
/// has caused incompatibilities with other compilers and Wasm targets. In a future version
/// of Rust, this will be fixed, and therefore code relying on the non-spec-compliant C ABI will
/// stop functioning.
pub WASM_C_ABI,
Warn,
"detects code relying on rustc's non-spec-compliant wasm C ABI",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseError,
reference: "issue #138762 <https://github.com/rust-lang/rust/issues/138762>",
report_in_deps: true,
};
}
declare_lint! {
/// The `aarch64_softfloat_neon` lint detects usage of `#[target_feature(enable = "neon")]` on
/// softfloat aarch64 targets. Enabling this target feature causes LLVM to alter the ABI of

View file

@ -16,9 +16,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable, extension};
use rustc_session::config::OptLevel;
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
use rustc_target::callconv::FnAbi;
use rustc_target::spec::{
HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, PanicStrategy, Target, WasmCAbi, X86Abi,
};
use rustc_target::spec::{HasTargetSpec, HasX86AbiOpt, PanicStrategy, Target, X86Abi};
use tracing::debug;
use {rustc_abi as abi, rustc_hir as hir};
@ -565,12 +563,6 @@ impl<'tcx> HasTargetSpec for TyCtxt<'tcx> {
}
}
impl<'tcx> HasWasmCAbiOpt for TyCtxt<'tcx> {
fn wasm_c_abi_opt(&self) -> WasmCAbi {
self.sess.opts.unstable_opts.wasm_c_abi
}
}
impl<'tcx> HasX86AbiOpt for TyCtxt<'tcx> {
fn x86_abi_opt(&self) -> X86Abi {
X86Abi {
@ -625,12 +617,6 @@ impl<'tcx> HasTargetSpec for LayoutCx<'tcx> {
}
}
impl<'tcx> HasWasmCAbiOpt for LayoutCx<'tcx> {
fn wasm_c_abi_opt(&self) -> WasmCAbi {
self.calc.cx.wasm_c_abi_opt()
}
}
impl<'tcx> HasX86AbiOpt for LayoutCx<'tcx> {
fn x86_abi_opt(&self) -> X86Abi {
self.calc.cx.x86_abi_opt()

View file

@ -60,11 +60,4 @@ monomorphize_start_not_found = using `fn main` requires the standard library
monomorphize_symbol_already_defined = symbol `{$symbol}` is already defined
monomorphize_wasm_c_abi_transition =
this function {$is_call ->
[true] call
*[false] definition
} involves an argument of type `{$ty}` which is affected by the wasm ABI transition
.help = the "C" ABI Rust uses on wasm32-unknown-unknown will change to align with the standard "C" ABI for this target
monomorphize_written_to_path = the full type name has been written to '{$path}'

View file

@ -100,12 +100,3 @@ pub(crate) struct AbiRequiredTargetFeature<'a> {
/// Whether this is a problem at a call site or at a declaration.
pub is_call: bool,
}
#[derive(LintDiagnostic)]
#[diag(monomorphize_wasm_c_abi_transition)]
#[help]
pub(crate) struct WasmCAbiTransition<'a> {
pub ty: Ty<'a>,
/// Whether this is a problem at a call site or at a declaration.
pub is_call: bool,
}

View file

@ -3,13 +3,10 @@
use rustc_abi::{BackendRepr, CanonAbi, RegKind, X86Call};
use rustc_hir::{CRATE_HIR_ID, HirId};
use rustc_middle::mir::{self, Location, traversal};
use rustc_middle::ty::layout::LayoutCx;
use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt, TypingEnv};
use rustc_session::lint::builtin::WASM_C_ABI;
use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt};
use rustc_span::def_id::DefId;
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
use rustc_target::callconv::{ArgAbi, FnAbi, PassMode};
use rustc_target::spec::{HasWasmCAbiOpt, WasmCAbi};
use rustc_target::callconv::{FnAbi, PassMode};
use crate::errors;
@ -81,73 +78,6 @@ fn do_check_simd_vector_abi<'tcx>(
}
}
/// Determines whether the given argument is passed the same way on the old and new wasm ABIs.
fn wasm_abi_safe<'tcx>(tcx: TyCtxt<'tcx>, arg: &ArgAbi<'tcx, Ty<'tcx>>) -> bool {
if matches!(arg.layout.backend_repr, BackendRepr::Scalar(_)) {
return true;
}
// Both the old and the new ABIs treat vector types like `v128` the same
// way.
if uses_vector_registers(&arg.mode, &arg.layout.backend_repr) {
return true;
}
// This matches `unwrap_trivial_aggregate` in the wasm ABI logic.
if arg.layout.is_aggregate() {
let cx = LayoutCx::new(tcx, TypingEnv::fully_monomorphized());
if let Some(unit) = arg.layout.homogeneous_aggregate(&cx).ok().and_then(|ha| ha.unit()) {
let size = arg.layout.size;
// Ensure there's just a single `unit` element in `arg`.
if unit.size == size {
return true;
}
}
}
// Zero-sized types are dropped in both ABIs, so they're safe
if arg.layout.is_zst() {
return true;
}
false
}
/// Warns against usage of `extern "C"` on wasm32-unknown-unknown that is affected by the
/// ABI transition.
fn do_check_wasm_abi<'tcx>(
tcx: TyCtxt<'tcx>,
abi: &FnAbi<'tcx, Ty<'tcx>>,
is_call: bool,
loc: impl Fn() -> (Span, HirId),
) {
// Only proceed for `extern "C" fn` on wasm32-unknown-unknown (same check as what
// `adjust_for_foreign_abi` uses to call `compute_wasm_abi_info`), and only proceed if
// `wasm_c_abi_opt` indicates we should emit the lint.
if !(tcx.sess.target.arch == "wasm32"
&& tcx.sess.target.os == "unknown"
&& tcx.wasm_c_abi_opt() == WasmCAbi::Legacy { with_lint: true }
&& abi.conv == CanonAbi::C)
{
return;
}
// Warn against all types whose ABI will change. Return values are not affected by this change.
for arg_abi in abi.args.iter() {
if wasm_abi_safe(tcx, arg_abi) {
continue;
}
let (span, hir_id) = loc();
tcx.emit_node_span_lint(
WASM_C_ABI,
hir_id,
span,
errors::WasmCAbiTransition { ty: arg_abi.layout.ty, is_call },
);
// Let's only warn once per function.
break;
}
}
/// Checks that the ABI of a given instance of a function does not contain vector-passed arguments
/// or return values for which the corresponding target feature is not enabled.
fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
@ -173,7 +103,6 @@ fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
)
};
do_check_simd_vector_abi(tcx, abi, instance.def_id(), /*is_call*/ false, loc);
do_check_wasm_abi(tcx, abi, /*is_call*/ false, loc);
}
/// Checks that a call expression does not try to pass a vector-passed argument which requires a
@ -212,7 +141,6 @@ fn check_call_site_abi<'tcx>(
return;
};
do_check_simd_vector_abi(tcx, callee_abi, caller.def_id(), /*is_call*/ true, loc);
do_check_wasm_abi(tcx, callee_abi, /*is_call*/ true, loc);
}
fn check_callees_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, body: &mir::Body<'tcx>) {

View file

@ -3066,7 +3066,7 @@ pub(crate) mod dep_tracking {
use rustc_target::spec::{
CodeModel, FramePointer, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel,
RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, SymbolVisibility, TargetTuple,
TlsModel, WasmCAbi,
TlsModel,
};
use super::{
@ -3177,7 +3177,6 @@ pub(crate) mod dep_tracking {
Polonius,
InliningThreshold,
FunctionReturn,
WasmCAbi,
Align,
);

View file

@ -16,7 +16,7 @@ use rustc_span::{RealFileName, SourceFileHashAlgorithm};
use rustc_target::spec::{
CodeModel, FramePointer, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy,
RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, SymbolVisibility,
TargetTuple, TlsModel, WasmCAbi,
TargetTuple, TlsModel,
};
use crate::config::*;
@ -802,7 +802,6 @@ mod desc {
"either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
pub(crate) const parse_llvm_module_flag: &str = "<key>:<type>:<value>:<behavior>. Type must currently be `u32`. Behavior should be one of (`error`, `warning`, `require`, `override`, `append`, `appendunique`, `max`, `min`)";
pub(crate) const parse_function_return: &str = "`keep` or `thunk-extern`";
pub(crate) const parse_wasm_c_abi: &str = "`legacy` or `spec`";
pub(crate) const parse_mir_include_spans: &str =
"either a boolean (`yes`, `no`, `on`, `off`, etc), or `nll` (default: `nll`)";
pub(crate) const parse_align: &str = "a number that is a power of 2 between 1 and 2^29";
@ -1898,16 +1897,6 @@ pub mod parse {
true
}
pub(crate) fn parse_wasm_c_abi(slot: &mut WasmCAbi, v: Option<&str>) -> bool {
match v {
Some("spec") => *slot = WasmCAbi::Spec,
// Explicitly setting the `-Z` flag suppresses the lint.
Some("legacy") => *slot = WasmCAbi::Legacy { with_lint: false },
_ => return false,
}
true
}
pub(crate) fn parse_mir_include_spans(slot: &mut MirIncludeSpans, v: Option<&str>) -> bool {
*slot = match v {
Some("on" | "yes" | "y" | "true") | None => MirIncludeSpans::On,
@ -2642,8 +2631,6 @@ written to standard error output)"),
Requires `-Clto[=[fat,yes]]`"),
wasi_exec_model: Option<WasiExecModel> = (None, parse_wasi_exec_model, [TRACKED],
"whether to build a wasi command or reactor"),
wasm_c_abi: WasmCAbi = (WasmCAbi::Legacy { with_lint: true }, parse_wasm_c_abi, [TRACKED],
"use spec-compliant C ABI for `wasm32-unknown-unknown` (default: legacy)"),
write_long_types_to_disk: bool = (true, parse_bool, [UNTRACKED],
"whether long type names should be written to files instead of being printed in errors"),
// tidy-alphabetical-end

View file

@ -7,7 +7,7 @@ use rustc_abi::{
use rustc_macros::HashStable_Generic;
pub use crate::spec::AbiMap;
use crate::spec::{HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, WasmCAbi};
use crate::spec::{HasTargetSpec, HasX86AbiOpt};
mod aarch64;
mod amdgpu;
@ -593,7 +593,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
pub fn adjust_for_foreign_abi<C>(&mut self, cx: &C, abi: ExternAbi)
where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout + HasTargetSpec + HasWasmCAbiOpt + HasX86AbiOpt,
C: HasDataLayout + HasTargetSpec + HasX86AbiOpt,
{
if abi == ExternAbi::X86Interrupt {
if let Some(arg) = self.args.first_mut() {
@ -669,14 +669,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
"hexagon" => hexagon::compute_abi_info(self),
"xtensa" => xtensa::compute_abi_info(cx, self),
"riscv32" | "riscv64" => riscv::compute_abi_info(cx, self),
"wasm32" => {
if spec.os == "unknown" && matches!(cx.wasm_c_abi_opt(), WasmCAbi::Legacy { .. }) {
wasm::compute_wasm_abi_info(self)
} else {
wasm::compute_c_abi_info(cx, self)
}
}
"wasm64" => wasm::compute_c_abi_info(cx, self),
"wasm32" | "wasm64" => wasm::compute_abi_info(cx, self),
"bpf" => bpf::compute_abi_info(self),
arch => panic!("no lowering implemented for {arch}"),
}

View file

@ -59,7 +59,7 @@ where
}
/// The purpose of this ABI is to match the C ABI (aka clang) exactly.
pub(crate) fn compute_c_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout,
@ -75,43 +75,3 @@ where
classify_arg(cx, arg);
}
}
/// The purpose of this ABI is for matching the WebAssembly standard. This
/// intentionally diverges from the C ABI and is specifically crafted to take
/// advantage of LLVM's support of multiple returns in WebAssembly.
///
/// This ABI is *bad*! It uses `PassMode::Direct` for `abi::Aggregate` types, which leaks LLVM
/// implementation details into the ABI. It's just hard to fix because ABIs are hard to change.
/// Also see <https://github.com/rust-lang/rust/issues/115666>.
pub(crate) fn compute_wasm_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
if !fn_abi.ret.is_ignore() {
classify_ret_wasm_abi(&mut fn_abi.ret);
}
for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
classify_arg_wasm_abi(arg);
}
fn classify_ret_wasm_abi<Ty>(ret: &mut ArgAbi<'_, Ty>) {
if !ret.layout.is_sized() {
// Not touching this...
return;
}
// FIXME: this is bad! https://github.com/rust-lang/rust/issues/115666
ret.make_direct_deprecated();
ret.extend_integer_width_to(32);
}
fn classify_arg_wasm_abi<Ty>(arg: &mut ArgAbi<'_, Ty>) {
if !arg.layout.is_sized() {
// Not touching this...
return;
}
// FIXME: this is bad! https://github.com/rust-lang/rust/issues/115666
arg.make_direct_deprecated();
arg.extend_integer_width_to(32);
}
}

View file

@ -2233,22 +2233,6 @@ impl HasTargetSpec for Target {
}
}
/// Which C ABI to use for `wasm32-unknown-unknown`.
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum WasmCAbi {
/// Spec-compliant C ABI.
Spec,
/// Legacy ABI. Which is non-spec-compliant.
Legacy {
/// Indicates whether the `wasm_c_abi` lint should be emitted.
with_lint: bool,
},
}
pub trait HasWasmCAbiOpt {
fn wasm_c_abi_opt(&self) -> WasmCAbi;
}
/// x86 (32-bit) abi options.
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct X86Abi {

View file

@ -403,28 +403,18 @@ fn fn_abi_sanity_check<'tcx>(
// For an unsized type we'd only pass the sized prefix, so there is no universe
// in which we ever want to allow this.
assert!(sized, "`PassMode::Direct` for unsized type in ABI: {:#?}", fn_abi);
// This really shouldn't happen even for sized aggregates, since
// `immediate_llvm_type` will use `layout.fields` to turn this Rust type into an
// LLVM type. This means all sorts of Rust type details leak into the ABI.
// However wasm sadly *does* currently use this mode for it's "C" ABI so we
// have to allow it -- but we absolutely shouldn't let any more targets do
// that. (Also see <https://github.com/rust-lang/rust/issues/115666>.)
//
// The unadjusted ABI also uses Direct for all args and is ill-specified,
// The unadjusted ABI however uses Direct for all args. It is ill-specified,
// but unfortunately we need it for calling certain LLVM intrinsics.
match spec_abi {
ExternAbi::Unadjusted => {}
ExternAbi::C { unwind: _ }
if matches!(&*tcx.sess.target.arch, "wasm32" | "wasm64") => {}
_ => {
panic!(
"`PassMode::Direct` for aggregates only allowed for \"unadjusted\" functions and on wasm\n\
Problematic type: {:#?}",
arg.layout,
);
}
}
assert!(
matches!(spec_abi, ExternAbi::Unadjusted),
"`PassMode::Direct` for aggregates only allowed for \"unadjusted\"\n\
Problematic type: {:#?}",
arg.layout,
);
}
}
}

View file

@ -7,9 +7,6 @@
//! Rust ABIs (e.g., stage0/bin/rustc vs stage1/bin/rustc during bootstrap).
#![deny(unsafe_code)]
// proc_macros anyway don't work on wasm hosts so while both sides of this bridge can
// be built with different versions of rustc, the wasm ABI changes don't really matter.
#![allow(wasm_c_abi)]
use std::hash::Hash;
use std::ops::{Bound, Range};

View file

@ -1,57 +0,0 @@
//@ compile-flags: --target wasm32-unknown-unknown
//@ needs-llvm-components: webassembly
//@ add-core-stubs
//@ build-fail
#![feature(no_core, repr_simd)]
#![no_core]
#![crate_type = "lib"]
#![deny(wasm_c_abi)]
extern crate minicore;
use minicore::*;
pub extern "C" fn my_fun_trivial(_x: i32, _y: f32) {}
#[repr(C)]
pub struct MyType(i32, i32);
pub extern "C" fn my_fun(_x: MyType) {} //~ERROR: wasm ABI transition
//~^WARN: previously accepted
// This one is ABI-safe as it only wraps a single field,
// and the return type can be anything.
#[repr(C)]
pub struct MySafeType(i32);
pub extern "C" fn my_fun_safe(_x: MySafeType) -> MyType { loop {} }
// This one not ABI-safe due to the alignment.
#[repr(C, align(16))]
pub struct MyAlignedType(i32);
pub extern "C" fn my_fun_aligned(_x: MyAlignedType) {} //~ERROR: wasm ABI transition
//~^WARN: previously accepted
// Check call-site warning
extern "C" {
fn other_fun(x: MyType);
}
pub fn call_other_fun(x: MyType) {
unsafe { other_fun(x) } //~ERROR: wasm ABI transition
//~^WARN: previously accepted
}
// Zero-sized types are safe in both ABIs
#[repr(C)]
pub struct MyZstType;
#[allow(improper_ctypes_definitions)]
pub extern "C" fn zst_safe(_x: (), _y: MyZstType) {}
// The old and new wasm ABI treats simd types like `v128` the same way, so no
// wasm_c_abi warning should be emitted.
#[repr(simd)]
#[allow(non_camel_case_types)]
pub struct v128([i32; 4]);
#[target_feature(enable = "simd128")]
pub extern "C" fn my_safe_simd(x: v128) -> v128 { x }
//~^ WARN `extern` fn uses type `v128`, which is not FFI-safe
//~| WARN `extern` fn uses type `v128`, which is not FFI-safe

View file

@ -1,114 +0,0 @@
warning: `extern` fn uses type `v128`, which is not FFI-safe
--> $DIR/wasm_c_abi_transition.rs:55:35
|
LL | pub extern "C" fn my_safe_simd(x: v128) -> v128 { x }
| ^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
= note: this struct has unspecified layout
note: the type is defined here
--> $DIR/wasm_c_abi_transition.rs:53:1
|
LL | pub struct v128([i32; 4]);
| ^^^^^^^^^^^^^^^
= note: `#[warn(improper_ctypes_definitions)]` on by default
warning: `extern` fn uses type `v128`, which is not FFI-safe
--> $DIR/wasm_c_abi_transition.rs:55:44
|
LL | pub extern "C" fn my_safe_simd(x: v128) -> v128 { x }
| ^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
= note: this struct has unspecified layout
note: the type is defined here
--> $DIR/wasm_c_abi_transition.rs:53:1
|
LL | pub struct v128([i32; 4]);
| ^^^^^^^^^^^^^^^
error: this function definition involves an argument of type `MyType` which is affected by the wasm ABI transition
--> $DIR/wasm_c_abi_transition.rs:18:1
|
LL | pub extern "C" fn my_fun(_x: MyType) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #138762 <https://github.com/rust-lang/rust/issues/138762>
= help: the "C" ABI Rust uses on wasm32-unknown-unknown will change to align with the standard "C" ABI for this target
note: the lint level is defined here
--> $DIR/wasm_c_abi_transition.rs:9:9
|
LL | #![deny(wasm_c_abi)]
| ^^^^^^^^^^
error: this function definition involves an argument of type `MyAlignedType` which is affected by the wasm ABI transition
--> $DIR/wasm_c_abi_transition.rs:30:1
|
LL | pub extern "C" fn my_fun_aligned(_x: MyAlignedType) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #138762 <https://github.com/rust-lang/rust/issues/138762>
= help: the "C" ABI Rust uses on wasm32-unknown-unknown will change to align with the standard "C" ABI for this target
error: this function call involves an argument of type `MyType` which is affected by the wasm ABI transition
--> $DIR/wasm_c_abi_transition.rs:39:14
|
LL | unsafe { other_fun(x) }
| ^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #138762 <https://github.com/rust-lang/rust/issues/138762>
= help: the "C" ABI Rust uses on wasm32-unknown-unknown will change to align with the standard "C" ABI for this target
error: aborting due to 3 previous errors; 2 warnings emitted
Future incompatibility report: Future breakage diagnostic:
error: this function definition involves an argument of type `MyType` which is affected by the wasm ABI transition
--> $DIR/wasm_c_abi_transition.rs:18:1
|
LL | pub extern "C" fn my_fun(_x: MyType) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #138762 <https://github.com/rust-lang/rust/issues/138762>
= help: the "C" ABI Rust uses on wasm32-unknown-unknown will change to align with the standard "C" ABI for this target
note: the lint level is defined here
--> $DIR/wasm_c_abi_transition.rs:9:9
|
LL | #![deny(wasm_c_abi)]
| ^^^^^^^^^^
Future breakage diagnostic:
error: this function definition involves an argument of type `MyAlignedType` which is affected by the wasm ABI transition
--> $DIR/wasm_c_abi_transition.rs:30:1
|
LL | pub extern "C" fn my_fun_aligned(_x: MyAlignedType) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #138762 <https://github.com/rust-lang/rust/issues/138762>
= help: the "C" ABI Rust uses on wasm32-unknown-unknown will change to align with the standard "C" ABI for this target
note: the lint level is defined here
--> $DIR/wasm_c_abi_transition.rs:9:9
|
LL | #![deny(wasm_c_abi)]
| ^^^^^^^^^^
Future breakage diagnostic:
error: this function call involves an argument of type `MyType` which is affected by the wasm ABI transition
--> $DIR/wasm_c_abi_transition.rs:39:14
|
LL | unsafe { other_fun(x) }
| ^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #138762 <https://github.com/rust-lang/rust/issues/138762>
= help: the "C" ABI Rust uses on wasm32-unknown-unknown will change to align with the standard "C" ABI for this target
note: the lint level is defined here
--> $DIR/wasm_c_abi_transition.rs:9:9
|
LL | #![deny(wasm_c_abi)]
| ^^^^^^^^^^