From 07ba1fdd59cbf563536c40d82c5690008d67937f Mon Sep 17 00:00:00 2001 From: Jan Ferdinand Sauer Date: Fri, 7 Jun 2024 14:43:52 +0200 Subject: [PATCH 01/24] docs: Mention `spare_capacity_mut()` in `Vec::set_len` --- library/alloc/src/vec/mod.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index aa9b632cbed9..e5a3cbcc834c 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1420,7 +1420,10 @@ impl Vec { /// /// # Examples /// - /// This method can be useful for situations in which the vector + /// See [`spare_capacity_mut()`] for an example with safe + /// initialization of capacity elements and use of this method. + /// + /// `set_len()` can be useful for situations in which the vector /// is serving as a buffer for other code, particularly over FFI: /// /// ```no_run @@ -1477,6 +1480,8 @@ impl Vec { /// /// Normally, here, one would use [`clear`] instead to correctly drop /// the contents and thus not leak memory. + /// + /// [`spare_capacity_mut()`]: Vec::spare_capacity_mut #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn set_len(&mut self, new_len: usize) { From b8407d9852dd4a11385390165b553f64b114f59a Mon Sep 17 00:00:00 2001 From: wr7 Date: Sat, 9 Nov 2024 16:49:53 -0600 Subject: [PATCH 02/24] Rename `elem_offset` to `element_offset` --- library/core/src/slice/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 52d2179b04de..39541e853039 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -4553,7 +4553,7 @@ impl [T] { /// let num = &nums[2]; /// /// assert_eq!(num, &1); - /// assert_eq!(nums.elem_offset(num), Some(2)); + /// assert_eq!(nums.element_offset(num), Some(2)); /// ``` /// Returning `None` with an in-between element: /// ``` @@ -4568,12 +4568,12 @@ impl [T] { /// assert_eq!(ok_elm, &[0, 1]); /// assert_eq!(weird_elm, &[1, 2]); /// - /// assert_eq!(arr.elem_offset(ok_elm), Some(0)); // Points to element 0 - /// assert_eq!(arr.elem_offset(weird_elm), None); // Points between element 0 and 1 + /// assert_eq!(arr.element_offset(ok_elm), Some(0)); // Points to element 0 + /// assert_eq!(arr.element_offset(weird_elm), None); // Points between element 0 and 1 /// ``` #[must_use] #[unstable(feature = "substr_range", issue = "126769")] - pub fn elem_offset(&self, element: &T) -> Option { + pub fn element_offset(&self, element: &T) -> Option { if T::IS_ZST { panic!("elements are zero-sized"); } From 3c8bfb7f7bc586afb597155184a14d1a4fe0d244 Mon Sep 17 00:00:00 2001 From: wr7 Date: Sat, 9 Nov 2024 16:28:15 -0600 Subject: [PATCH 03/24] Improve documentation of `element_offset` and related methods --- library/core/src/slice/mod.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 39541e853039..d0a9af09ea80 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -4533,7 +4533,7 @@ impl [T] { /// Returns the index that an element reference points to. /// - /// Returns `None` if `element` does not point within the slice or if it points between elements. + /// Returns `None` if `element` does not point to the start of an element within the slice. /// /// This method is useful for extending slice iterators like [`slice::split`]. /// @@ -4555,7 +4555,7 @@ impl [T] { /// assert_eq!(num, &1); /// assert_eq!(nums.element_offset(num), Some(2)); /// ``` - /// Returning `None` with an in-between element: + /// Returning `None` with an unaligned element: /// ``` /// #![feature(substr_range)] /// @@ -4594,7 +4594,8 @@ impl [T] { /// Returns the range of indices that a subslice points to. /// - /// Returns `None` if `subslice` does not point within the slice or if it points between elements. + /// Returns `None` if `subslice` does not point within the slice or if it is not aligned with the + /// elements in the slice. /// /// This method **does not compare elements**. Instead, this method finds the location in the slice that /// `subslice` was obtained from. To find the index of a subslice via comparison, instead use From ef96965f44ac1f0b8d99d39708283e07fadcc945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Tue, 17 Dec 2024 18:54:39 +0000 Subject: [PATCH 04/24] add `MixedBitSet::clear` --- compiler/rustc_index/src/bit_set.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index aba1e9382969..664b77fd49eb 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -1191,6 +1191,14 @@ impl MixedBitSet { } } + #[inline] + pub fn clear(&mut self) { + match self { + MixedBitSet::Small(set) => set.clear(), + MixedBitSet::Large(set) => set.clear(), + } + } + bit_relations_inherent_impls! {} } From db7d6a9ba8fcc708db07a4880a4c560ee41edcd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Tue, 17 Dec 2024 18:55:05 +0000 Subject: [PATCH 05/24] make const qualif use mixed bitsets instead of dense bitsets --- .../rustc_const_eval/src/check_consts/resolver.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/resolver.rs b/compiler/rustc_const_eval/src/check_consts/resolver.rs index 763c37a41aff..79df63a9e849 100644 --- a/compiler/rustc_const_eval/src/check_consts/resolver.rs +++ b/compiler/rustc_const_eval/src/check_consts/resolver.rs @@ -5,7 +5,7 @@ use std::fmt; use std::marker::PhantomData; -use rustc_index::bit_set::BitSet; +use rustc_index::bit_set::MixedBitSet; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::{ self, BasicBlock, CallReturnPlaces, Local, Location, Statement, StatementKind, TerminatorEdges, @@ -246,12 +246,14 @@ where } #[derive(Debug, PartialEq, Eq)] +/// The state for the `FlowSensitiveAnalysis` dataflow analysis. This domain is likely homogeneous, +/// and has a big size, so we use a bitset that can be sparse (c.f. issue #134404). pub(super) struct State { /// Describes whether a local contains qualif. - pub qualif: BitSet, + pub qualif: MixedBitSet, /// Describes whether a local's address escaped and it might become qualified as a result an /// indirect mutation. - pub borrow: BitSet, + pub borrow: MixedBitSet, } impl Clone for State { @@ -320,8 +322,8 @@ where fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain { State { - qualif: BitSet::new_empty(body.local_decls.len()), - borrow: BitSet::new_empty(body.local_decls.len()), + qualif: MixedBitSet::new_empty(body.local_decls.len()), + borrow: MixedBitSet::new_empty(body.local_decls.len()), } } From fd8b983452841ef04b9a15cf2259caedf5fe3c66 Mon Sep 17 00:00:00 2001 From: tiif Date: Sat, 16 Nov 2024 09:04:30 +0000 Subject: [PATCH 06/24] Pass FnAbi to find_mir_or_eval_fn --- .../src/const_eval/dummy_machine.rs | 4 +- .../src/const_eval/machine.rs | 5 +- .../rustc_const_eval/src/interpret/call.rs | 4 +- .../rustc_const_eval/src/interpret/machine.rs | 9 +- src/tools/miri/src/helpers.rs | 19 +- src/tools/miri/src/machine.rs | 5 +- src/tools/miri/src/shims/backtrace.rs | 21 +- src/tools/miri/src/shims/foreign_items.rs | 88 ++++---- .../src/shims/unix/android/foreign_items.rs | 17 +- .../miri/src/shims/unix/android/thread.rs | 8 +- .../miri/src/shims/unix/foreign_items.rs | 206 +++++++++--------- .../src/shims/unix/freebsd/foreign_items.rs | 21 +- .../src/shims/unix/linux/foreign_items.rs | 39 ++-- .../miri/src/shims/unix/linux_like/syscall.rs | 8 +- .../src/shims/unix/macos/foreign_items.rs | 55 ++--- .../src/shims/unix/solarish/foreign_items.rs | 23 +- .../miri/src/shims/wasi/foreign_items.rs | 9 +- .../miri/src/shims/windows/foreign_items.rs | 125 ++++++----- src/tools/miri/src/shims/x86/aesni.rs | 18 +- src/tools/miri/src/shims/x86/avx.rs | 42 ++-- src/tools/miri/src/shims/x86/avx2.rs | 44 ++-- src/tools/miri/src/shims/x86/bmi.rs | 7 +- src/tools/miri/src/shims/x86/gfni.rs | 12 +- src/tools/miri/src/shims/x86/mod.rs | 15 +- src/tools/miri/src/shims/x86/sha.rs | 11 +- src/tools/miri/src/shims/x86/sse.rs | 23 +- src/tools/miri/src/shims/x86/sse2.rs | 33 +-- src/tools/miri/src/shims/x86/sse3.rs | 9 +- src/tools/miri/src/shims/x86/sse41.rs | 25 ++- src/tools/miri/src/shims/x86/sse42.rs | 17 +- src/tools/miri/src/shims/x86/ssse3.rs | 17 +- 31 files changed, 484 insertions(+), 455 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs b/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs index 817acfcca74b..46dcebc46e9c 100644 --- a/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs @@ -1,9 +1,11 @@ use rustc_middle::mir::interpret::{AllocId, ConstAllocation, InterpResult}; use rustc_middle::mir::*; use rustc_middle::query::TyCtxtAt; +use rustc_middle::ty::Ty; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::{bug, span_bug, ty}; use rustc_span::def_id::DefId; +use rustc_target::callconv::FnAbi; use crate::interpret::{ self, HasStaticRootDefId, ImmTy, Immediate, InterpCx, PointerArithmetic, interp_ok, @@ -86,7 +88,7 @@ impl<'tcx> interpret::Machine<'tcx> for DummyMachine { fn find_mir_or_eval_fn( _ecx: &mut InterpCx<'tcx, Self>, _instance: ty::Instance<'tcx>, - _abi: rustc_abi::ExternAbi, + _abi: &FnAbi<'tcx, Ty<'tcx>>, _args: &[interpret::FnArg<'tcx, Self::Provenance>], _destination: &interpret::MPlaceTy<'tcx, Self::Provenance>, _target: Option, diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 9c660ef0b18c..ba7fbb254c66 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -2,7 +2,7 @@ use std::borrow::{Borrow, Cow}; use std::fmt; use std::hash::Hash; -use rustc_abi::{Align, ExternAbi, Size}; +use rustc_abi::{Align, Size}; use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, IndexEntry}; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -14,6 +14,7 @@ use rustc_middle::ty::layout::{HasTypingEnv, TyAndLayout}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, mir}; use rustc_span::{Span, Symbol, sym}; +use rustc_target::callconv::FnAbi; use tracing::debug; use super::error::*; @@ -339,7 +340,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { fn find_mir_or_eval_fn( ecx: &mut InterpCx<'tcx, Self>, orig_instance: ty::Instance<'tcx>, - _abi: ExternAbi, + _abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[FnArg<'tcx>], dest: &MPlaceTy<'tcx>, ret: Option, diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index ed4a1a9e6478..46720328ea47 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -519,7 +519,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { return M::call_extra_fn( self, extra, - caller_abi, + caller_fn_abi, args, destination, target, @@ -570,7 +570,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let Some((body, instance)) = M::find_mir_or_eval_fn( self, instance, - caller_abi, + caller_fn_abi, args, destination, target, diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 9ac2a024ccf3..36e5a2ff750a 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -6,7 +6,7 @@ use std::borrow::{Borrow, Cow}; use std::fmt::Debug; use std::hash::Hash; -use rustc_abi::{Align, ExternAbi, Size}; +use rustc_abi::{Align, Size}; use rustc_apfloat::{Float, FloatConvert}; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_middle::query::TyCtxtAt; @@ -15,6 +15,7 @@ use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::{mir, ty}; use rustc_span::Span; use rustc_span::def_id::DefId; +use rustc_target::callconv::FnAbi; use super::{ AllocBytes, AllocId, AllocKind, AllocRange, Allocation, CTFE_ALLOC_SALT, ConstAllocation, @@ -201,7 +202,7 @@ pub trait Machine<'tcx>: Sized { fn find_mir_or_eval_fn( ecx: &mut InterpCx<'tcx, Self>, instance: ty::Instance<'tcx>, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[FnArg<'tcx, Self::Provenance>], destination: &MPlaceTy<'tcx, Self::Provenance>, target: Option, @@ -213,7 +214,7 @@ pub trait Machine<'tcx>: Sized { fn call_extra_fn( ecx: &mut InterpCx<'tcx, Self>, fn_val: Self::ExtraFnVal, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[FnArg<'tcx, Self::Provenance>], destination: &MPlaceTy<'tcx, Self::Provenance>, target: Option, @@ -656,7 +657,7 @@ pub macro compile_time_machine(<$tcx: lifetime>) { fn call_extra_fn( _ecx: &mut InterpCx<$tcx, Self>, fn_val: !, - _abi: ExternAbi, + _abi: &FnAbi<$tcx, Ty<$tcx>>, _args: &[FnArg<$tcx>], _destination: &MPlaceTy<$tcx, Self::Provenance>, _target: Option, diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 1f7c60ad1bdf..412efd0296e4 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -19,6 +19,7 @@ use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, MaybeResult, TyAndLayout}; use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, UintTy}; use rustc_session::config::CrateType; use rustc_span::{Span, Symbol}; +use rustc_target::callconv::{Conv, FnAbi}; use crate::*; @@ -914,13 +915,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } /// Check that the ABI is what we expect. - fn check_abi<'a>(&self, abi: ExternAbi, exp_abi: ExternAbi) -> InterpResult<'a, ()> { - if abi != exp_abi { + fn check_abi<'a>(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, exp_abi: Conv) -> InterpResult<'a, ()> { + if fn_abi.conv != exp_abi { throw_ub_format!( - "calling a function with ABI {} using caller ABI {}", - exp_abi.name(), - abi.name() - ) + "calling a function with ABI {:?} using caller ABI {:?}", + exp_abi, fn_abi.conv); } interp_ok(()) } @@ -950,8 +949,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn check_abi_and_shim_symbol_clash( &mut self, - abi: ExternAbi, - exp_abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, + exp_abi: Conv, link_name: Symbol, ) -> InterpResult<'tcx, ()> { self.check_abi(abi, exp_abi)?; @@ -975,8 +974,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn check_shim<'a, const N: usize>( &mut self, - abi: ExternAbi, - exp_abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, + exp_abi: Conv, link_name: Symbol, args: &'a [OpTy<'tcx>], ) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]> diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index ad8a7ea1668d..592a54ff50d2 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -13,6 +13,7 @@ use rand::{Rng, SeedableRng}; use rustc_abi::{Align, ExternAbi, Size}; use rustc_attr_parsing::InlineAttr; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_target::callconv::FnAbi; #[allow(unused)] use rustc_data_structures::static_assert_size; use rustc_middle::mir; @@ -1010,7 +1011,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { fn find_mir_or_eval_fn( ecx: &mut MiriInterpCx<'tcx>, instance: ty::Instance<'tcx>, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[FnArg<'tcx, Provenance>], dest: &MPlaceTy<'tcx>, ret: Option, @@ -1037,7 +1038,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { fn call_extra_fn( ecx: &mut MiriInterpCx<'tcx>, fn_val: DynSym, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[FnArg<'tcx, Provenance>], dest: &MPlaceTy<'tcx>, ret: Option, diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs index c7b399228bfb..1622ef280d25 100644 --- a/src/tools/miri/src/shims/backtrace.rs +++ b/src/tools/miri/src/shims/backtrace.rs @@ -1,7 +1,8 @@ -use rustc_abi::{ExternAbi, Size}; +use rustc_abi::Size; use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::ty::{self, Instance, Ty}; use rustc_span::{BytePos, Loc, Symbol, hygiene}; +use rustc_target::callconv::{Conv, FnAbi}; use crate::helpers::check_min_arg_count; use crate::*; @@ -10,13 +11,13 @@ impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn handle_miri_backtrace_size( &mut self, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let [flags] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [flags] = this.check_shim(abi, Conv::Rust, link_name, args)?; let flags = this.read_scalar(flags)?.to_u64()?; if flags != 0 { @@ -30,7 +31,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn handle_miri_get_backtrace( &mut self, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, @@ -71,7 +72,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // storage for pointers is allocated by miri // deallocating the slice is undefined behavior with a custom global allocator 0 => { - let [_flags] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [_flags] = this.check_shim(abi, Conv::Rust, link_name, args)?; let alloc = this.allocate(array_layout, MiriMemoryKind::Rust.into())?; @@ -86,7 +87,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // storage for pointers is allocated by the caller 1 => { - let [_flags, buf] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [_flags, buf] = this.check_shim(abi, Conv::Rust, link_name, args)?; let buf_place = this.deref_pointer(buf)?; @@ -136,13 +137,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn handle_miri_resolve_frame( &mut self, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let [ptr, flags] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [ptr, flags] = this.check_shim(abi, Conv::Rust, link_name, args)?; let flags = this.read_scalar(flags)?.to_u64()?; @@ -207,14 +208,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn handle_miri_resolve_frame_names( &mut self, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, link_name: Symbol, args: &[OpTy<'tcx>], ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); let [ptr, flags, name_ptr, filename_ptr] = - this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + this.check_shim(abi, Conv::Rust, link_name, args)?; let flags = this.read_scalar(flags)?.to_u64()?; if flags != 0 { diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 4dc857ef30b4..7b2a0d6f4d64 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -3,14 +3,17 @@ use std::io::Write; use std::iter; use std::path::Path; -use rustc_abi::{Align, AlignFromBytesError, ExternAbi, Size}; +use rustc_abi::{Align, AlignFromBytesError, Size}; use rustc_apfloat::Float; use rustc_ast::expand::allocator::alloc_error_handler_name; use rustc_hir::def::DefKind; use rustc_hir::def_id::CrateNum; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::{mir, ty}; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; + use self::helpers::{ToHost, ToSoft}; use super::alloc::EvalContextExt as _; @@ -39,7 +42,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ret: Option, @@ -106,7 +109,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_dyn_sym( &mut self, sym: DynSym, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ret: Option, @@ -218,7 +221,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -235,11 +238,10 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { return interp_ok(EmulateItemResult::NeedsReturn); } } - // When adding a new shim, you should follow the following pattern: // ``` // "shim_name" => { - // let [arg1, arg2, arg3] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + // let [arg1, arg2, arg3] = this.check_shim(abi, Conv::::C , link_name, args)?; // let result = this.shim_name(arg1, arg2, arg3)?; // this.write_scalar(result, dest)?; // } @@ -277,16 +279,16 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Miri-specific extern functions "miri_start_unwind" => { - let [payload] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [payload] = this.check_shim(abi, Conv::Rust, link_name, args)?; this.handle_miri_start_unwind(payload)?; return interp_ok(EmulateItemResult::NeedsUnwind); } "miri_run_provenance_gc" => { - let [] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [] = this.check_shim(abi, Conv::Rust, link_name, args)?; this.run_provenance_gc(); } "miri_get_alloc_id" => { - let [ptr] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [ptr] = this.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let (alloc_id, _, _) = this.ptr_get_alloc_id(ptr, 0).map_err_kind(|_e| { err_machine_stop!(TerminationInfo::Abort(format!( @@ -296,7 +298,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_u64(alloc_id.0.get()), dest)?; } "miri_print_borrow_state" => { - let [id, show_unnamed] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [id, show_unnamed] = this.check_shim(abi, Conv::Rust, link_name, args)?; let id = this.read_scalar(id)?.to_u64()?; let show_unnamed = this.read_scalar(show_unnamed)?.to_bool()?; if let Some(id) = std::num::NonZero::new(id).map(AllocId) @@ -311,7 +313,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // This associates a name to a tag. Very useful for debugging, and also makes // tests more strict. let [ptr, nth_parent, name] = - this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + this.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let nth_parent = this.read_scalar(nth_parent)?.to_u8()?; let name = this.read_immediate(name)?; @@ -324,7 +326,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.give_pointer_debug_name(ptr, nth_parent, &name)?; } "miri_static_root" => { - let [ptr] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [ptr] = this.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let (alloc_id, offset, _) = this.ptr_get_alloc_id(ptr, 0)?; if offset != Size::ZERO { @@ -336,7 +338,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } "miri_host_to_target_path" => { let [ptr, out, out_size] = - this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + this.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let out = this.read_pointer(out)?; let out_size = this.read_scalar(out_size)?.to_target_usize(this)?; @@ -372,7 +374,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Writes some bytes to the interpreter's stdout/stderr. See the // README for details. "miri_write_to_stdout" | "miri_write_to_stderr" => { - let [msg] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [msg] = this.check_shim(abi, Conv::Rust, link_name, args)?; let msg = this.read_immediate(msg)?; let msg = this.read_byte_slice(&msg)?; // Note: we're ignoring errors writing to host stdout/stderr. @@ -386,7 +388,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "miri_promise_symbolic_alignment" => { use rustc_abi::AlignFromBytesError; - let [ptr, align] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [ptr, align] = this.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let align = this.read_target_usize(align)?; if !align.is_power_of_two() { @@ -428,12 +430,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Aborting the process. "exit" => { let [code] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let code = this.read_scalar(code)?.to_i32()?; throw_machine_stop!(TerminationInfo::Exit { code: code.into(), leak_check: false }); } "abort" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C , link_name, args)?; throw_machine_stop!(TerminationInfo::Abort( "the program aborted execution".to_owned() )) @@ -442,7 +444,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Standard C allocation "malloc" => { let [size] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let size = this.read_target_usize(size)?; if size <= this.max_size_of_val().bytes() { let res = this.malloc(size, /*zero_init:*/ false)?; @@ -457,7 +459,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } "calloc" => { let [items, elem_size] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let items = this.read_target_usize(items)?; let elem_size = this.read_target_usize(elem_size)?; if let Some(size) = this.compute_size_in_bytes(Size::from_bytes(elem_size), items) { @@ -473,13 +475,13 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } "free" => { let [ptr] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let ptr = this.read_pointer(ptr)?; this.free(ptr)?; } "realloc" => { let [old_ptr, new_size] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let old_ptr = this.read_pointer(old_ptr)?; let new_size = this.read_target_usize(new_size)?; if new_size <= this.max_size_of_val().bytes() { @@ -499,7 +501,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { let default = |ecx: &mut MiriInterpCx<'tcx>| { // Only call `check_shim` when `#[global_allocator]` isn't used. When that // macro is used, we act like no shim exists, so that the exported function can run. - let [size, align] = ecx.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [size, align] = ecx.check_shim(abi, Conv::Rust, link_name, args)?; let size = ecx.read_target_usize(size)?; let align = ecx.read_target_usize(align)?; @@ -533,7 +535,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { return this.emulate_allocator(|this| { // See the comment for `__rust_alloc` why `check_shim` is only called in the // default case. - let [size, align] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + let [size, align] = this.check_shim(abi, Conv::Rust, link_name, args)?; let size = this.read_target_usize(size)?; let align = this.read_target_usize(align)?; @@ -559,7 +561,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // See the comment for `__rust_alloc` why `check_shim` is only called in the // default case. let [ptr, old_size, align] = - ecx.check_shim(abi, ExternAbi::Rust, link_name, args)?; + ecx.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = ecx.read_pointer(ptr)?; let old_size = ecx.read_target_usize(old_size)?; let align = ecx.read_target_usize(align)?; @@ -594,7 +596,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // See the comment for `__rust_alloc` why `check_shim` is only called in the // default case. let [ptr, old_size, align, new_size] = - this.check_shim(abi, ExternAbi::Rust, link_name, args)?; + this.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let old_size = this.read_target_usize(old_size)?; let align = this.read_target_usize(align)?; @@ -618,7 +620,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // C memory handling functions "memcmp" => { let [left, right, n] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let left = this.read_pointer(left)?; let right = this.read_pointer(right)?; let n = Size::from_bytes(this.read_target_usize(n)?); @@ -643,7 +645,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } "memrchr" => { let [ptr, val, num] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let ptr = this.read_pointer(ptr)?; let val = this.read_scalar(val)?.to_i32()?; let num = this.read_target_usize(num)?; @@ -670,7 +672,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } "memchr" => { let [ptr, val, num] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let ptr = this.read_pointer(ptr)?; let val = this.read_scalar(val)?.to_i32()?; let num = this.read_target_usize(num)?; @@ -694,7 +696,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } "strlen" => { let [ptr] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let ptr = this.read_pointer(ptr)?; // This reads at least 1 byte, so we are already enforcing that this is a valid pointer. let n = this.read_c_str(ptr)?.len(); @@ -705,7 +707,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } "wcslen" => { let [ptr] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let ptr = this.read_pointer(ptr)?; // This reads at least 1 byte, so we are already enforcing that this is a valid pointer. let n = this.read_wchar_t_str(ptr)?.len(); @@ -716,7 +718,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } "memcpy" => { let [ptr_dest, ptr_src, n] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let ptr_dest = this.read_pointer(ptr_dest)?; let ptr_src = this.read_pointer(ptr_src)?; let n = this.read_target_usize(n)?; @@ -731,7 +733,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } "strcpy" => { let [ptr_dest, ptr_src] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let ptr_dest = this.read_pointer(ptr_dest)?; let ptr_src = this.read_pointer(ptr_src)?; @@ -760,7 +762,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { | "expm1f" | "tgammaf" => { - let [f] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [f] = this.check_shim(abi, Conv::C , link_name, args)?; let f = this.read_scalar(f)?.to_f32()?; // Using host floats (but it's fine, these operations do not have guaranteed precision). let f_host = f.to_host(); @@ -788,7 +790,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { | "atan2f" | "fdimf" => { - let [f1, f2] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [f1, f2] = this.check_shim(abi, Conv::C , link_name, args)?; let f1 = this.read_scalar(f1)?.to_f32()?; let f2 = this.read_scalar(f2)?.to_f32()?; // underscore case for windows, here and below @@ -817,7 +819,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { | "expm1" | "tgamma" => { - let [f] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [f] = this.check_shim(abi, Conv::C , link_name, args)?; let f = this.read_scalar(f)?.to_f64()?; // Using host floats (but it's fine, these operations do not have guaranteed precision). let f_host = f.to_host(); @@ -845,7 +847,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { | "atan2" | "fdim" => { - let [f1, f2] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [f1, f2] = this.check_shim(abi, Conv::C , link_name, args)?; let f1 = this.read_scalar(f1)?.to_f64()?; let f2 = this.read_scalar(f2)?.to_f64()?; // underscore case for windows, here and below @@ -866,7 +868,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { | "ldexp" | "scalbn" => { - let [x, exp] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [x, exp] = this.check_shim(abi, Conv::C , link_name, args)?; // For radix-2 (binary) systems, `ldexp` and `scalbn` are the same. let x = this.read_scalar(x)?.to_f64()?; let exp = this.read_scalar(exp)?.to_i32()?; @@ -877,7 +879,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } "lgammaf_r" => { let [x, signp] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let x = this.read_scalar(x)?.to_f32()?; let signp = this.deref_pointer(signp)?; @@ -889,7 +891,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } "lgamma_r" => { let [x, signp] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let x = this.read_scalar(x)?.to_f64()?; let signp = this.deref_pointer(signp)?; @@ -903,7 +905,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // LLVM intrinsics "llvm.prefetch" => { let [p, rw, loc, ty] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let _ = this.read_pointer(p)?; let rw = this.read_scalar(rw)?.to_i32()?; @@ -930,7 +932,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the x86 `_mm{,256,512}_popcnt_epi{8,16,32,64}` and wasm // `{i,u}8x16_popcnt` functions. name if name.starts_with("llvm.ctpop.v") => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C , link_name, args)?; let (op, op_len) = this.project_to_simd(op)?; let (dest, dest_len) = this.project_to_simd(dest)?; @@ -961,7 +963,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } // FIXME: Move these to an `arm` submodule. "llvm.aarch64.isb" if this.tcx.sess.target.arch == "aarch64" => { - let [arg] = this.check_shim(abi, ExternAbi::Unadjusted, link_name, args)?; + let [arg] = this.check_shim(abi, Conv::C, link_name, args)?; let arg = this.read_scalar(arg)?.to_i32()?; match arg { // SY ("full system scope") @@ -974,7 +976,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "llvm.arm.hint" if this.tcx.sess.target.arch == "arm" => { - let [arg] = this.check_shim(abi, ExternAbi::Unadjusted, link_name, args)?; + let [arg] = this.check_shim(abi, Conv::C, link_name, args)?; let arg = this.read_scalar(arg)?.to_i32()?; // Note that different arguments might have different target feature requirements. match arg { diff --git a/src/tools/miri/src/shims/unix/android/foreign_items.rs b/src/tools/miri/src/shims/unix/android/foreign_items.rs index f9003885450c..1a2fa7cfc0f6 100644 --- a/src/tools/miri/src/shims/unix/android/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/android/foreign_items.rs @@ -1,5 +1,8 @@ -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; + + use crate::shims::unix::android::thread::prctl; use crate::shims::unix::linux_like::epoll::EvalContextExt as _; @@ -16,7 +19,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -25,31 +28,31 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // epoll, eventfd "epoll_create1" => { let [flag] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.epoll_create1(flag)?; this.write_scalar(result, dest)?; } "epoll_ctl" => { let [epfd, op, fd, event] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.epoll_ctl(epfd, op, fd, event)?; this.write_scalar(result, dest)?; } "epoll_wait" => { let [epfd, events, maxevents, timeout] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; this.epoll_wait(epfd, events, maxevents, timeout, dest)?; } "eventfd" => { let [val, flag] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.eventfd(val, flag)?; this.write_scalar(result, dest)?; } // Miscellaneous "__errno" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; let errno_place = this.last_error_place()?; this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?; } diff --git a/src/tools/miri/src/shims/unix/android/thread.rs b/src/tools/miri/src/shims/unix/android/thread.rs index f8a0b3a85a2f..8d5d4a52b6ef 100644 --- a/src/tools/miri/src/shims/unix/android/thread.rs +++ b/src/tools/miri/src/shims/unix/android/thread.rs @@ -1,5 +1,7 @@ -use rustc_abi::{ExternAbi, Size}; +use rustc_abi::Size; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use crate::helpers::check_min_arg_count; use crate::shims::unix::thread::{EvalContextExt as _, ThreadNameResult}; @@ -10,13 +12,13 @@ const TASK_COMM_LEN: usize = 16; pub fn prctl<'tcx>( ecx: &mut MiriInterpCx<'tcx>, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { // We do not use `check_shim` here because `prctl` is variadic. The argument // count is checked bellow. - ecx.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?; + ecx.check_abi_and_shim_symbol_clash(abi, Conv::C, link_name)?; // FIXME: Use constants once https://github.com/rust-lang/libc/pull/3941 backported to the 0.2 branch. let pr_set_name = 15; diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index 88ec32808b1c..ff316e782b0b 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -1,9 +1,11 @@ use std::ffi::OsStr; use std::str; -use rustc_abi::{ExternAbi, Size}; +use rustc_abi::Size; use rustc_middle::ty::layout::LayoutOf; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use self::shims::unix::android::foreign_items as android; use self::shims::unix::freebsd::foreign_items as freebsd; @@ -100,7 +102,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -111,54 +113,52 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Environment related shims "getenv" => { - let [name] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [name] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.getenv(name)?; this.write_pointer(result, dest)?; } "unsetenv" => { - let [name] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [name] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.unsetenv(name)?; this.write_scalar(result, dest)?; } "setenv" => { - let [name, value, overwrite] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [name, value, overwrite] = this.check_shim(abi, Conv::C , link_name, args)?; this.read_scalar(overwrite)?.to_i32()?; let result = this.setenv(name, value)?; this.write_scalar(result, dest)?; } "getcwd" => { - let [buf, size] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [buf, size] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.getcwd(buf, size)?; this.write_pointer(result, dest)?; } "chdir" => { - let [path] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [path] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.chdir(path)?; this.write_scalar(result, dest)?; } "getpid" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false}, link_name, args)?; + let [] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.getpid()?; this.write_scalar(result, dest)?; } - "sysconf" => { let [val] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.sysconf(val)?; this.write_scalar(result, dest)?; } - // File descriptors "read" => { - let [fd, buf, count] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, buf, count] = this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(count)?; this.read(fd, buf, count, None, dest)?; } "write" => { - let [fd, buf, n] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, buf, n] = this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(n)?; @@ -166,7 +166,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write(fd, buf, count, None, dest)?; } "pread" => { - let [fd, buf, count, offset] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, buf, count, offset] = this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(count)?; @@ -174,7 +174,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.read(fd, buf, count, Some(offset), dest)?; } "pwrite" => { - let [fd, buf, n, offset] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, buf, n, offset] = this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(n)?; @@ -183,7 +183,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write(fd, buf, count, Some(offset), dest)?; } "pread64" => { - let [fd, buf, count, offset] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, buf, count, offset] = this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(count)?; @@ -191,7 +191,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.read(fd, buf, count, Some(offset), dest)?; } "pwrite64" => { - let [fd, buf, n, offset] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, buf, n, offset] = this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(n)?; @@ -200,32 +200,32 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write(fd, buf, count, Some(offset), dest)?; } "close" => { - let [fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.close(fd)?; this.write_scalar(result, dest)?; } "fcntl" => { // `fcntl` is variadic. The argument count is checked based on the first argument // in `this.fcntl()`, so we do not use `check_shim` here. - this.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?; + this.check_abi_and_shim_symbol_clash(abi, Conv::C , link_name)?; let result = this.fcntl(args)?; this.write_scalar(result, dest)?; } "dup" => { - let [old_fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [old_fd] = this.check_shim(abi, Conv::C , link_name, args)?; let old_fd = this.read_scalar(old_fd)?.to_i32()?; let new_fd = this.dup(old_fd)?; this.write_scalar(new_fd, dest)?; } "dup2" => { - let [old_fd, new_fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [old_fd, new_fd] = this.check_shim(abi, Conv::C , link_name, args)?; let old_fd = this.read_scalar(old_fd)?.to_i32()?; let new_fd = this.read_scalar(new_fd)?.to_i32()?; let result = this.dup2(old_fd, new_fd)?; this.write_scalar(result, dest)?; } "flock" => { - let [fd, op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, op] = this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let op = this.read_scalar(op)?.to_i32()?; let result = this.flock(fd, op)?; @@ -235,47 +235,47 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // File and file system access "open" | "open64" => { // `open` is variadic, the third argument is only present when the second argument has O_CREAT (or on linux O_TMPFILE, but miri doesn't support that) set - this.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?; + this.check_abi_and_shim_symbol_clash(abi, Conv::C , link_name)?; let result = this.open(args)?; this.write_scalar(result, dest)?; } "unlink" => { - let [path] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [path] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.unlink(path)?; this.write_scalar(result, dest)?; } "symlink" => { - let [target, linkpath] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [target, linkpath] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.symlink(target, linkpath)?; this.write_scalar(result, dest)?; } "rename" => { - let [oldpath, newpath] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [oldpath, newpath] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.rename(oldpath, newpath)?; this.write_scalar(result, dest)?; } "mkdir" => { - let [path, mode] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [path, mode] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.mkdir(path, mode)?; this.write_scalar(result, dest)?; } "rmdir" => { - let [path] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [path] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.rmdir(path)?; this.write_scalar(result, dest)?; } "opendir" => { - let [name] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [name] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.opendir(name)?; this.write_scalar(result, dest)?; } "closedir" => { - let [dirp] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [dirp] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.closedir(dirp)?; this.write_scalar(result, dest)?; } "lseek64" => { - let [fd, offset, whence] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, offset, whence] = this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let offset = this.read_scalar(offset)?.to_i64()?; let whence = this.read_scalar(whence)?.to_i32()?; @@ -283,7 +283,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "lseek" => { - let [fd, offset, whence] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd, offset, whence] = this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?; let whence = this.read_scalar(whence)?.to_i32()?; @@ -292,7 +292,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "ftruncate64" => { let [fd, length] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let length = this.read_scalar(length)?.to_i64()?; let result = this.ftruncate64(fd, length.into())?; @@ -300,30 +300,30 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "ftruncate" => { let [fd, length] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let length = this.read_scalar(length)?.to_int(this.libc_ty_layout("off_t").size)?; let result = this.ftruncate64(fd, length)?; this.write_scalar(result, dest)?; } "fsync" => { - let [fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.fsync(fd)?; this.write_scalar(result, dest)?; } "fdatasync" => { - let [fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.fdatasync(fd)?; this.write_scalar(result, dest)?; } "readlink" => { - let [pathname, buf, bufsize] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [pathname, buf, bufsize] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.readlink(pathname, buf, bufsize)?; this.write_scalar(Scalar::from_target_isize(result, this), dest)?; } "posix_fadvise" => { let [fd, offset, len, advice] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; this.read_scalar(fd)?.to_i32()?; this.read_target_isize(offset)?; this.read_target_isize(len)?; @@ -332,12 +332,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_null(dest)?; } "realpath" => { - let [path, resolved_path] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [path, resolved_path] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.realpath(path, resolved_path)?; this.write_scalar(result, dest)?; } "mkstemp" => { - let [template] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [template] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.mkstemp(template)?; this.write_scalar(result, dest)?; } @@ -345,13 +345,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Unnamed sockets and pipes "socketpair" => { let [domain, type_, protocol, sv] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let result = this.socketpair(domain, type_, protocol, sv)?; this.write_scalar(result, dest)?; } "pipe" => { let [pipefd] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let result = this.pipe2(pipefd, /*flags*/ None)?; this.write_scalar(result, dest)?; } @@ -364,44 +364,44 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); } let [pipefd, flags] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let result = this.pipe2(pipefd, Some(flags))?; this.write_scalar(result, dest)?; } // Time "gettimeofday" => { - let [tv, tz] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [tv, tz] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.gettimeofday(tv, tz)?; this.write_scalar(result, dest)?; } "localtime_r" => { - let [timep, result_op] = this.check_shim(abi, ExternAbi::C {unwind: false}, link_name, args)?; + let [timep, result_op] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.localtime_r(timep, result_op)?; this.write_pointer(result, dest)?; } "clock_gettime" => { let [clk_id, tp] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let result = this.clock_gettime(clk_id, tp)?; this.write_scalar(result, dest)?; } // Allocation "posix_memalign" => { - let [memptr, align, size] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [memptr, align, size] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.posix_memalign(memptr, align, size)?; this.write_scalar(result, dest)?; } "mmap" => { - let [addr, length, prot, flags, fd, offset] = this.check_shim(abi, ExternAbi::C {unwind: false}, link_name, args)?; + let [addr, length, prot, flags, fd, offset] = this.check_shim(abi, Conv::C , link_name, args)?; let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?; let ptr = this.mmap(addr, length, prot, flags, fd, offset)?; this.write_scalar(ptr, dest)?; } "munmap" => { - let [addr, length] = this.check_shim(abi, ExternAbi::C {unwind: false}, link_name, args)?; + let [addr, length] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.munmap(addr, length)?; this.write_scalar(result, dest)?; } @@ -415,7 +415,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); } let [ptr, nmemb, size] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let ptr = this.read_pointer(ptr)?; let nmemb = this.read_target_usize(nmemb)?; let size = this.read_target_usize(size)?; @@ -439,14 +439,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // This is a C11 function, we assume all Unixes have it. // (MSVC explicitly does not support this.) let [align, size] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let res = this.aligned_alloc(align, size)?; this.write_pointer(res, dest)?; } // Dynamic symbol loading "dlsym" => { - let [handle, symbol] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [handle, symbol] = this.check_shim(abi, Conv::C , link_name, args)?; this.read_target_usize(handle)?; let symbol = this.read_pointer(symbol)?; let name = this.read_c_str(symbol)?; @@ -460,7 +460,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Thread-local storage "pthread_key_create" => { - let [key, dtor] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [key, dtor] = this.check_shim(abi, Conv::C , link_name, args)?; let key_place = this.deref_pointer_as(key, this.libc_ty_layout("pthread_key_t"))?; let dtor = this.read_pointer(dtor)?; @@ -488,21 +488,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_null(dest)?; } "pthread_key_delete" => { - let [key] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [key] = this.check_shim(abi, Conv::C , link_name, args)?; let key = this.read_scalar(key)?.to_bits(key.layout.size)?; this.machine.tls.delete_tls_key(key)?; // Return success (0) this.write_null(dest)?; } "pthread_getspecific" => { - let [key] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [key] = this.check_shim(abi, Conv::C , link_name, args)?; let key = this.read_scalar(key)?.to_bits(key.layout.size)?; let active_thread = this.active_thread(); let ptr = this.machine.tls.load_tls(key, active_thread, this)?; this.write_scalar(ptr, dest)?; } "pthread_setspecific" => { - let [key, new_ptr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [key, new_ptr] = this.check_shim(abi, Conv::C , link_name, args)?; let key = this.read_scalar(key)?.to_bits(key.layout.size)?; let active_thread = this.active_thread(); let new_data = this.read_scalar(new_ptr)?; @@ -514,151 +514,151 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Synchronization primitives "pthread_mutexattr_init" => { - let [attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [attr] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_mutexattr_init(attr)?; this.write_null(dest)?; } "pthread_mutexattr_settype" => { - let [attr, kind] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [attr, kind] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.pthread_mutexattr_settype(attr, kind)?; this.write_scalar(result, dest)?; } "pthread_mutexattr_destroy" => { - let [attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [attr] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_mutexattr_destroy(attr)?; this.write_null(dest)?; } "pthread_mutex_init" => { - let [mutex, attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [mutex, attr] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_mutex_init(mutex, attr)?; this.write_null(dest)?; } "pthread_mutex_lock" => { - let [mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [mutex] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_mutex_lock(mutex, dest)?; } "pthread_mutex_trylock" => { - let [mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [mutex] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.pthread_mutex_trylock(mutex)?; this.write_scalar(result, dest)?; } "pthread_mutex_unlock" => { - let [mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [mutex] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.pthread_mutex_unlock(mutex)?; this.write_scalar(result, dest)?; } "pthread_mutex_destroy" => { - let [mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [mutex] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_mutex_destroy(mutex)?; this.write_int(0, dest)?; } "pthread_rwlock_rdlock" => { - let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [rwlock] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_rwlock_rdlock(rwlock, dest)?; } "pthread_rwlock_tryrdlock" => { - let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [rwlock] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.pthread_rwlock_tryrdlock(rwlock)?; this.write_scalar(result, dest)?; } "pthread_rwlock_wrlock" => { - let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [rwlock] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_rwlock_wrlock(rwlock, dest)?; } "pthread_rwlock_trywrlock" => { - let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [rwlock] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.pthread_rwlock_trywrlock(rwlock)?; this.write_scalar(result, dest)?; } "pthread_rwlock_unlock" => { - let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [rwlock] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_rwlock_unlock(rwlock)?; this.write_null(dest)?; } "pthread_rwlock_destroy" => { - let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [rwlock] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_rwlock_destroy(rwlock)?; this.write_null(dest)?; } "pthread_condattr_init" => { - let [attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [attr] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_condattr_init(attr)?; this.write_null(dest)?; } "pthread_condattr_setclock" => { let [attr, clock_id] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let result = this.pthread_condattr_setclock(attr, clock_id)?; this.write_scalar(result, dest)?; } "pthread_condattr_getclock" => { let [attr, clock_id] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_condattr_getclock(attr, clock_id)?; this.write_null(dest)?; } "pthread_condattr_destroy" => { - let [attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [attr] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_condattr_destroy(attr)?; this.write_null(dest)?; } "pthread_cond_init" => { - let [cond, attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [cond, attr] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_cond_init(cond, attr)?; this.write_null(dest)?; } "pthread_cond_signal" => { - let [cond] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [cond] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_cond_signal(cond)?; this.write_null(dest)?; } "pthread_cond_broadcast" => { - let [cond] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [cond] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_cond_broadcast(cond)?; this.write_null(dest)?; } "pthread_cond_wait" => { - let [cond, mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [cond, mutex] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_cond_wait(cond, mutex, dest)?; } "pthread_cond_timedwait" => { - let [cond, mutex, abstime] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [cond, mutex, abstime] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_cond_timedwait(cond, mutex, abstime, dest)?; } "pthread_cond_destroy" => { - let [cond] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [cond] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_cond_destroy(cond)?; this.write_null(dest)?; } // Threading "pthread_create" => { - let [thread, attr, start, arg] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [thread, attr, start, arg] = this.check_shim(abi, Conv::C , link_name, args)?; this.pthread_create(thread, attr, start, arg)?; this.write_null(dest)?; } "pthread_join" => { - let [thread, retval] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [thread, retval] = this.check_shim(abi, Conv::C , link_name, args)?; let res = this.pthread_join(thread, retval)?; this.write_scalar(res, dest)?; } "pthread_detach" => { - let [thread] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [thread] = this.check_shim(abi, Conv::C , link_name, args)?; let res = this.pthread_detach(thread)?; this.write_scalar(res, dest)?; } "pthread_self" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C , link_name, args)?; let res = this.pthread_self()?; this.write_scalar(res, dest)?; } "sched_yield" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C , link_name, args)?; this.sched_yield()?; this.write_null(dest)?; } "nanosleep" => { - let [req, rem] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [req, rem] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.nanosleep(req, rem)?; this.write_scalar(result, dest)?; } @@ -672,7 +672,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let [pid, cpusetsize, mask] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let pid = this.read_scalar(pid)?.to_u32()?; let cpusetsize = this.read_target_usize(cpusetsize)?; let mask = this.read_pointer(mask)?; @@ -712,7 +712,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let [pid, cpusetsize, mask] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let pid = this.read_scalar(pid)?.to_u32()?; let cpusetsize = this.read_target_usize(cpusetsize)?; let mask = this.read_pointer(mask)?; @@ -748,12 +748,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Miscellaneous "isatty" => { - let [fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [fd] = this.check_shim(abi, Conv::C , link_name, args)?; let result = this.isatty(fd)?; this.write_scalar(result, dest)?; } "pthread_atfork" => { - let [prepare, parent, child] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [prepare, parent, child] = this.check_shim(abi, Conv::C , link_name, args)?; this.read_pointer(prepare)?; this.read_pointer(parent)?; this.read_pointer(child)?; @@ -771,7 +771,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let [buf, bufsize] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let buf = this.read_pointer(buf)?; let bufsize = this.read_target_usize(bufsize)?; @@ -790,7 +790,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "strerror_r" => { let [errnum, buf, buflen] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.strerror_r(errnum, buf, buflen)?; this.write_scalar(result, dest)?; } @@ -805,7 +805,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); } let [ptr, len, flags] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let ptr = this.read_pointer(ptr)?; let len = this.read_target_usize(len)?; let _flags = this.read_scalar(flags)?.to_i32()?; @@ -822,7 +822,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.tcx.sess.target.os ); } - let [ptr, len] = this.check_shim(abi, ExternAbi::C { unwind: false}, link_name, args)?; + let [ptr, len] = this.check_shim(abi, Conv::C , link_name, args)?; let ptr = this.read_pointer(ptr)?; let len = this.read_target_usize(len)?; this.gen_random(ptr, len)?; @@ -848,12 +848,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); } // This function looks and behaves excatly like miri_start_unwind. - let [payload] = this.check_shim(abi, ExternAbi::C { unwind: true }, link_name, args)?; + let [payload] = this.check_shim(abi, Conv::C, link_name, args)?; this.handle_miri_start_unwind(payload)?; return interp_ok(EmulateItemResult::NeedsUnwind); } "getuid" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C , link_name, args)?; // For now, just pretend we always have this fixed UID. this.write_int(UID, dest)?; } @@ -862,7 +862,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // These shims are enabled only when the caller is in the standard library. "pthread_attr_getguardsize" if this.frame_in_std() => { - let [_attr, guard_size] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [_attr, guard_size] = this.check_shim(abi, Conv::C , link_name, args)?; let guard_size = this.deref_pointer(guard_size)?; let guard_size_layout = this.libc_ty_layout("size_t"); this.write_scalar(Scalar::from_uint(this.machine.page_size, guard_size_layout.size), &guard_size)?; @@ -874,12 +874,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "pthread_attr_init" | "pthread_attr_destroy" if this.frame_in_std() => { - let [_] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [_] = this.check_shim(abi, Conv::C , link_name, args)?; this.write_null(dest)?; } | "pthread_attr_setstacksize" if this.frame_in_std() => { - let [_, _] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [_, _] = this.check_shim(abi, Conv::C , link_name, args)?; this.write_null(dest)?; } @@ -888,7 +888,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // We don't support "pthread_attr_setstack", so we just pretend all stacks have the same values here. // Hence we can mostly ignore the input `attr_place`. let [attr_place, addr_place, size_place] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; let _attr_place = this.deref_pointer_as(attr_place, this.libc_ty_layout("pthread_attr_t"))?; let addr_place = this.deref_pointer(addr_place)?; let size_place = this.deref_pointer(size_place)?; @@ -909,13 +909,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "signal" | "sigaltstack" if this.frame_in_std() => { - let [_, _] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [_, _] = this.check_shim(abi, Conv::C , link_name, args)?; this.write_null(dest)?; } | "sigaction" | "mprotect" if this.frame_in_std() => { - let [_, _, _] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [_, _, _] = this.check_shim(abi, Conv::C , link_name, args)?; this.write_null(dest)?; } @@ -923,7 +923,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { if this.frame_in_std() => { // getpwuid_r is the standard name, __posix_getpwuid_r is used on solarish let [uid, pwd, buf, buflen, result] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C , link_name, args)?; this.check_no_isolation("`getpwuid_r`")?; let uid = this.read_scalar(uid)?.to_u32()?; diff --git a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs index 0c9bc005ece4..b617e00e5d5e 100644 --- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs @@ -1,5 +1,6 @@ -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use crate::shims::unix::*; use crate::*; @@ -13,7 +14,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -22,7 +23,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Threading "pthread_set_name_np" => { let [thread, name] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let max_len = usize::MAX; // FreeBSD does not seem to have a limit. // FreeBSD's pthread_set_name_np does not return anything. this.pthread_setname_np( @@ -34,7 +35,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "pthread_get_name_np" => { let [thread, name, len] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; // FreeBSD's pthread_get_name_np does not return anything // and uses strlcpy, which truncates the resulting value, // but always adds a null terminator (except for zero-sized buffers). @@ -52,32 +53,32 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // since freebsd 12 the former form can be expected. "stat" | "stat@FBSD_1.0" => { let [path, buf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_stat(path, buf)?; this.write_scalar(result, dest)?; } "lstat" | "lstat@FBSD_1.0" => { let [path, buf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_lstat(path, buf)?; this.write_scalar(result, dest)?; } "fstat" | "fstat@FBSD_1.0" => { let [fd, buf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_fstat(fd, buf)?; this.write_scalar(result, dest)?; } "readdir_r" | "readdir_r@FBSD_1.0" => { let [dirp, entry, result] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_readdir_r(dirp, entry, result)?; this.write_scalar(result, dest)?; } // Miscellaneous "__error" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; let errno_place = this.last_error_place()?; this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?; } @@ -86,7 +87,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // These shims are enabled only when the caller is in the standard library. "pthread_attr_get_np" if this.frame_in_std() => { let [_thread, _attr] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; this.write_null(dest)?; } diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs index bc3619090c08..d7fe909caff5 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -1,5 +1,6 @@ -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use self::shims::unix::linux::mem::EvalContextExt as _; use self::shims::unix::linux_like::epoll::EvalContextExt as _; @@ -24,7 +25,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -36,19 +37,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // File related shims "readdir64" => { let [dirp] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.linux_readdir64(dirp)?; this.write_scalar(result, dest)?; } "sync_file_range" => { let [fd, offset, nbytes, flags] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.sync_file_range(fd, offset, nbytes, flags)?; this.write_scalar(result, dest)?; } "statx" => { let [dirfd, pathname, flags, mask, statxbuf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.linux_statx(dirfd, pathname, flags, mask, statxbuf)?; this.write_scalar(result, dest)?; } @@ -56,24 +57,24 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // epoll, eventfd "epoll_create1" => { let [flag] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.epoll_create1(flag)?; this.write_scalar(result, dest)?; } "epoll_ctl" => { let [epfd, op, fd, event] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.epoll_ctl(epfd, op, fd, event)?; this.write_scalar(result, dest)?; } "epoll_wait" => { let [epfd, events, maxevents, timeout] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; this.epoll_wait(epfd, events, maxevents, timeout, dest)?; } "eventfd" => { let [val, flag] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.eventfd(val, flag)?; this.write_scalar(result, dest)?; } @@ -81,7 +82,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Threading "pthread_setname_np" => { let [thread, name] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let res = match this.pthread_setname_np( this.read_scalar(thread)?, this.read_scalar(name)?, @@ -97,7 +98,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "pthread_getname_np" => { let [thread, name, len] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; // The function's behavior isn't portable between platforms. // In case of glibc, the length of the output buffer must // be not shorter than TASK_COMM_LEN. @@ -120,7 +121,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "gettid" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.linux_gettid()?; this.write_scalar(result, dest)?; } @@ -133,35 +134,35 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Miscellaneous "mmap64" => { let [addr, length, prot, flags, fd, offset] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let offset = this.read_scalar(offset)?.to_i64()?; let ptr = this.mmap(addr, length, prot, flags, fd, offset.into())?; this.write_scalar(ptr, dest)?; } "mremap" => { let [old_address, old_size, new_size, flags] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let ptr = this.mremap(old_address, old_size, new_size, flags)?; this.write_scalar(ptr, dest)?; } "__xpg_strerror_r" => { let [errnum, buf, buflen] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.strerror_r(errnum, buf, buflen)?; this.write_scalar(result, dest)?; } "__errno_location" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; let errno_place = this.last_error_place()?; this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?; } "__libc_current_sigrtmin" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; this.write_int(SIGRTMIN, dest)?; } "__libc_current_sigrtmax" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; this.write_int(SIGRTMAX, dest)?; } @@ -170,7 +171,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // These shims are enabled only when the caller is in the standard library. "pthread_getattr_np" if this.frame_in_std() => { let [_thread, _attr] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; this.write_null(dest)?; } diff --git a/src/tools/miri/src/shims/unix/linux_like/syscall.rs b/src/tools/miri/src/shims/unix/linux_like/syscall.rs index e9a32a263263..57f10ace6a78 100644 --- a/src/tools/miri/src/shims/unix/linux_like/syscall.rs +++ b/src/tools/miri/src/shims/unix/linux_like/syscall.rs @@ -1,5 +1,7 @@ -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; + use crate::helpers::check_min_arg_count; use crate::shims::unix::linux_like::eventfd::EvalContextExt as _; @@ -9,13 +11,13 @@ use crate::*; pub fn syscall<'tcx>( ecx: &mut MiriInterpCx<'tcx>, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { // We do not use `check_shim` here because `syscall` is variadic. The argument // count is checked bellow. - ecx.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?; + ecx.check_abi_and_shim_symbol_clash(abi, Conv::C, link_name)?; // The syscall variadic function is legal to call with more arguments than needed, // extra arguments are simply ignored. The important check is that when we use an // argument, we have to also check all arguments *before* it to ensure that they diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs index 103bea086208..3be6967b7c2f 100644 --- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs @@ -1,5 +1,6 @@ -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use super::sync::EvalContextExt as _; use crate::shims::unix::*; @@ -14,7 +15,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -25,7 +26,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // errno "__error" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; let errno_place = this.last_error_place()?; this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?; } @@ -33,50 +34,50 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // File related shims "close$NOCANCEL" => { let [result] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.close(result)?; this.write_scalar(result, dest)?; } "stat" | "stat64" | "stat$INODE64" => { let [path, buf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_stat(path, buf)?; this.write_scalar(result, dest)?; } "lstat" | "lstat64" | "lstat$INODE64" => { let [path, buf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_lstat(path, buf)?; this.write_scalar(result, dest)?; } "fstat" | "fstat64" | "fstat$INODE64" => { let [fd, buf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_fstat(fd, buf)?; this.write_scalar(result, dest)?; } "opendir$INODE64" => { let [name] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.opendir(name)?; this.write_scalar(result, dest)?; } "readdir_r" | "readdir_r$INODE64" => { let [dirp, entry, result] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_readdir_r(dirp, entry, result)?; this.write_scalar(result, dest)?; } "realpath$DARWIN_EXTSN" => { let [path, resolved_path] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.realpath(path, resolved_path)?; this.write_scalar(result, dest)?; } // Environment related shims "_NSGetEnviron" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; let environ = this.machine.env_vars.unix().environ(); this.write_pointer(environ, dest)?; } @@ -84,7 +85,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Random data generation "CCRandomGenerateBytes" => { let [bytes, count] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let bytes = this.read_pointer(bytes)?; let count = this.read_target_usize(count)?; let success = this.eval_libc_i32("kCCSuccess"); @@ -94,30 +95,30 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Time related shims "mach_absolute_time" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.mach_absolute_time()?; this.write_scalar(result, dest)?; } "mach_timebase_info" => { let [info] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.mach_timebase_info(info)?; this.write_scalar(result, dest)?; } // Access to command-line arguments "_NSGetArgc" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; this.write_pointer(this.machine.argc.expect("machine must be initialized"), dest)?; } "_NSGetArgv" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; this.write_pointer(this.machine.argv.expect("machine must be initialized"), dest)?; } "_NSGetExecutablePath" => { let [buf, bufsize] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; this.check_no_isolation("`_NSGetExecutablePath`")?; let buf_ptr = this.read_pointer(buf)?; @@ -143,7 +144,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Thread-local storage "_tlv_atexit" => { let [dtor, data] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let dtor = this.read_pointer(dtor)?; let dtor = this.get_ptr_fn(dtor)?.as_instance()?; let data = this.read_scalar(data)?; @@ -154,14 +155,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Querying system information "pthread_get_stackaddr_np" => { let [thread] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; this.read_target_usize(thread)?; let stack_addr = Scalar::from_uint(this.machine.stack_addr, this.pointer_size()); this.write_scalar(stack_addr, dest)?; } "pthread_get_stacksize_np" => { let [thread] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; this.read_target_usize(thread)?; let stack_size = Scalar::from_uint(this.machine.stack_size, this.pointer_size()); this.write_scalar(stack_size, dest)?; @@ -170,7 +171,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Threading "pthread_setname_np" => { let [name] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; // The real implementation has logic in two places: // * in userland at https://github.com/apple-oss-distributions/libpthread/blob/c032e0b076700a0a47db75528a282b8d3a06531a/src/pthread.c#L1178-L1200, @@ -198,7 +199,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "pthread_getname_np" => { let [thread, name, len] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; // The function's behavior isn't portable between platforms. // In case of macOS, a truncated name (due to a too small buffer) @@ -224,27 +225,27 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "os_unfair_lock_lock" => { let [lock_op] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; this.os_unfair_lock_lock(lock_op)?; } "os_unfair_lock_trylock" => { let [lock_op] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; this.os_unfair_lock_trylock(lock_op, dest)?; } "os_unfair_lock_unlock" => { let [lock_op] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; this.os_unfair_lock_unlock(lock_op)?; } "os_unfair_lock_assert_owner" => { let [lock_op] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; this.os_unfair_lock_assert_owner(lock_op)?; } "os_unfair_lock_assert_not_owner" => { let [lock_op] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; this.os_unfair_lock_assert_not_owner(lock_op)?; } diff --git a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs index e45291703684..fa67b6c939e2 100644 --- a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs @@ -1,5 +1,6 @@ -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use crate::shims::unix::foreign_items::EvalContextExt as _; use crate::shims::unix::*; @@ -14,7 +15,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -23,7 +24,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Threading "pthread_setname_np" => { let [thread, name] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; // THREAD_NAME_MAX allows a thread name of 31+1 length // https://github.com/illumos/illumos-gate/blob/7671517e13b8123748eda4ef1ee165c6d9dba7fe/usr/src/uts/common/sys/thread.h#L613 let max_len = 32; @@ -42,7 +43,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "pthread_getname_np" => { let [thread, name, len] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; // See https://illumos.org/man/3C/pthread_getname_np for the error codes. let res = match this.pthread_getname_np( this.read_scalar(thread)?, @@ -60,33 +61,33 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // File related shims "stat" | "stat64" => { let [path, buf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_stat(path, buf)?; this.write_scalar(result, dest)?; } "lstat" | "lstat64" => { let [path, buf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_lstat(path, buf)?; this.write_scalar(result, dest)?; } "fstat" | "fstat64" => { let [fd, buf] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_fstat(fd, buf)?; this.write_scalar(result, dest)?; } // Miscellaneous "___errno" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; let errno_place = this.last_error_place()?; this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?; } "stack_getbounds" => { let [stack] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let stack = this.deref_pointer_as(stack, this.libc_ty_layout("stack_t"))?; this.write_int_fields_named( @@ -105,7 +106,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "pset_info" => { let [pset, tpe, cpus, list] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; // We do not need to handle the current process cpu mask, available_parallelism // implementation pass null anyway. We only care for the number of // cpus. @@ -135,7 +136,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "__sysconf_xpg7" => { let [val] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.sysconf(val)?; this.write_scalar(result, dest)?; } diff --git a/src/tools/miri/src/shims/wasi/foreign_items.rs b/src/tools/miri/src/shims/wasi/foreign_items.rs index 2c349203d465..facb6f8ce3a9 100644 --- a/src/tools/miri/src/shims/wasi/foreign_items.rs +++ b/src/tools/miri/src/shims/wasi/foreign_items.rs @@ -1,5 +1,6 @@ -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use crate::shims::alloc::EvalContextExt as _; use crate::*; @@ -13,7 +14,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -22,13 +23,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Allocation "posix_memalign" => { let [memptr, align, size] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let result = this.posix_memalign(memptr, align, size)?; this.write_scalar(result, dest)?; } "aligned_alloc" => { let [align, size] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let res = this.aligned_alloc(align, size)?; this.write_pointer(res, dest)?; } diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index d6a180451d7a..dd531c5956f6 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -2,8 +2,10 @@ use std::ffi::OsStr; use std::path::{self, Path, PathBuf}; use std::{io, iter, str}; -use rustc_abi::{Align, ExternAbi, Size}; +use rustc_abi::{Align, Size}; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use self::shims::windows::handle::{Handle, PseudoHandle}; use crate::shims::os_str::bytes_to_os_str; @@ -83,12 +85,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { let this = self.eval_context_mut(); + // According to + // https://github.com/rust-lang/rust/blob/fb00adbdb69266f10df95a4527b767b0ad35ea48/compiler/rustc_target/src/spec/mod.rs#L2766-L2768, + // x86-32 Windows uses a different calling convention than other Windows targets + // for the "system" ABI. + let sys_conv = if this.tcx.sess.target.arch == "x86" { Conv::X86Stdcall } else { Conv::C }; + // See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern. // Windows API stubs. @@ -101,49 +109,49 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Environment related shims "GetEnvironmentVariableW" => { let [name, buf, size] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let result = this.GetEnvironmentVariableW(name, buf, size)?; this.write_scalar(result, dest)?; } "SetEnvironmentVariableW" => { let [name, value] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let result = this.SetEnvironmentVariableW(name, value)?; this.write_scalar(result, dest)?; } "GetEnvironmentStringsW" => { let [] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let result = this.GetEnvironmentStringsW()?; this.write_pointer(result, dest)?; } "FreeEnvironmentStringsW" => { let [env_block] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let result = this.FreeEnvironmentStringsW(env_block)?; this.write_scalar(result, dest)?; } "GetCurrentDirectoryW" => { let [size, buf] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let result = this.GetCurrentDirectoryW(size, buf)?; this.write_scalar(result, dest)?; } "SetCurrentDirectoryW" => { let [path] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let result = this.SetCurrentDirectoryW(path)?; this.write_scalar(result, dest)?; } "GetUserProfileDirectoryW" => { let [token, buf, size] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let result = this.GetUserProfileDirectoryW(token, buf, size)?; this.write_scalar(result, dest)?; } "GetCurrentProcessId" => { let [] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let result = this.GetCurrentProcessId()?; this.write_scalar(result, dest)?; } @@ -166,7 +174,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { n, byte_offset, _key, - ] = this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + ] = this.check_shim(abi, sys_conv, link_name, args)?; let handle = this.read_target_isize(handle)?; let buf = this.read_pointer(buf)?; let n = this.read_scalar(n)?.to_u32()?; @@ -218,7 +226,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "GetFullPathNameW" => { let [filename, size, buffer, filepart] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.check_no_isolation("`GetFullPathNameW`")?; let filename = this.read_pointer(filename)?; @@ -250,7 +258,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Allocation "HeapAlloc" => { let [handle, flags, size] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.read_target_isize(handle)?; let flags = this.read_scalar(flags)?.to_u32()?; let size = this.read_target_usize(size)?; @@ -274,7 +282,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "HeapFree" => { let [handle, flags, ptr] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.read_target_isize(handle)?; this.read_scalar(flags)?.to_u32()?; let ptr = this.read_pointer(ptr)?; @@ -287,7 +295,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "HeapReAlloc" => { let [handle, flags, old_ptr, size] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.read_target_isize(handle)?; this.read_scalar(flags)?.to_u32()?; let old_ptr = this.read_pointer(old_ptr)?; @@ -307,7 +315,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "LocalFree" => { let [ptr] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let ptr = this.read_pointer(ptr)?; // "If the hMem parameter is NULL, LocalFree ignores the parameter and returns NULL." // (https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-localfree) @@ -320,13 +328,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // errno "SetLastError" => { let [error] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let error = this.read_scalar(error)?; this.set_last_error(error)?; } "GetLastError" => { let [] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let last_error = this.get_last_error()?; this.write_scalar(last_error, dest)?; } @@ -335,7 +343,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetSystemInfo" => { // Also called from `page_size` crate. let [system_info] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let system_info = this.deref_pointer_as(system_info, this.windows_ty_layout("SYSTEM_INFO"))?; // Initialize with `0`. @@ -359,13 +367,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Create key and return it. let [] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let key = this.machine.tls.create_tls_key(None, dest.layout.size)?; this.write_scalar(Scalar::from_uint(key, dest.layout.size), dest)?; } "TlsGetValue" => { let [key] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let key = u128::from(this.read_scalar(key)?.to_u32()?); let active_thread = this.active_thread(); let ptr = this.machine.tls.load_tls(key, active_thread, this)?; @@ -373,7 +381,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "TlsSetValue" => { let [key, new_ptr] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let key = u128::from(this.read_scalar(key)?.to_u32()?); let active_thread = this.active_thread(); let new_data = this.read_scalar(new_ptr)?; @@ -383,8 +391,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_int(1, dest)?; } "TlsFree" => { - let [key] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + let [key] = this.check_shim(abi, sys_conv, link_name, args)?; let key = u128::from(this.read_scalar(key)?.to_u32()?); this.machine.tls.delete_tls_key(key)?; @@ -395,7 +402,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Access to command-line arguments "GetCommandLineW" => { let [] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.write_pointer( this.machine.cmd_line.expect("machine must be initialized"), dest, @@ -406,32 +413,32 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetSystemTimeAsFileTime" | "GetSystemTimePreciseAsFileTime" => { #[allow(non_snake_case)] let [LPFILETIME] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.GetSystemTimeAsFileTime(link_name.as_str(), LPFILETIME)?; } "QueryPerformanceCounter" => { #[allow(non_snake_case)] let [lpPerformanceCount] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let result = this.QueryPerformanceCounter(lpPerformanceCount)?; this.write_scalar(result, dest)?; } "QueryPerformanceFrequency" => { #[allow(non_snake_case)] let [lpFrequency] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let result = this.QueryPerformanceFrequency(lpFrequency)?; this.write_scalar(result, dest)?; } "Sleep" => { let [timeout] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.Sleep(timeout)?; } "CreateWaitableTimerExW" => { let [attributes, name, flags, access] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.read_pointer(attributes)?; this.read_pointer(name)?; this.read_scalar(flags)?.to_u32()?; @@ -445,30 +452,30 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Synchronization primitives "InitOnceBeginInitialize" => { let [ptr, flags, pending, context] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.InitOnceBeginInitialize(ptr, flags, pending, context, dest)?; } "InitOnceComplete" => { let [ptr, flags, context] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let result = this.InitOnceComplete(ptr, flags, context)?; this.write_scalar(result, dest)?; } "WaitOnAddress" => { let [ptr_op, compare_op, size_op, timeout_op] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.WaitOnAddress(ptr_op, compare_op, size_op, timeout_op, dest)?; } "WakeByAddressSingle" => { let [ptr_op] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.WakeByAddressSingle(ptr_op)?; } "WakeByAddressAll" => { let [ptr_op] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.WakeByAddressAll(ptr_op)?; } @@ -477,7 +484,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetProcAddress" => { #[allow(non_snake_case)] let [hModule, lpProcName] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.read_target_isize(hModule)?; let name = this.read_c_str(this.read_pointer(lpProcName)?)?; if let Ok(name) = str::from_utf8(name) @@ -493,7 +500,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Threading "CreateThread" => { let [security, stacksize, start, arg, flags, thread] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let thread_id = this.CreateThread(security, stacksize, start, arg, flags, thread)?; @@ -502,14 +509,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "WaitForSingleObject" => { let [handle, timeout] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let ret = this.WaitForSingleObject(handle, timeout)?; this.write_scalar(ret, dest)?; } "GetCurrentThread" => { let [] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.write_scalar( Handle::Pseudo(PseudoHandle::CurrentThread).to_scalar(this), @@ -518,7 +525,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "SetThreadDescription" => { let [handle, name] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let handle = this.read_scalar(handle)?; let name = this.read_wide_str(this.read_pointer(name)?)?; @@ -543,7 +550,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "GetThreadDescription" => { let [handle, name_ptr] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let handle = this.read_scalar(handle)?; let name_ptr = this.deref_pointer(name_ptr)?; // the pointer where we should store the ptr to the name @@ -575,7 +582,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Miscellaneous "ExitProcess" => { let [code] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let code = this.read_scalar(code)?.to_u32()?; throw_machine_stop!(TerminationInfo::Exit { code: code.into(), leak_check: false }); } @@ -583,7 +590,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // used by getrandom 0.1 // This is really 'RtlGenRandom'. let [ptr, len] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let ptr = this.read_pointer(ptr)?; let len = this.read_scalar(len)?.to_u32()?; this.gen_random(ptr, len.into())?; @@ -592,7 +599,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "ProcessPrng" => { // used by `std` let [ptr, len] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let ptr = this.read_pointer(ptr)?; let len = this.read_target_usize(len)?; this.gen_random(ptr, len)?; @@ -601,7 +608,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "BCryptGenRandom" => { // used by getrandom 0.2 let [algorithm, ptr, len, flags] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let algorithm = this.read_scalar(algorithm)?; let algorithm = algorithm.to_target_usize(this)?; let ptr = this.read_pointer(ptr)?; @@ -636,7 +643,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetConsoleScreenBufferInfo" => { // `term` needs this, so we fake it. let [console, buffer_info] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.read_target_isize(console)?; // FIXME: this should use deref_pointer_as, but CONSOLE_SCREEN_BUFFER_INFO is not in std this.deref_pointer(buffer_info)?; @@ -646,7 +653,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "GetStdHandle" => { let [which] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let which = this.read_scalar(which)?.to_i32()?; // We just make this the identity function, so we know later in `NtWriteFile` which // one it is. This is very fake, but libtest needs it so we cannot make it a @@ -656,7 +663,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "CloseHandle" => { let [handle] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let ret = this.CloseHandle(handle)?; @@ -664,7 +671,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "GetModuleFileNameW" => { let [handle, filename, size] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.check_no_isolation("`GetModuleFileNameW`")?; let handle = this.read_target_usize(handle)?; @@ -698,7 +705,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "FormatMessageW" => { let [flags, module, message_id, language_id, buffer, size, arguments] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; let flags = this.read_scalar(flags)?.to_u32()?; let _module = this.read_pointer(module)?; // seems to contain a module name @@ -734,7 +741,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // These shims are enabled only when the caller is in the standard library. "GetProcessHeap" if this.frame_in_std() => { let [] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; // Just fake a HANDLE // It's fine to not use the Handle type here because its a stub this.write_int(1, dest)?; @@ -742,20 +749,20 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetModuleHandleA" if this.frame_in_std() => { #[allow(non_snake_case)] let [_lpModuleName] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; // We need to return something non-null here to make `compat_fn!` work. this.write_int(1, dest)?; } "SetConsoleTextAttribute" if this.frame_in_std() => { #[allow(non_snake_case)] let [_hConsoleOutput, _wAttribute] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; // Pretend these does not exist / nothing happened, by returning zero. this.write_null(dest)?; } "GetConsoleMode" if this.frame_in_std() => { let [console, mode] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.read_target_isize(console)?; this.deref_pointer(mode)?; // Indicate an error. @@ -764,28 +771,28 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetFileType" if this.frame_in_std() => { #[allow(non_snake_case)] let [_hFile] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; // Return unknown file type. this.write_null(dest)?; } "AddVectoredExceptionHandler" if this.frame_in_std() => { #[allow(non_snake_case)] let [_First, _Handler] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; // Any non zero value works for the stdlib. This is just used for stack overflows anyway. this.write_int(1, dest)?; } "SetThreadStackGuarantee" if this.frame_in_std() => { #[allow(non_snake_case)] let [_StackSizeInBytes] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; // Any non zero value works for the stdlib. This is just used for stack overflows anyway. this.write_int(1, dest)?; } // this is only callable from std because we know that std ignores the return value "SwitchToThread" if this.frame_in_std() => { let [] = - this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, sys_conv, link_name, args)?; this.yield_active_thread(); @@ -805,7 +812,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // This function looks and behaves excatly like miri_start_unwind. let [payload] = - this.check_shim(abi, ExternAbi::C { unwind: true }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; this.handle_miri_start_unwind(payload)?; return interp_ok(EmulateItemResult::NeedsUnwind); } diff --git a/src/tools/miri/src/shims/x86/aesni.rs b/src/tools/miri/src/shims/x86/aesni.rs index 4c6c1cefeb1d..a89a2bb0cd08 100644 --- a/src/tools/miri/src/shims/x86/aesni.rs +++ b/src/tools/miri/src/shims/x86/aesni.rs @@ -1,7 +1,7 @@ -use rustc_abi::ExternAbi; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf as _; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use crate::*; @@ -10,7 +10,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_aesni_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -27,8 +27,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdec_si128 "aesdec" | "aesdec.256" | "aesdec.512" => { let [state, key] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; - + this.check_shim(abi, Conv::C, link_name, args)?; aes_round(this, state, key, dest, |state, key| { let key = aes::Block::from(key.to_le_bytes()); let mut state = aes::Block::from(state.to_le_bytes()); @@ -45,7 +44,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdeclast_si128 "aesdeclast" | "aesdeclast.256" | "aesdeclast.512" => { let [state, key] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; aes_round(this, state, key, dest, |state, key| { let mut state = aes::Block::from(state.to_le_bytes()); @@ -70,8 +69,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenc_si128 "aesenc" | "aesenc.256" | "aesenc.512" => { let [state, key] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; - + this.check_shim(abi, Conv::C, link_name, args)?; aes_round(this, state, key, dest, |state, key| { let key = aes::Block::from(key.to_le_bytes()); let mut state = aes::Block::from(state.to_le_bytes()); @@ -88,8 +86,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenclast_si128 "aesenclast" | "aesenclast.256" | "aesenclast.512" => { let [state, key] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; - + this.check_shim(abi, Conv::C, link_name, args)?; aes_round(this, state, key, dest, |state, key| { let mut state = aes::Block::from(state.to_le_bytes()); // `aes::hazmat::cipher_round` does the following operations: @@ -109,8 +106,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the _mm_aesimc_si128 function. // Performs the AES InvMixColumns operation on `op` "aesimc" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; - + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; // Transmute to `u128` let op = op.transmute(this.machine.layouts.u128, this)?; let dest = dest.transmute(this.machine.layouts.u128, this)?; diff --git a/src/tools/miri/src/shims/x86/avx.rs b/src/tools/miri/src/shims/x86/avx.rs index 3971fa3b913f..07bbd0731d81 100644 --- a/src/tools/miri/src/shims/x86/avx.rs +++ b/src/tools/miri/src/shims/x86/avx.rs @@ -1,9 +1,9 @@ -use rustc_abi::ExternAbi; use rustc_apfloat::ieee::{Double, Single}; use rustc_middle::mir; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf as _; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use super::{ FloatBinOp, FloatUnaryOp, bin_op_simd_float_all, conditional_dot_product, convert_float_to_int, @@ -17,7 +17,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_avx_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -34,7 +34,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // semantics. "min.ps.256" | "max.ps.256" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "min.ps.256" => FloatBinOp::Min, @@ -47,7 +47,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement _mm256_min_pd and _mm256_max_pd functions. "min.pd.256" | "max.pd.256" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "min.pd.256" => FloatBinOp::Min, @@ -61,7 +61,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Rounds the elements of `op` according to `rounding`. "round.ps.256" => { let [op, rounding] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; round_all::(this, op, rounding, dest)?; } @@ -69,14 +69,14 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Rounds the elements of `op` according to `rounding`. "round.pd.256" => { let [op, rounding] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; round_all::(this, op, rounding, dest)?; } // Used to implement _mm256_{rcp,rsqrt}_ps functions. // Performs the operations on all components of `op`. "rcp.ps.256" | "rsqrt.ps.256" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "rcp.ps.256" => FloatUnaryOp::Rcp, @@ -89,7 +89,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the _mm256_dp_ps function. "dp.ps.256" => { let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; conditional_dot_product(this, left, right, imm, dest)?; } @@ -98,7 +98,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // in `left` and `right`. "hadd.ps.256" | "hadd.pd.256" | "hsub.ps.256" | "hsub.pd.256" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "hadd.ps.256" | "hadd.pd.256" => mir::BinOp::Add, @@ -114,7 +114,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // if true. "cmp.ps.256" => { let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -127,7 +127,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // if true. "cmp.pd.256" => { let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -138,7 +138,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // and _mm256_cvttpd_epi32 functions. // Converts packed f32/f64 to packed i32. "cvt.ps2dq.256" | "cvtt.ps2dq.256" | "cvt.pd2dq.256" | "cvtt.pd2dq.256" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; let rnd = match unprefixed_name { // "current SSE rounding mode", assume nearest @@ -157,7 +157,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `control` determines which element of the current `data` array is written. "vpermilvar.ps" | "vpermilvar.ps.256" => { let [data, control] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (data, data_len) = this.project_to_simd(data)?; let (control, control_len) = this.project_to_simd(control)?; @@ -191,7 +191,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // written. "vpermilvar.pd" | "vpermilvar.pd.256" => { let [data, control] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (data, data_len) = this.project_to_simd(data)?; let (control, control_len) = this.project_to_simd(control)?; @@ -224,7 +224,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // zero, according to `imm`. "vperm2f128.ps.256" | "vperm2f128.pd.256" | "vperm2f128.si.256" => { let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; assert_eq!(dest.layout, left.layout); assert_eq!(dest.layout, right.layout); @@ -268,7 +268,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // loaded. "maskload.ps" | "maskload.pd" | "maskload.ps.256" | "maskload.pd.256" => { let [ptr, mask] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; mask_load(this, ptr, mask, dest)?; } @@ -279,7 +279,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Unlike SSE2's _mm_maskmoveu_si128, these are not non-temporal stores. "maskstore.ps" | "maskstore.pd" | "maskstore.ps.256" | "maskstore.pd.256" => { let [ptr, mask, value] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; mask_store(this, ptr, mask, value)?; } @@ -290,7 +290,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // unaligned read. "ldu.dq.256" => { let [src_ptr] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let src_ptr = this.read_pointer(src_ptr)?; let dest = dest.force_mplace(this)?; @@ -303,7 +303,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `op & mask != 0 && op & mask != mask` "ptestz.256" | "ptestc.256" | "ptestnzc.256" => { let [op, mask] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (all_zero, masked_set) = test_bits_masked(this, op, mask)?; let res = match unprefixed_name { @@ -327,7 +327,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "vtestnzc.pd" | "vtestz.ps.256" | "vtestc.ps.256" | "vtestnzc.ps.256" | "vtestz.ps" | "vtestc.ps" | "vtestnzc.ps" => { let [op, mask] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (direct, negated) = test_high_bits_masked(this, op, mask)?; let res = match unprefixed_name { @@ -349,7 +349,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // compiler, making these functions no-ops. // The only thing that needs to be ensured is the correct calling convention. - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; } _ => return interp_ok(EmulateItemResult::NotSupported), } diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs index 6aefb87d4d0e..76e4b06d5cfd 100644 --- a/src/tools/miri/src/shims/x86/avx2.rs +++ b/src/tools/miri/src/shims/x86/avx2.rs @@ -1,8 +1,8 @@ -use rustc_abi::ExternAbi; use rustc_middle::mir; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf as _; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use super::{ ShiftOp, horizontal_bin_op, int_abs, mask_load, mask_store, mpsadbw, packssdw, packsswb, @@ -15,7 +15,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_avx2_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -28,7 +28,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the _mm256_abs_epi{8,16,32} functions. // Calculates the absolute value of packed 8/16/32-bit integers. "pabs.b" | "pabs.w" | "pabs.d" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; int_abs(this, op, dest)?; } @@ -37,7 +37,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // integer values in `left` and `right`. "phadd.w" | "phadd.sw" | "phadd.d" | "phsub.w" | "phsub.sw" | "phsub.d" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (which, saturating) = match unprefixed_name { "phadd.w" | "phadd.d" => (mir::BinOp::Add, false), @@ -58,7 +58,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "gather.d.pd.256" | "gather.q.pd" | "gather.q.pd.256" | "gather.d.ps" | "gather.d.ps.256" | "gather.q.ps" | "gather.q.ps.256" => { let [src, slice, offsets, mask, scale] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; assert_eq!(dest.layout, src.layout); @@ -116,7 +116,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // intermediate 32-bit integers, and pack the results in `dest`. "pmadd.wd" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -153,7 +153,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // produces the output at index `i`. "pmadd.ub.sw" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -188,7 +188,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // loaded. "maskload.d" | "maskload.q" | "maskload.d.256" | "maskload.q.256" => { let [ptr, mask] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; mask_load(this, ptr, mask, dest)?; } @@ -199,7 +199,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Unlike SSE2's _mm_maskmoveu_si128, these are not non-temporal stores. "maskstore.d" | "maskstore.q" | "maskstore.d.256" | "maskstore.q.256" => { let [ptr, mask, value] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; mask_store(this, ptr, mask, value)?; } @@ -211,7 +211,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_mpsadbw_epu8 "mpsadbw" => { let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; mpsadbw(this, left, right, imm, dest)?; } @@ -223,7 +223,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_mulhrs_epi16 "pmul.hr.sw" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; pmulhrsw(this, left, right, dest)?; } @@ -232,7 +232,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // vector with signed saturation. "packsswb" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; packsswb(this, left, right, dest)?; } @@ -241,7 +241,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // vector with signed saturation. "packssdw" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; packssdw(this, left, right, dest)?; } @@ -250,7 +250,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // unsigned integer vector with saturation. "packuswb" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; packuswb(this, left, right, dest)?; } @@ -259,7 +259,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // the result to a 16-bit unsigned integer vector with saturation. "packusdw" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; packusdw(this, left, right, dest)?; } @@ -269,7 +269,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // as indices. "permd" | "permps" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -290,7 +290,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Shuffles 128-bit blocks of `a` and `b` using `imm` as pattern. "vperm2i128" => { let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; assert_eq!(left.layout.size.bits(), 256); assert_eq!(right.layout.size.bits(), 256); @@ -328,7 +328,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_sad_epu8 "psad.bw" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -361,7 +361,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Each 128-bit block is shuffled independently. "pshuf.b" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -393,7 +393,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Basically, we multiply `left` with `right.signum()`. "psign.b" | "psign.w" | "psign.d" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; psign(this, left, right, dest)?; } @@ -408,7 +408,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "psll.w" | "psrl.w" | "psra.w" | "psll.d" | "psrl.d" | "psra.d" | "psll.q" | "psrl.q" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "psll.w" | "psll.d" | "psll.q" => ShiftOp::Left, @@ -424,7 +424,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "psllv.d" | "psllv.d.256" | "psllv.q" | "psllv.q.256" | "psrlv.d" | "psrlv.d.256" | "psrlv.q" | "psrlv.q.256" | "psrav.d" | "psrav.d.256" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "psllv.d" | "psllv.d.256" | "psllv.q" | "psllv.q.256" => ShiftOp::Left, diff --git a/src/tools/miri/src/shims/x86/bmi.rs b/src/tools/miri/src/shims/x86/bmi.rs index 0f9e8d6f0258..b52807647384 100644 --- a/src/tools/miri/src/shims/x86/bmi.rs +++ b/src/tools/miri/src/shims/x86/bmi.rs @@ -1,5 +1,6 @@ -use rustc_abi::ExternAbi; use rustc_span::Symbol; +use rustc_middle::ty::Ty; +use rustc_target::callconv::{Conv, FnAbi}; use crate::*; @@ -8,7 +9,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_bmi_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -34,7 +35,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let left = this.read_scalar(left)?; let right = this.read_scalar(right)?; diff --git a/src/tools/miri/src/shims/x86/gfni.rs b/src/tools/miri/src/shims/x86/gfni.rs index 92010345f55d..48718ea609c4 100644 --- a/src/tools/miri/src/shims/x86/gfni.rs +++ b/src/tools/miri/src/shims/x86/gfni.rs @@ -1,5 +1,6 @@ -use rustc_abi::ExternAbi; use rustc_span::Symbol; +use rustc_middle::ty::Ty; +use rustc_target::callconv::{Conv, FnAbi}; use crate::*; @@ -8,7 +9,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_gfni_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -30,7 +31,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8affine_ "vgf2p8affineqb.128" | "vgf2p8affineqb.256" | "vgf2p8affineqb.512" => { let [left, right, imm8] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; affine_transform(this, left, right, imm8, dest, /* inverse */ false)?; } // Used to implement the `_mm{, 256, 512}_gf2p8affineinv_epi64_epi8` functions. @@ -38,7 +39,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8affineinv "vgf2p8affineinvqb.128" | "vgf2p8affineinvqb.256" | "vgf2p8affineinvqb.512" => { let [left, right, imm8] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; affine_transform(this, left, right, imm8, dest, /* inverse */ true)?; } // Used to implement the `_mm{, 256, 512}_gf2p8mul_epi8` functions. @@ -48,8 +49,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8mul "vgf2p8mulb.128" | "vgf2p8mulb.256" | "vgf2p8mulb.512" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; - + this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; let (dest, dest_len) = this.project_to_simd(dest)?; diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 3e02a4b36376..13439f421286 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -1,10 +1,11 @@ -use rustc_abi::{ExternAbi, Size}; +use rustc_abi::Size; use rustc_apfloat::Float; use rustc_apfloat::ieee::Single; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::{mir, ty}; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use self::helpers::bool_to_simd_element; use crate::*; @@ -27,7 +28,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -45,8 +46,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { return interp_ok(EmulateItemResult::NotSupported); } - let [cb_in, a, b] = this.check_shim(abi, ExternAbi::Unadjusted, link_name, args)?; - + let [cb_in, a, b] = this.check_shim(abi, Conv::C, link_name, args)?; let op = if unprefixed_name.starts_with("add") { mir::BinOp::AddWithOverflow } else { @@ -68,9 +68,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { if is_u64 && this.tcx.sess.target.arch != "x86_64" { return interp_ok(EmulateItemResult::NotSupported); } - let [c_in, a, b, out] = - this.check_shim(abi, ExternAbi::Unadjusted, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let out = this.deref_pointer_as( out, if is_u64 { this.machine.layouts.u64 } else { this.machine.layouts.u32 }, @@ -87,7 +86,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // the instruction behaves like a no-op, so it is always safe to call the // intrinsic. "sse2.pause" => { - let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; // Only exhibit the spin-loop hint behavior when SSE2 is enabled. if this.tcx.sess.unstable_target_features.contains(&Symbol::intern("sse2")) { this.yield_active_thread(); @@ -107,7 +106,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; pclmulqdq(this, left, right, imm, dest, len)?; } diff --git a/src/tools/miri/src/shims/x86/sha.rs b/src/tools/miri/src/shims/x86/sha.rs index f18ff1ec253b..07cc87a35bf5 100644 --- a/src/tools/miri/src/shims/x86/sha.rs +++ b/src/tools/miri/src/shims/x86/sha.rs @@ -4,8 +4,9 @@ //! //! [RustCrypto's sha256 module]: https://github.com/RustCrypto/hashes/blob/6be8466247e936c415d8aafb848697f39894a386/sha2/src/sha256/soft.rs -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use crate::*; @@ -14,7 +15,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sha_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -52,7 +53,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the _mm_sha256rnds2_epu32 function. "256rnds2" => { let [a, b, k] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (a_reg, a_len) = this.project_to_simd(a)?; let (b_reg, b_len) = this.project_to_simd(b)?; @@ -74,7 +75,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the _mm_sha256msg1_epu32 function. "256msg1" => { let [a, b] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (a_reg, a_len) = this.project_to_simd(a)?; let (b_reg, b_len) = this.project_to_simd(b)?; @@ -93,7 +94,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the _mm_sha256msg2_epu32 function. "256msg2" => { let [a, b] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (a_reg, a_len) = this.project_to_simd(a)?; let (b_reg, b_len) = this.project_to_simd(b)?; diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs index 9432b40a8058..e13265fba4f0 100644 --- a/src/tools/miri/src/shims/x86/sse.rs +++ b/src/tools/miri/src/shims/x86/sse.rs @@ -1,6 +1,7 @@ -use rustc_abi::ExternAbi; use rustc_apfloat::ieee::Single; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use super::{ FloatBinOp, FloatUnaryOp, bin_op_simd_float_all, bin_op_simd_float_first, unary_op_ps, @@ -13,7 +14,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sse_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -33,7 +34,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `right` and copies the remaining components from `left`. "min.ss" | "max.ss" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "min.ss" => FloatBinOp::Min, @@ -50,7 +51,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // semantics. "min.ps" | "max.ps" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "min.ps" => FloatBinOp::Min, @@ -64,7 +65,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Performs the operations on the first component of `op` and // copies the remaining components from `op`. "rcp.ss" | "rsqrt.ss" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "rcp.ss" => FloatUnaryOp::Rcp, @@ -77,7 +78,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement _mm_{sqrt,rcp,rsqrt}_ps functions. // Performs the operations on all components of `op`. "rcp.ps" | "rsqrt.ps" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "rcp.ps" => FloatUnaryOp::Rcp, @@ -97,7 +98,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // with hard-coded operations. "cmp.ss" => { let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -114,7 +115,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // with hard-coded operations. "cmp.ps" => { let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -128,7 +129,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "ucomieq.ss" | "ucomilt.ss" | "ucomile.ss" | "ucomigt.ss" | "ucomige.ss" | "ucomineq.ss" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -156,7 +157,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // _mm_cvtss_si64 and _mm_cvttss_si64 functions. // Converts the first component of `op` from f32 to i32/i64. "cvtss2si" | "cvttss2si" | "cvtss2si64" | "cvttss2si64" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; let (op, _) = this.project_to_simd(op)?; let op = this.read_immediate(&this.project_index(&op, 0)?)?; @@ -185,7 +186,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.felixcloutier.com/x86/cvtsi2ss "cvtsi2ss" | "cvtsi642ss" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (dest, dest_len) = this.project_to_simd(dest)?; diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index 4ff999be7cc9..959590e9791f 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -1,6 +1,7 @@ -use rustc_abi::ExternAbi; use rustc_apfloat::ieee::Double; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use super::{ FloatBinOp, ShiftOp, bin_op_simd_float_all, bin_op_simd_float_first, convert_float_to_int, @@ -13,7 +14,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sse2_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -40,7 +41,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // intermediate 32-bit integers, and pack the results in `dest`. "pmadd.wd" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -79,7 +80,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sad_epu8 "psad.bw" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -118,7 +119,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "psll.w" | "psrl.w" | "psra.w" | "psll.d" | "psrl.d" | "psra.d" | "psll.q" | "psrl.q" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "psll.w" | "psll.d" | "psll.q" => ShiftOp::Left, @@ -133,7 +134,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // and _mm_cvttpd_epi32 functions. // Converts packed f32/f64 to packed i32. "cvtps2dq" | "cvttps2dq" | "cvtpd2dq" | "cvttpd2dq" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; let (op_len, _) = op.layout.ty.simd_size_and_type(*this.tcx); let (dest_len, _) = dest.layout.ty.simd_size_and_type(*this.tcx); @@ -171,7 +172,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // vector with signed saturation. "packsswb.128" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; packsswb(this, left, right, dest)?; } @@ -180,7 +181,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // unsigned integer vector with saturation. "packuswb.128" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; packuswb(this, left, right, dest)?; } @@ -189,7 +190,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // vector with signed saturation. "packssdw.128" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; packssdw(this, left, right, dest)?; } @@ -200,7 +201,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // semantics. "min.sd" | "max.sd" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "min.sd" => FloatBinOp::Min, @@ -217,7 +218,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // semantics. "min.pd" | "max.pd" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "min.pd" => FloatBinOp::Min, @@ -237,7 +238,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // with hard-coded operations. "cmp.sd" => { let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -254,7 +255,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // with hard-coded operations. "cmp.pd" => { let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -268,7 +269,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "ucomieq.sd" | "ucomilt.sd" | "ucomile.sd" | "ucomigt.sd" | "ucomige.sd" | "ucomineq.sd" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -296,7 +297,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // _mm_cvtsd_si64 and _mm_cvttsd_si64 functions. // Converts the first component of `op` from f64 to i32/i64. "cvtsd2si" | "cvttsd2si" | "cvtsd2si64" | "cvttsd2si64" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; let (op, _) = this.project_to_simd(op)?; let op = this.read_immediate(&this.project_index(&op, 0)?)?; @@ -323,7 +324,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // the remaining elements from `left` "cvtsd2ss" | "cvtss2sd" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, _) = this.project_to_simd(right)?; diff --git a/src/tools/miri/src/shims/x86/sse3.rs b/src/tools/miri/src/shims/x86/sse3.rs index 86153d71b284..4ebd0240b1d3 100644 --- a/src/tools/miri/src/shims/x86/sse3.rs +++ b/src/tools/miri/src/shims/x86/sse3.rs @@ -1,6 +1,7 @@ -use rustc_abi::ExternAbi; use rustc_middle::mir; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use super::horizontal_bin_op; use crate::*; @@ -10,7 +11,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sse3_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -25,7 +26,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // in `left` and `right`. "hadd.ps" | "hadd.pd" | "hsub.ps" | "hsub.pd" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "hadd.ps" | "hadd.pd" => mir::BinOp::Add, @@ -42,7 +43,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // unaligned read. "ldu.dq" => { let [src_ptr] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let src_ptr = this.read_pointer(src_ptr)?; let dest = dest.force_mplace(this)?; diff --git a/src/tools/miri/src/shims/x86/sse41.rs b/src/tools/miri/src/shims/x86/sse41.rs index b81d6f24141b..41b7feab857b 100644 --- a/src/tools/miri/src/shims/x86/sse41.rs +++ b/src/tools/miri/src/shims/x86/sse41.rs @@ -1,5 +1,6 @@ -use rustc_abi::ExternAbi; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use super::{conditional_dot_product, mpsadbw, packusdw, round_all, round_first, test_bits_masked}; use crate::*; @@ -9,7 +10,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sse41_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -27,7 +28,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `i` is zeroed. "insertps" => { let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -63,7 +64,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // the result to a 16-bit unsigned integer vector with saturation. "packusdw" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; packusdw(this, left, right, dest)?; } @@ -74,7 +75,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // 4 bits of `imm`. "dpps" | "dppd" => { let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; conditional_dot_product(this, left, right, imm, dest)?; } @@ -83,7 +84,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // and copies the remaining elements from `left`. "round.ss" => { let [left, right, rounding] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; round_first::(this, left, right, rounding, dest)?; } @@ -91,7 +92,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // functions. Rounds the elements of `op` according to `rounding`. "round.ps" => { let [op, rounding] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; round_all::(this, op, rounding, dest)?; } @@ -100,7 +101,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // and copies the remaining elements from `left`. "round.sd" => { let [left, right, rounding] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; round_first::(this, left, right, rounding, dest)?; } @@ -108,7 +109,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // functions. Rounds the elements of `op` according to `rounding`. "round.pd" => { let [op, rounding] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; round_all::(this, op, rounding, dest)?; } @@ -116,7 +117,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Find the minimum unsinged 16-bit integer in `op` and // returns its value and position. "phminposuw" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; let (op, op_len) = this.project_to_simd(op)?; let (dest, dest_len) = this.project_to_simd(dest)?; @@ -151,7 +152,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mpsadbw_epu8 "mpsadbw" => { let [left, right, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; mpsadbw(this, left, right, imm, dest)?; } @@ -161,7 +162,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `(op & mask) != 0 && (op & mask) != mask` "ptestz" | "ptestc" | "ptestnzc" => { let [op, mask] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (all_zero, masked_set) = test_bits_masked(this, op, mask)?; let res = match unprefixed_name { diff --git a/src/tools/miri/src/shims/x86/sse42.rs b/src/tools/miri/src/shims/x86/sse42.rs index 0b058a9911e2..6ac69d22a934 100644 --- a/src/tools/miri/src/shims/x86/sse42.rs +++ b/src/tools/miri/src/shims/x86/sse42.rs @@ -1,8 +1,9 @@ -use rustc_abi::{ExternAbi, Size}; +use rustc_abi::Size; use rustc_middle::mir; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf as _; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use crate::*; @@ -200,7 +201,7 @@ fn deconstruct_args<'tcx>( unprefixed_name: &str, ecx: &mut MiriInterpCx<'tcx>, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], ) -> InterpResult<'tcx, (OpTy<'tcx>, OpTy<'tcx>, Option<(u64, u64)>, u8)> { let array_layout_fn = |ecx: &mut MiriInterpCx<'tcx>, imm: u8| { @@ -223,7 +224,7 @@ fn deconstruct_args<'tcx>( if is_explicit { let [str1, len1, str2, len2, imm] = - ecx.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + ecx.check_shim(abi, Conv::C, link_name, args)?; let imm = ecx.read_scalar(imm)?.to_u8()?; let default_len = default_len::(imm); @@ -237,7 +238,7 @@ fn deconstruct_args<'tcx>( interp_ok((str1, str2, Some((len1, len2)), imm)) } else { let [str1, str2, imm] = - ecx.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + ecx.check_shim(abi, Conv::C, link_name, args)?; let imm = ecx.read_scalar(imm)?.to_u8()?; let array_layout = array_layout_fn(ecx, imm)?; @@ -279,7 +280,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sse42_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -388,7 +389,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=924,925 "pcmpistriz128" | "pcmpistris128" => { let [str1, str2, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let imm = this.read_scalar(imm)?.to_u8()?; let str = if unprefixed_name == "pcmpistris128" { str1 } else { str2 }; @@ -409,7 +410,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=1046,1047 "pcmpestriz128" | "pcmpestris128" => { let [_, len1, _, len2, imm] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let len = if unprefixed_name == "pcmpestris128" { len1 } else { len2 }; let len = this.read_scalar(len)?.to_i32()?; let imm = this.read_scalar(imm)?.to_u8()?; @@ -437,7 +438,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let left = this.read_scalar(left)?; let right = this.read_scalar(right)?; diff --git a/src/tools/miri/src/shims/x86/ssse3.rs b/src/tools/miri/src/shims/x86/ssse3.rs index cdab78bc7427..d3971d0c92f1 100644 --- a/src/tools/miri/src/shims/x86/ssse3.rs +++ b/src/tools/miri/src/shims/x86/ssse3.rs @@ -1,6 +1,7 @@ -use rustc_abi::ExternAbi; use rustc_middle::mir; +use rustc_middle::ty::Ty; use rustc_span::Symbol; +use rustc_target::callconv::{Conv, FnAbi}; use super::{horizontal_bin_op, int_abs, pmulhrsw, psign}; use crate::*; @@ -10,7 +11,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_ssse3_intrinsic( &mut self, link_name: Symbol, - abi: ExternAbi, + abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -23,7 +24,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the _mm_abs_epi{8,16,32} functions. // Calculates the absolute value of packed 8/16/32-bit integers. "pabs.b.128" | "pabs.w.128" | "pabs.d.128" => { - let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; int_abs(this, op, dest)?; } @@ -32,7 +33,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_shuffle_epi8 "pshuf.b.128" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -62,7 +63,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "phadd.w.128" | "phadd.sw.128" | "phadd.d.128" | "phsub.w.128" | "phsub.sw.128" | "phsub.d.128" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (which, saturating) = match unprefixed_name { "phadd.w.128" | "phadd.d.128" => (mir::BinOp::Add, false), @@ -82,7 +83,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_maddubs_epi16 "pmadd.ub.sw.128" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -118,7 +119,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mulhrs_epi16 "pmul.hr.sw.128" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; pmulhrsw(this, left, right, dest)?; } @@ -129,7 +130,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Basically, we multiply `left` with `right.signum()`. "psign.b.128" | "psign.w.128" | "psign.d.128" => { let [left, right] = - this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, Conv::C, link_name, args)?; psign(this, left, right, dest)?; } From 25a9d62211ad1b1a89951497952f9aa1ca332d01 Mon Sep 17 00:00:00 2001 From: Adrian Taylor Date: Thu, 19 Dec 2024 15:30:44 +0000 Subject: [PATCH 07/24] Arbitrary self types v2: roll loop. Just for slightly more concise code - no functional changes. r? @wesleywiser --- compiler/rustc_hir_typeck/src/method/probe.rs | 27 +++++++------------ 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 3b377076545d..f07153afc066 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1230,23 +1230,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { if let Some(by_value_pick) = by_value_pick { if let Ok(by_value_pick) = by_value_pick.as_ref() { if by_value_pick.kind == PickKind::InherentImplPick { - if let Err(e) = self.check_for_shadowed_autorefd_method( - by_value_pick, - step, - self_ty, - hir::Mutability::Not, - track_unstable_candidates, - ) { - return Some(Err(e)); - } - if let Err(e) = self.check_for_shadowed_autorefd_method( - by_value_pick, - step, - self_ty, - hir::Mutability::Mut, - track_unstable_candidates, - ) { - return Some(Err(e)); + for mutbl in [hir::Mutability::Not, hir::Mutability::Mut] { + if let Err(e) = self.check_for_shadowed_autorefd_method( + by_value_pick, + step, + self_ty, + mutbl, + track_unstable_candidates, + ) { + return Some(Err(e)); + } } } } From 57e1a47dc4ef07c52db70737b1dee3944f729f95 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 11 Dec 2024 11:30:37 -0800 Subject: [PATCH 08/24] Rename TyAssocConstItem -> RequiredAssocConstItem --- src/librustdoc/clean/mod.rs | 4 ++-- src/librustdoc/clean/types.rs | 16 ++++++++++------ src/librustdoc/fold.rs | 2 +- src/librustdoc/formats/cache.rs | 4 ++-- src/librustdoc/formats/item_type.rs | 2 +- src/librustdoc/html/render/mod.rs | 6 +++--- src/librustdoc/html/render/print_item.rs | 3 ++- src/librustdoc/html/render/sidebar.rs | 2 +- src/librustdoc/json/conversions.rs | 2 +- .../passes/check_doc_test_visibility.rs | 2 +- src/librustdoc/passes/propagate_stability.rs | 2 +- src/librustdoc/passes/stripper.rs | 4 +++- src/librustdoc/visit.rs | 2 +- 13 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 25f88c8797f8..a96be7052621 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1229,7 +1229,7 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext })), hir::TraitItemKind::Const(ty, None) => { let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); - TyAssocConstItem(generics, Box::new(clean_ty(ty, cx))) + RequiredAssocConstItem(generics, Box::new(clean_ty(ty, cx))) } hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => { let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Body(body)); @@ -1331,7 +1331,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo type_: ty, })) } else { - TyAssocConstItem(generics, Box::new(ty)) + RequiredAssocConstItem(generics, Box::new(ty)) } } ty::AssocKind::Fn => { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index cba947eb833b..f3f0b72d65db 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -553,8 +553,8 @@ impl Item { pub(crate) fn is_associated_const(&self) -> bool { matches!(self.kind, AssocConstItem(..) | StrippedItem(box AssocConstItem(..))) } - pub(crate) fn is_ty_associated_const(&self) -> bool { - matches!(self.kind, TyAssocConstItem(..) | StrippedItem(box TyAssocConstItem(..))) + pub(crate) fn is_required_associated_const(&self) -> bool { + matches!(self.kind, RequiredAssocConstItem(..) | StrippedItem(box RequiredAssocConstItem(..))) } pub(crate) fn is_method(&self) -> bool { self.type_() == ItemType::Method @@ -701,8 +701,12 @@ impl Item { // Variants always inherit visibility VariantItem(..) | ImplItem(..) => return None, // Trait items inherit the trait's visibility - AssocConstItem(..) | TyAssocConstItem(..) | AssocTypeItem(..) | TyAssocTypeItem(..) - | TyMethodItem(..) | MethodItem(..) => { + AssocConstItem(..) + | RequiredAssocConstItem(..) + | AssocTypeItem(..) + | TyAssocTypeItem(..) + | TyMethodItem(..) + | MethodItem(..) => { let assoc_item = tcx.associated_item(def_id); let is_trait_item = match assoc_item.container { ty::AssocItemContainer::Trait => true, @@ -864,7 +868,7 @@ pub(crate) enum ItemKind { ProcMacroItem(ProcMacro), PrimitiveItem(PrimitiveType), /// A required associated constant in a trait declaration. - TyAssocConstItem(Generics, Box), + RequiredAssocConstItem(Generics, Box), ConstantItem(Box), /// An associated constant in a trait impl or a provided one in a trait declaration. AssocConstItem(Box), @@ -911,7 +915,7 @@ impl ItemKind { | MacroItem(_) | ProcMacroItem(_) | PrimitiveItem(_) - | TyAssocConstItem(..) + | RequiredAssocConstItem(..) | AssocConstItem(..) | TyAssocTypeItem(..) | AssocTypeItem(..) diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index 95e495205aea..604d588586d0 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -91,7 +91,7 @@ pub(crate) trait DocFolder: Sized { | MacroItem(_) | ProcMacroItem(_) | PrimitiveItem(_) - | TyAssocConstItem(..) + | RequiredAssocConstItem(..) | AssocConstItem(..) | TyAssocTypeItem(..) | AssocTypeItem(..) diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index e387eb010beb..f8f26c203f42 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -337,7 +337,7 @@ impl DocFolder for CacheBuilder<'_, '_> { | clean::TyMethodItem(..) | clean::MethodItem(..) | clean::StructFieldItem(..) - | clean::TyAssocConstItem(..) + | clean::RequiredAssocConstItem(..) | clean::AssocConstItem(..) | clean::TyAssocTypeItem(..) | clean::AssocTypeItem(..) @@ -450,7 +450,7 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It return; } clean::TyMethodItem(..) - | clean::TyAssocConstItem(..) + | clean::RequiredAssocConstItem(..) | clean::TyAssocTypeItem(..) | clean::StructFieldItem(..) | clean::VariantItem(..) => { diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs index 383e3135faa8..43170cecad59 100644 --- a/src/librustdoc/formats/item_type.rs +++ b/src/librustdoc/formats/item_type.rs @@ -96,7 +96,7 @@ impl<'a> From<&'a clean::Item> for ItemType { clean::ForeignStaticItem(..) => ItemType::Static, // no ForeignStatic clean::MacroItem(..) => ItemType::Macro, clean::PrimitiveItem(..) => ItemType::Primitive, - clean::TyAssocConstItem(..) | clean::AssocConstItem(..) => ItemType::AssocConst, + clean::RequiredAssocConstItem(..) | clean::AssocConstItem(..) => ItemType::AssocConst, clean::TyAssocTypeItem(..) | clean::AssocTypeItem(..) => ItemType::AssocType, clean::ForeignTypeItem => ItemType::ForeignType, clean::KeywordItem => ItemType::Keyword, diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index e013829e5e0c..7bccd6cc7df9 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1081,7 +1081,7 @@ fn render_assoc_item( clean::MethodItem(m, _) => { assoc_method(w, item, &m.generics, &m.decl, link, parent, cx, render_mode) } - clean::TyAssocConstItem(generics, ty) => assoc_const( + clean::RequiredAssocConstItem(generics, ty) => assoc_const( w, item, generics, @@ -1689,7 +1689,7 @@ fn render_impl( w.write_str(""); } } - clean::TyAssocConstItem(ref generics, ref ty) => { + clean::RequiredAssocConstItem(ref generics, ref ty) => { let source_id = format!("{item_type}.{name}"); let id = cx.derive_id(&source_id); write!(w, "
"); @@ -1812,7 +1812,7 @@ fn render_impl( clean::TyAssocTypeItem(..) | clean::AssocTypeItem(..) => { assoc_types.push(trait_item) } - clean::TyAssocConstItem(..) | clean::AssocConstItem(_) => { + clean::RequiredAssocConstItem(..) | clean::AssocConstItem(_) => { // We render it directly since they're supposed to come first. doc_impl_item( &mut default_impl_items, diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 4c8d704e65bc..c2ffd8e764f2 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -653,7 +653,8 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra let bounds = bounds(&t.bounds, false, cx); let required_types = t.items.iter().filter(|m| m.is_ty_associated_type()).collect::>(); let provided_types = t.items.iter().filter(|m| m.is_associated_type()).collect::>(); - let required_consts = t.items.iter().filter(|m| m.is_ty_associated_const()).collect::>(); + let required_consts = + t.items.iter().filter(|m| m.is_required_associated_const()).collect::>(); let provided_consts = t.items.iter().filter(|m| m.is_associated_const()).collect::>(); let required_methods = t.items.iter().filter(|m| m.is_ty_method()).collect::>(); let provided_methods = t.items.iter().filter(|m| m.is_method()).collect::>(); diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index e99e2f04b2c5..031510c006ec 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -285,7 +285,7 @@ fn sidebar_trait<'a>( let req_assoc = filter_items(&t.items, |m| m.is_ty_associated_type(), "associatedtype"); let prov_assoc = filter_items(&t.items, |m| m.is_associated_type(), "associatedtype"); let req_assoc_const = - filter_items(&t.items, |m| m.is_ty_associated_const(), "associatedconstant"); + filter_items(&t.items, |m| m.is_required_associated_const(), "associatedconstant"); let prov_assoc_const = filter_items(&t.items, |m| m.is_associated_const(), "associatedconstant"); let req_method = filter_items(&t.items, |m| m.is_ty_method(), "tymethod"); diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index bb967b7f163e..d83ac2c7648d 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -339,7 +339,7 @@ fn from_clean_item(item: clean::Item, renderer: &JsonRenderer<'_>) -> ItemEnum { }) } // FIXME(generic_const_items): Add support for generic associated consts. - TyAssocConstItem(_generics, ty) => { + RequiredAssocConstItem(_generics, ty) => { ItemEnum::AssocConst { type_: (*ty).into_json(renderer), value: None } } // FIXME(generic_const_items): Add support for generic associated consts. diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index c288a3cf2a47..465569c13632 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -74,7 +74,7 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) - | clean::ForeignTypeItem | clean::AssocConstItem(..) | clean::AssocTypeItem(..) - | clean::TyAssocConstItem(..) + | clean::RequiredAssocConstItem(..) | clean::TyAssocTypeItem(..) // check for trait impl | clean::ImplItem(box clean::Impl { trait_: Some(_), .. }) diff --git a/src/librustdoc/passes/propagate_stability.rs b/src/librustdoc/passes/propagate_stability.rs index a81b130a218b..d534ee56e458 100644 --- a/src/librustdoc/passes/propagate_stability.rs +++ b/src/librustdoc/passes/propagate_stability.rs @@ -69,7 +69,7 @@ impl DocFolder for StabilityPropagator<'_, '_> { ItemKind::ImplItem(..) | ItemKind::TyMethodItem(..) | ItemKind::MethodItem(..) - | ItemKind::TyAssocConstItem(..) + | ItemKind::RequiredAssocConstItem(..) | ItemKind::AssocConstItem(..) | ItemKind::TyAssocTypeItem(..) | ItemKind::AssocTypeItem(..) diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index 60909754b333..3994f634f154 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -118,7 +118,9 @@ impl DocFolder for Stripper<'_, '_> { clean::ImplItem(..) => {} // tymethods etc. have no control over privacy - clean::TyMethodItem(..) | clean::TyAssocConstItem(..) | clean::TyAssocTypeItem(..) => {} + clean::TyMethodItem(..) + | clean::RequiredAssocConstItem(..) + | clean::TyAssocTypeItem(..) => {} // Proc-macros are always public clean::ProcMacroItem(..) => {} diff --git a/src/librustdoc/visit.rs b/src/librustdoc/visit.rs index c2e8ffd7665b..43a33e0ac1db 100644 --- a/src/librustdoc/visit.rs +++ b/src/librustdoc/visit.rs @@ -44,7 +44,7 @@ pub(crate) trait DocVisitor<'a>: Sized { | MacroItem(_) | ProcMacroItem(_) | PrimitiveItem(_) - | TyAssocConstItem(..) + | RequiredAssocConstItem(..) | AssocConstItem(..) | TyAssocTypeItem(..) | AssocTypeItem(..) From 044885c8ae8e296963327b7b60cd4e08118104e3 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 11 Dec 2024 11:34:50 -0800 Subject: [PATCH 09/24] Split AssocConstItem into ProvidedAssocConstItem and ImplAssocConstItem --- src/librustdoc/clean/mod.rs | 37 +++++++++++-------- src/librustdoc/clean/types.rs | 16 +++++--- src/librustdoc/fold.rs | 3 +- src/librustdoc/formats/cache.rs | 12 ++++-- src/librustdoc/formats/item_type.rs | 4 +- src/librustdoc/html/render/mod.rs | 8 ++-- src/librustdoc/json/conversions.rs | 2 +- .../passes/check_doc_test_visibility.rs | 3 +- src/librustdoc/passes/propagate_stability.rs | 3 +- src/librustdoc/passes/stripper.rs | 5 ++- src/librustdoc/visit.rs | 3 +- 11 files changed, 62 insertions(+), 34 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a96be7052621..51ff70a69fe6 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1222,11 +1222,13 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext let local_did = trait_item.owner_id.to_def_id(); cx.with_param_env(local_did, |cx| { let inner = match trait_item.kind { - hir::TraitItemKind::Const(ty, Some(default)) => AssocConstItem(Box::new(Constant { - generics: enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)), - kind: ConstantKind::Local { def_id: local_did, body: default }, - type_: clean_ty(ty, cx), - })), + hir::TraitItemKind::Const(ty, Some(default)) => { + ProvidedAssocConstItem(Box::new(Constant { + generics: enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)), + kind: ConstantKind::Local { def_id: local_did, body: default }, + type_: clean_ty(ty, cx), + })) + } hir::TraitItemKind::Const(ty, None) => { let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); RequiredAssocConstItem(generics, Box::new(clean_ty(ty, cx))) @@ -1271,7 +1273,7 @@ pub(crate) fn clean_impl_item<'tcx>( let local_did = impl_.owner_id.to_def_id(); cx.with_param_env(local_did, |cx| { let inner = match impl_.kind { - hir::ImplItemKind::Const(ty, expr) => AssocConstItem(Box::new(Constant { + hir::ImplItemKind::Const(ty, expr) => ImplAssocConstItem(Box::new(Constant { generics: clean_generics(impl_.generics, cx), kind: ConstantKind::Local { def_id: local_did, body: expr }, type_: clean_ty(ty, cx), @@ -1320,18 +1322,23 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo ); simplify::move_bounds_to_generic_parameters(&mut generics); - let provided = match assoc_item.container { - ty::AssocItemContainer::Impl => true, - ty::AssocItemContainer::Trait => tcx.defaultness(assoc_item.def_id).has_value(), - }; - if provided { - AssocConstItem(Box::new(Constant { + match assoc_item.container { + ty::AssocItemContainer::Impl => ImplAssocConstItem(Box::new(Constant { generics, kind: ConstantKind::Extern { def_id: assoc_item.def_id }, type_: ty, - })) - } else { - RequiredAssocConstItem(generics, Box::new(ty)) + })), + ty::AssocItemContainer::Trait => { + if tcx.defaultness(assoc_item.def_id).has_value() { + ProvidedAssocConstItem(Box::new(Constant { + generics, + kind: ConstantKind::Extern { def_id: assoc_item.def_id }, + type_: ty, + })) + } else { + RequiredAssocConstItem(generics, Box::new(ty)) + } + } } } ty::AssocKind::Fn => { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index f3f0b72d65db..feec8ac5b22c 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -551,7 +551,7 @@ impl Item { matches!(self.kind, TyAssocTypeItem(..) | StrippedItem(box TyAssocTypeItem(..))) } pub(crate) fn is_associated_const(&self) -> bool { - matches!(self.kind, AssocConstItem(..) | StrippedItem(box AssocConstItem(..))) + matches!(self.kind, ProvidedAssocConstItem(..) | ImplAssocConstItem(..) | StrippedItem(box (ProvidedAssocConstItem(..) | ImplAssocConstItem(..)))) } pub(crate) fn is_required_associated_const(&self) -> bool { matches!(self.kind, RequiredAssocConstItem(..) | StrippedItem(box RequiredAssocConstItem(..))) @@ -701,8 +701,9 @@ impl Item { // Variants always inherit visibility VariantItem(..) | ImplItem(..) => return None, // Trait items inherit the trait's visibility - AssocConstItem(..) - | RequiredAssocConstItem(..) + RequiredAssocConstItem(..) + | ProvidedAssocConstItem(..) + | ImplAssocConstItem(..) | AssocTypeItem(..) | TyAssocTypeItem(..) | TyMethodItem(..) @@ -870,8 +871,10 @@ pub(crate) enum ItemKind { /// A required associated constant in a trait declaration. RequiredAssocConstItem(Generics, Box), ConstantItem(Box), - /// An associated constant in a trait impl or a provided one in a trait declaration. - AssocConstItem(Box), + /// An associated constant in a trait declaration with provided default value. + ProvidedAssocConstItem(Box), + /// An associated constant in an inherent impl or trait impl. + ImplAssocConstItem(Box), /// A required associated type in a trait declaration. /// /// The bounds may be non-empty if there is a `where` clause. @@ -916,7 +919,8 @@ impl ItemKind { | ProcMacroItem(_) | PrimitiveItem(_) | RequiredAssocConstItem(..) - | AssocConstItem(..) + | ProvidedAssocConstItem(..) + | ImplAssocConstItem(..) | TyAssocTypeItem(..) | AssocTypeItem(..) | StrippedItem(_) diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index 604d588586d0..d2e3b9ce2e4e 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -92,7 +92,8 @@ pub(crate) trait DocFolder: Sized { | ProcMacroItem(_) | PrimitiveItem(_) | RequiredAssocConstItem(..) - | AssocConstItem(..) + | ProvidedAssocConstItem(..) + | ImplAssocConstItem(..) | TyAssocTypeItem(..) | AssocTypeItem(..) | KeywordItem => kind, diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index f8f26c203f42..a87979ab186e 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -338,7 +338,8 @@ impl DocFolder for CacheBuilder<'_, '_> { | clean::MethodItem(..) | clean::StructFieldItem(..) | clean::RequiredAssocConstItem(..) - | clean::AssocConstItem(..) + | clean::ProvidedAssocConstItem(..) + | clean::ImplAssocConstItem(..) | clean::TyAssocTypeItem(..) | clean::AssocTypeItem(..) | clean::StrippedItem(..) @@ -443,7 +444,9 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It let item_def_id = item.item_id.as_def_id().unwrap(); let (parent_did, parent_path) = match item.kind { clean::StrippedItem(..) => return, - clean::AssocConstItem(..) | clean::AssocTypeItem(..) + clean::ProvidedAssocConstItem(..) + | clean::ImplAssocConstItem(..) + | clean::AssocTypeItem(..) if cache.parent_stack.last().is_some_and(|parent| parent.is_trait_impl()) => { // skip associated items in trait impls @@ -467,7 +470,10 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It let parent_path = &cache.stack[..cache.stack.len() - 1]; (Some(parent_did), parent_path) } - clean::MethodItem(..) | clean::AssocConstItem(..) | clean::AssocTypeItem(..) => { + clean::MethodItem(..) + | clean::ProvidedAssocConstItem(..) + | clean::ImplAssocConstItem(..) + | clean::AssocTypeItem(..) => { let last = cache.parent_stack.last().expect("parent_stack is empty 2"); let parent_did = match last { // impl Trait for &T { fn method(self); } diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs index 43170cecad59..8f5e26d0104b 100644 --- a/src/librustdoc/formats/item_type.rs +++ b/src/librustdoc/formats/item_type.rs @@ -96,7 +96,9 @@ impl<'a> From<&'a clean::Item> for ItemType { clean::ForeignStaticItem(..) => ItemType::Static, // no ForeignStatic clean::MacroItem(..) => ItemType::Macro, clean::PrimitiveItem(..) => ItemType::Primitive, - clean::RequiredAssocConstItem(..) | clean::AssocConstItem(..) => ItemType::AssocConst, + clean::RequiredAssocConstItem(..) + | clean::ProvidedAssocConstItem(..) + | clean::ImplAssocConstItem(..) => ItemType::AssocConst, clean::TyAssocTypeItem(..) | clean::AssocTypeItem(..) => ItemType::AssocType, clean::ForeignTypeItem => ItemType::ForeignType, clean::KeywordItem => ItemType::Keyword, diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 7bccd6cc7df9..4d9faf2f5680 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1091,7 +1091,7 @@ fn render_assoc_item( if parent == ItemType::Trait { 4 } else { 0 }, cx, ), - clean::AssocConstItem(ci) => assoc_const( + clean::ProvidedAssocConstItem(ci) | clean::ImplAssocConstItem(ci) => assoc_const( w, item, &ci.generics, @@ -1711,7 +1711,7 @@ fn render_impl( ); w.write_str("
"); } - clean::AssocConstItem(ci) => { + clean::ProvidedAssocConstItem(ci) | clean::ImplAssocConstItem(ci) => { let source_id = format!("{item_type}.{name}"); let id = cx.derive_id(&source_id); write!(w, "
"); @@ -1812,7 +1812,9 @@ fn render_impl( clean::TyAssocTypeItem(..) | clean::AssocTypeItem(..) => { assoc_types.push(trait_item) } - clean::RequiredAssocConstItem(..) | clean::AssocConstItem(_) => { + clean::RequiredAssocConstItem(..) + | clean::ProvidedAssocConstItem(_) + | clean::ImplAssocConstItem(_) => { // We render it directly since they're supposed to come first. doc_impl_item( &mut default_impl_items, diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index d83ac2c7648d..36a0aa0fdfac 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -343,7 +343,7 @@ fn from_clean_item(item: clean::Item, renderer: &JsonRenderer<'_>) -> ItemEnum { ItemEnum::AssocConst { type_: (*ty).into_json(renderer), value: None } } // FIXME(generic_const_items): Add support for generic associated consts. - AssocConstItem(ci) => ItemEnum::AssocConst { + ProvidedAssocConstItem(ci) | ImplAssocConstItem(ci) => ItemEnum::AssocConst { type_: ci.type_.into_json(renderer), value: Some(ci.kind.expr(renderer.tcx)), }, diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index 465569c13632..2b0af187b2da 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -72,9 +72,10 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) - | clean::ForeignFunctionItem(..) | clean::ForeignStaticItem(..) | clean::ForeignTypeItem - | clean::AssocConstItem(..) | clean::AssocTypeItem(..) | clean::RequiredAssocConstItem(..) + | clean::ProvidedAssocConstItem(..) + | clean::ImplAssocConstItem(..) | clean::TyAssocTypeItem(..) // check for trait impl | clean::ImplItem(box clean::Impl { trait_: Some(_), .. }) diff --git a/src/librustdoc/passes/propagate_stability.rs b/src/librustdoc/passes/propagate_stability.rs index d534ee56e458..1f9dc7536606 100644 --- a/src/librustdoc/passes/propagate_stability.rs +++ b/src/librustdoc/passes/propagate_stability.rs @@ -70,7 +70,8 @@ impl DocFolder for StabilityPropagator<'_, '_> { | ItemKind::TyMethodItem(..) | ItemKind::MethodItem(..) | ItemKind::RequiredAssocConstItem(..) - | ItemKind::AssocConstItem(..) + | ItemKind::ProvidedAssocConstItem(..) + | ItemKind::ImplAssocConstItem(..) | ItemKind::TyAssocTypeItem(..) | ItemKind::AssocTypeItem(..) | ItemKind::PrimitiveItem(..) diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index 3994f634f154..7dc7856405ee 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -79,7 +79,10 @@ impl DocFolder for Stripper<'_, '_> { } } - clean::MethodItem(..) | clean::AssocConstItem(..) | clean::AssocTypeItem(..) => { + clean::MethodItem(..) + | clean::ProvidedAssocConstItem(..) + | clean::ImplAssocConstItem(..) + | clean::AssocTypeItem(..) => { let item_id = i.item_id; if item_id.is_local() && !self.effective_visibilities.is_reachable(self.tcx, item_id.expect_def_id()) diff --git a/src/librustdoc/visit.rs b/src/librustdoc/visit.rs index 43a33e0ac1db..397ff8873a34 100644 --- a/src/librustdoc/visit.rs +++ b/src/librustdoc/visit.rs @@ -45,7 +45,8 @@ pub(crate) trait DocVisitor<'a>: Sized { | ProcMacroItem(_) | PrimitiveItem(_) | RequiredAssocConstItem(..) - | AssocConstItem(..) + | ProvidedAssocConstItem(..) + | ImplAssocConstItem(..) | TyAssocTypeItem(..) | AssocTypeItem(..) | KeywordItem => {} From da89d10264d641a67c506f6c85c77d876613c06f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 14 Dec 2024 15:33:47 -0800 Subject: [PATCH 10/24] Add test for rustdoc showing underscore as assoc const value --- tests/rustdoc/assoc-consts-underscore.rs | 27 ++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 tests/rustdoc/assoc-consts-underscore.rs diff --git a/tests/rustdoc/assoc-consts-underscore.rs b/tests/rustdoc/assoc-consts-underscore.rs new file mode 100644 index 000000000000..9bb44f0a03c7 --- /dev/null +++ b/tests/rustdoc/assoc-consts-underscore.rs @@ -0,0 +1,27 @@ +pub struct Struct { + _private: (), +} + +pub trait Trait { + //@ has assoc_consts_underscore/trait.Trait.html '//pre[@class="rust item-decl"]' \ + // 'const REQUIRED: Struct;' + //@ !has - '//*[@id="associatedconstant.REQUIRED"]' 'const REQUIRED: Struct = _' + //@ has - '//*[@id="associatedconstant.REQUIRED"]' 'const REQUIRED: Struct' + const REQUIRED: Struct; + //@ has - '//pre[@class="rust item-decl"]' 'const OPTIONAL: Struct = _;' + //@ has - '//*[@id="associatedconstant.OPTIONAL"]' 'const OPTIONAL: Struct = _' + const OPTIONAL: Struct = Struct { _private: () }; +} + +impl Trait for Struct { + //@ has assoc_consts_underscore/struct.Struct.html '//*[@id="associatedconstant.REQUIRED"]' \ + // 'const REQUIRED: Struct = _' + const REQUIRED: Struct = Struct { _private: () }; + //@ has - '//*[@id="associatedconstant.OPTIONAL"]' 'const OPTIONAL: Struct = _' + const OPTIONAL: Struct = Struct { _private: () }; +} + +impl Struct { + //@ has - '//*[@id="associatedconstant.INHERENT"]' 'const INHERENT: Struct = _' + pub const INHERENT: Struct = Struct { _private: () }; +} From 6bdfd12ee9f09c48e7ec00403d5be10d3b7b6b2c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 14 Dec 2024 14:45:30 -0800 Subject: [PATCH 11/24] Suppress `= _` on associated constants in impls --- src/librustdoc/html/render/mod.rs | 50 +++++++++++++++++++----- tests/rustdoc/assoc-consts-underscore.rs | 9 +++-- tests/rustdoc/bold-tag-101743.rs | 2 +- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 4d9faf2f5680..436b5422ba9f 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -835,12 +835,23 @@ fn assoc_href_attr(it: &clean::Item, link: AssocItemLink<'_>, cx: &Context<'_>) href.map(|href| format!(" href=\"{href}\"")).unwrap_or_default() } +#[derive(Debug)] +enum AssocConstValue<'a> { + // In trait definitions, it is relevant for the public API whether an + // associated constant comes with a default value, so even if we cannot + // render its value, the presence of a value must be shown using `= _`. + TraitDefault(&'a clean::ConstantKind), + // In impls, there is no need to show `= _`. + Impl(&'a clean::ConstantKind), + None, +} + fn assoc_const( w: &mut Buffer, it: &clean::Item, generics: &clean::Generics, ty: &clean::Type, - default: Option<&clean::ConstantKind>, + value: AssocConstValue<'_>, link: AssocItemLink<'_>, indent: usize, cx: &Context<'_>, @@ -856,15 +867,20 @@ fn assoc_const( generics = generics.print(cx), ty = ty.print(cx), ); - if let Some(default) = default { - w.write_str(" = "); - + if let AssocConstValue::TraitDefault(konst) | AssocConstValue::Impl(konst) = value { // FIXME: `.value()` uses `clean::utils::format_integer_with_underscore_sep` under the // hood which adds noisy underscores and a type suffix to number literals. // This hurts readability in this context especially when more complex expressions // are involved and it doesn't add much of value. // Find a way to print constants here without all that jazz. - write!(w, "{}", Escape(&default.value(tcx).unwrap_or_else(|| default.expr(tcx)))); + let repr = konst.value(tcx).unwrap_or_else(|| konst.expr(tcx)); + if match value { + AssocConstValue::TraitDefault(_) => true, // always show + AssocConstValue::Impl(_) => repr != "_", // show if there is a meaningful value to show + AssocConstValue::None => unreachable!(), + } { + write!(w, " = {}", Escape(&repr)); + } } write!(w, "{}", print_where_clause(generics, cx, indent, Ending::NoNewline)); } @@ -1086,17 +1102,27 @@ fn render_assoc_item( item, generics, ty, - None, + AssocConstValue::None, link, if parent == ItemType::Trait { 4 } else { 0 }, cx, ), - clean::ProvidedAssocConstItem(ci) | clean::ImplAssocConstItem(ci) => assoc_const( + clean::ProvidedAssocConstItem(ci) => assoc_const( w, item, &ci.generics, &ci.type_, - Some(&ci.kind), + AssocConstValue::TraitDefault(&ci.kind), + link, + if parent == ItemType::Trait { 4 } else { 0 }, + cx, + ), + clean::ImplAssocConstItem(ci) => assoc_const( + w, + item, + &ci.generics, + &ci.type_, + AssocConstValue::Impl(&ci.kind), link, if parent == ItemType::Trait { 4 } else { 0 }, cx, @@ -1704,7 +1730,7 @@ fn render_impl( item, generics, ty, - None, + AssocConstValue::None, link.anchor(if trait_.is_some() { &source_id } else { &id }), 0, cx, @@ -1726,7 +1752,11 @@ fn render_impl( item, &ci.generics, &ci.type_, - Some(&ci.kind), + match item.kind { + clean::ProvidedAssocConstItem(_) => AssocConstValue::TraitDefault(&ci.kind), + clean::ImplAssocConstItem(_) => AssocConstValue::Impl(&ci.kind), + _ => unreachable!(), + }, link.anchor(if trait_.is_some() { &source_id } else { &id }), 0, cx, diff --git a/tests/rustdoc/assoc-consts-underscore.rs b/tests/rustdoc/assoc-consts-underscore.rs index 9bb44f0a03c7..f48098094db5 100644 --- a/tests/rustdoc/assoc-consts-underscore.rs +++ b/tests/rustdoc/assoc-consts-underscore.rs @@ -14,14 +14,17 @@ pub trait Trait { } impl Trait for Struct { - //@ has assoc_consts_underscore/struct.Struct.html '//*[@id="associatedconstant.REQUIRED"]' \ + //@ !has assoc_consts_underscore/struct.Struct.html '//*[@id="associatedconstant.REQUIRED"]' \ // 'const REQUIRED: Struct = _' + //@ has - '//*[@id="associatedconstant.REQUIRED"]' 'const REQUIRED: Struct' const REQUIRED: Struct = Struct { _private: () }; - //@ has - '//*[@id="associatedconstant.OPTIONAL"]' 'const OPTIONAL: Struct = _' + //@ !has - '//*[@id="associatedconstant.OPTIONAL"]' 'const OPTIONAL: Struct = _' + //@ has - '//*[@id="associatedconstant.OPTIONAL"]' 'const OPTIONAL: Struct' const OPTIONAL: Struct = Struct { _private: () }; } impl Struct { - //@ has - '//*[@id="associatedconstant.INHERENT"]' 'const INHERENT: Struct = _' + //@ !has - '//*[@id="associatedconstant.INHERENT"]' 'const INHERENT: Struct = _' + //@ has - '//*[@id="associatedconstant.INHERENT"]' 'const INHERENT: Struct' pub const INHERENT: Struct = Struct { _private: () }; } diff --git a/tests/rustdoc/bold-tag-101743.rs b/tests/rustdoc/bold-tag-101743.rs index a81767eeeeb6..3cd4005a4fad 100644 --- a/tests/rustdoc/bold-tag-101743.rs +++ b/tests/rustdoc/bold-tag-101743.rs @@ -14,6 +14,6 @@ impl Repr { // If we change back to rendering the value of consts, check this doesn't add // a tag, but escapes correctly - //@ has foo/struct.Repr.html '//section[@id="associatedconstant.BASE"]/h4' '= _' + //@ !has foo/struct.Repr.html '//section[@id="associatedconstant.BASE"]/h4' '=' pub const BASE: IBig = base_as_ibig::(); } From ff65d62922631bd00af13b905fd3abd9c971ae27 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 14 Dec 2024 17:02:09 -0800 Subject: [PATCH 12/24] Rename TyAssocTypeItem -> RequiredAssocTypeItem --- src/librustdoc/clean/mod.rs | 4 ++-- src/librustdoc/clean/types.rs | 10 +++++----- src/librustdoc/fold.rs | 2 +- src/librustdoc/formats/cache.rs | 4 ++-- src/librustdoc/formats/item_type.rs | 2 +- src/librustdoc/html/render/mod.rs | 6 +++--- src/librustdoc/html/render/print_item.rs | 3 ++- src/librustdoc/html/render/search_index.rs | 5 +++-- src/librustdoc/html/render/sidebar.rs | 2 +- src/librustdoc/json/conversions.rs | 2 +- src/librustdoc/passes/check_doc_test_visibility.rs | 2 +- src/librustdoc/passes/propagate_stability.rs | 2 +- src/librustdoc/passes/stripper.rs | 2 +- src/librustdoc/visit.rs | 2 +- 14 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 51ff70a69fe6..6dd6b139b1a1 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1259,7 +1259,7 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext hir::TraitItemKind::Type(bounds, None) => { let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); let bounds = bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(); - TyAssocTypeItem(generics, bounds) + RequiredAssocTypeItem(generics, bounds) } }; Item::from_def_id_and_parts(local_did, Some(trait_item.ident.name), inner, cx) @@ -1493,7 +1493,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo bounds, ) } else { - TyAssocTypeItem(generics, bounds) + RequiredAssocTypeItem(generics, bounds) } } else { AssocTypeItem( diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index feec8ac5b22c..d48897799f9b 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -547,8 +547,8 @@ impl Item { pub(crate) fn is_associated_type(&self) -> bool { matches!(self.kind, AssocTypeItem(..) | StrippedItem(box AssocTypeItem(..))) } - pub(crate) fn is_ty_associated_type(&self) -> bool { - matches!(self.kind, TyAssocTypeItem(..) | StrippedItem(box TyAssocTypeItem(..))) + pub(crate) fn is_required_associated_type(&self) -> bool { + matches!(self.kind, RequiredAssocTypeItem(..) | StrippedItem(box RequiredAssocTypeItem(..))) } pub(crate) fn is_associated_const(&self) -> bool { matches!(self.kind, ProvidedAssocConstItem(..) | ImplAssocConstItem(..) | StrippedItem(box (ProvidedAssocConstItem(..) | ImplAssocConstItem(..)))) @@ -705,7 +705,7 @@ impl Item { | ProvidedAssocConstItem(..) | ImplAssocConstItem(..) | AssocTypeItem(..) - | TyAssocTypeItem(..) + | RequiredAssocTypeItem(..) | TyMethodItem(..) | MethodItem(..) => { let assoc_item = tcx.associated_item(def_id); @@ -878,7 +878,7 @@ pub(crate) enum ItemKind { /// A required associated type in a trait declaration. /// /// The bounds may be non-empty if there is a `where` clause. - TyAssocTypeItem(Generics, Vec), + RequiredAssocTypeItem(Generics, Vec), /// An associated type in a trait impl or a provided one in a trait declaration. AssocTypeItem(Box, Vec), /// An item that has been stripped by a rustdoc pass @@ -921,7 +921,7 @@ impl ItemKind { | RequiredAssocConstItem(..) | ProvidedAssocConstItem(..) | ImplAssocConstItem(..) - | TyAssocTypeItem(..) + | RequiredAssocTypeItem(..) | AssocTypeItem(..) | StrippedItem(_) | KeywordItem => [].iter(), diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index d2e3b9ce2e4e..a42c8c94fde9 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -94,7 +94,7 @@ pub(crate) trait DocFolder: Sized { | RequiredAssocConstItem(..) | ProvidedAssocConstItem(..) | ImplAssocConstItem(..) - | TyAssocTypeItem(..) + | RequiredAssocTypeItem(..) | AssocTypeItem(..) | KeywordItem => kind, } diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index a87979ab186e..2ad8c832daf0 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -340,7 +340,7 @@ impl DocFolder for CacheBuilder<'_, '_> { | clean::RequiredAssocConstItem(..) | clean::ProvidedAssocConstItem(..) | clean::ImplAssocConstItem(..) - | clean::TyAssocTypeItem(..) + | clean::RequiredAssocTypeItem(..) | clean::AssocTypeItem(..) | clean::StrippedItem(..) | clean::KeywordItem => { @@ -454,7 +454,7 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It } clean::TyMethodItem(..) | clean::RequiredAssocConstItem(..) - | clean::TyAssocTypeItem(..) + | clean::RequiredAssocTypeItem(..) | clean::StructFieldItem(..) | clean::VariantItem(..) => { // Don't index if containing module is stripped (i.e., private), diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs index 8f5e26d0104b..f51292a5d5d4 100644 --- a/src/librustdoc/formats/item_type.rs +++ b/src/librustdoc/formats/item_type.rs @@ -99,7 +99,7 @@ impl<'a> From<&'a clean::Item> for ItemType { clean::RequiredAssocConstItem(..) | clean::ProvidedAssocConstItem(..) | clean::ImplAssocConstItem(..) => ItemType::AssocConst, - clean::TyAssocTypeItem(..) | clean::AssocTypeItem(..) => ItemType::AssocType, + clean::RequiredAssocTypeItem(..) | clean::AssocTypeItem(..) => ItemType::AssocType, clean::ForeignTypeItem => ItemType::ForeignType, clean::KeywordItem => ItemType::Keyword, clean::TraitAliasItem(..) => ItemType::TraitAlias, diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 436b5422ba9f..2d75d1a4c0e9 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1127,7 +1127,7 @@ fn render_assoc_item( if parent == ItemType::Trait { 4 } else { 0 }, cx, ), - clean::TyAssocTypeItem(ref generics, ref bounds) => assoc_type( + clean::RequiredAssocTypeItem(ref generics, ref bounds) => assoc_type( w, item, generics, @@ -1763,7 +1763,7 @@ fn render_impl( ); w.write_str("
"); } - clean::TyAssocTypeItem(ref generics, ref bounds) => { + clean::RequiredAssocTypeItem(ref generics, ref bounds) => { let source_id = format!("{item_type}.{name}"); let id = cx.derive_id(&source_id); write!(w, "
"); @@ -1839,7 +1839,7 @@ fn render_impl( for trait_item in &impl_.items { match trait_item.kind { clean::MethodItem(..) | clean::TyMethodItem(_) => methods.push(trait_item), - clean::TyAssocTypeItem(..) | clean::AssocTypeItem(..) => { + clean::RequiredAssocTypeItem(..) | clean::AssocTypeItem(..) => { assoc_types.push(trait_item) } clean::RequiredAssocConstItem(..) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index c2ffd8e764f2..76040bb2daba 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -651,7 +651,8 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean:: fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) { let tcx = cx.tcx(); let bounds = bounds(&t.bounds, false, cx); - let required_types = t.items.iter().filter(|m| m.is_ty_associated_type()).collect::>(); + let required_types = + t.items.iter().filter(|m| m.is_required_associated_type()).collect::>(); let provided_types = t.items.iter().filter(|m| m.is_associated_type()).collect::>(); let required_consts = t.items.iter().filter(|m| m.is_required_associated_const()).collect::>(); diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 2c26ffa76f6a..84bb8056e254 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -1207,10 +1207,11 @@ fn simplify_fn_type<'a, 'tcx>( && let Type::Path { path } = arg && let def_id = path.def_id() && let Some(trait_) = cache.traits.get(&def_id) - && trait_.items.iter().any(|at| at.is_ty_associated_type()) + && trait_.items.iter().any(|at| at.is_required_associated_type()) { for assoc_ty in &trait_.items { - if let clean::ItemKind::TyAssocTypeItem(_generics, bounds) = &assoc_ty.kind + if let clean::ItemKind::RequiredAssocTypeItem(_generics, bounds) = + &assoc_ty.kind && let Some(name) = assoc_ty.name { let idx = -isize::try_from(rgen.len() + 1).unwrap(); diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index 031510c006ec..af39d15f6717 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -282,7 +282,7 @@ fn sidebar_trait<'a>( res } - let req_assoc = filter_items(&t.items, |m| m.is_ty_associated_type(), "associatedtype"); + let req_assoc = filter_items(&t.items, |m| m.is_required_associated_type(), "associatedtype"); let prov_assoc = filter_items(&t.items, |m| m.is_associated_type(), "associatedtype"); let req_assoc_const = filter_items(&t.items, |m| m.is_required_associated_const(), "associatedconstant"); diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 36a0aa0fdfac..a6da40d4329e 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -347,7 +347,7 @@ fn from_clean_item(item: clean::Item, renderer: &JsonRenderer<'_>) -> ItemEnum { type_: ci.type_.into_json(renderer), value: Some(ci.kind.expr(renderer.tcx)), }, - TyAssocTypeItem(g, b) => ItemEnum::AssocType { + RequiredAssocTypeItem(g, b) => ItemEnum::AssocType { generics: g.into_json(renderer), bounds: b.into_json(renderer), type_: None, diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index 2b0af187b2da..0fefd13f7633 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -76,7 +76,7 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) - | clean::RequiredAssocConstItem(..) | clean::ProvidedAssocConstItem(..) | clean::ImplAssocConstItem(..) - | clean::TyAssocTypeItem(..) + | clean::RequiredAssocTypeItem(..) // check for trait impl | clean::ImplItem(box clean::Impl { trait_: Some(_), .. }) ) diff --git a/src/librustdoc/passes/propagate_stability.rs b/src/librustdoc/passes/propagate_stability.rs index 1f9dc7536606..564d196dd019 100644 --- a/src/librustdoc/passes/propagate_stability.rs +++ b/src/librustdoc/passes/propagate_stability.rs @@ -72,7 +72,7 @@ impl DocFolder for StabilityPropagator<'_, '_> { | ItemKind::RequiredAssocConstItem(..) | ItemKind::ProvidedAssocConstItem(..) | ItemKind::ImplAssocConstItem(..) - | ItemKind::TyAssocTypeItem(..) + | ItemKind::RequiredAssocTypeItem(..) | ItemKind::AssocTypeItem(..) | ItemKind::PrimitiveItem(..) | ItemKind::KeywordItem => own_stability, diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index 7dc7856405ee..c992d8d94775 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -123,7 +123,7 @@ impl DocFolder for Stripper<'_, '_> { // tymethods etc. have no control over privacy clean::TyMethodItem(..) | clean::RequiredAssocConstItem(..) - | clean::TyAssocTypeItem(..) => {} + | clean::RequiredAssocTypeItem(..) => {} // Proc-macros are always public clean::ProcMacroItem(..) => {} diff --git a/src/librustdoc/visit.rs b/src/librustdoc/visit.rs index 397ff8873a34..293e1f3af4e1 100644 --- a/src/librustdoc/visit.rs +++ b/src/librustdoc/visit.rs @@ -47,7 +47,7 @@ pub(crate) trait DocVisitor<'a>: Sized { | RequiredAssocConstItem(..) | ProvidedAssocConstItem(..) | ImplAssocConstItem(..) - | TyAssocTypeItem(..) + | RequiredAssocTypeItem(..) | AssocTypeItem(..) | KeywordItem => {} } From 7ee31ebd55f536a5fad9f31784cc85a6ec48ae74 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 14 Dec 2024 17:08:02 -0800 Subject: [PATCH 13/24] Rename TyMethodItem -> RequiredMethodItem --- src/librustdoc/clean/mod.rs | 4 ++-- src/librustdoc/clean/types.rs | 12 +++++++----- src/librustdoc/fold.rs | 2 +- src/librustdoc/formats/cache.rs | 4 ++-- src/librustdoc/formats/item_type.rs | 2 +- src/librustdoc/html/render/mod.rs | 8 ++++---- src/librustdoc/html/render/search_index.rs | 2 +- src/librustdoc/json/conversions.rs | 4 +++- src/librustdoc/passes/propagate_stability.rs | 2 +- src/librustdoc/passes/stripper.rs | 2 +- src/librustdoc/visit.rs | 2 +- 11 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6dd6b139b1a1..6b32d1896ea9 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1239,7 +1239,7 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext } hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(names)) => { let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Names(names)); - TyMethodItem(m) + RequiredMethodItem(m) } hir::TraitItemKind::Type(bounds, Some(default)) => { let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); @@ -1376,7 +1376,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo }; MethodItem(item, defaultness) } else { - TyMethodItem(item) + RequiredMethodItem(item) } } ty::AssocKind::Type => { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index d48897799f9b..ffd9caa0bcad 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -671,7 +671,9 @@ impl Item { asyncness: hir::IsAsync::NotAsync, } } - ItemKind::FunctionItem(_) | ItemKind::MethodItem(_, _) | ItemKind::TyMethodItem(_) => { + ItemKind::FunctionItem(_) + | ItemKind::MethodItem(_, _) + | ItemKind::RequiredMethodItem(_) => { let def_id = self.def_id().unwrap(); build_fn_header(def_id, tcx, tcx.asyncness(def_id)) } @@ -706,7 +708,7 @@ impl Item { | ImplAssocConstItem(..) | AssocTypeItem(..) | RequiredAssocTypeItem(..) - | TyMethodItem(..) + | RequiredMethodItem(..) | MethodItem(..) => { let assoc_item = tcx.associated_item(def_id); let is_trait_item = match assoc_item.container { @@ -852,10 +854,10 @@ pub(crate) enum ItemKind { TraitAliasItem(TraitAlias), ImplItem(Box), /// A required method in a trait declaration meaning it's only a function signature. - TyMethodItem(Box), + RequiredMethodItem(Box), /// A method in a trait impl or a provided method in a trait declaration. /// - /// Compared to [TyMethodItem], it also contains a method body. + /// Compared to [RequiredMethodItem], it also contains a method body. MethodItem(Box, Option), StructFieldItem(Type), VariantItem(Variant), @@ -909,7 +911,7 @@ impl ItemKind { | StaticItem(_) | ConstantItem(_) | TraitAliasItem(_) - | TyMethodItem(_) + | RequiredMethodItem(_) | MethodItem(_, _) | StructFieldItem(_) | ForeignFunctionItem(_, _) diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index a42c8c94fde9..c03d16ad081b 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -82,7 +82,7 @@ pub(crate) trait DocFolder: Sized { | StaticItem(_) | ConstantItem(..) | TraitAliasItem(_) - | TyMethodItem(_) + | RequiredMethodItem(_) | MethodItem(_, _) | StructFieldItem(_) | ForeignFunctionItem(..) diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 2ad8c832daf0..b63122565c42 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -334,7 +334,7 @@ impl DocFolder for CacheBuilder<'_, '_> { clean::ExternCrateItem { .. } | clean::ImportItem(..) | clean::ImplItem(..) - | clean::TyMethodItem(..) + | clean::RequiredMethodItem(..) | clean::MethodItem(..) | clean::StructFieldItem(..) | clean::RequiredAssocConstItem(..) @@ -452,7 +452,7 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It // skip associated items in trait impls return; } - clean::TyMethodItem(..) + clean::RequiredMethodItem(..) | clean::RequiredAssocConstItem(..) | clean::RequiredAssocTypeItem(..) | clean::StructFieldItem(..) diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs index f51292a5d5d4..de6537e992f1 100644 --- a/src/librustdoc/formats/item_type.rs +++ b/src/librustdoc/formats/item_type.rs @@ -88,7 +88,7 @@ impl<'a> From<&'a clean::Item> for ItemType { clean::ConstantItem(..) => ItemType::Constant, clean::TraitItem(..) => ItemType::Trait, clean::ImplItem(..) => ItemType::Impl, - clean::TyMethodItem(..) => ItemType::TyMethod, + clean::RequiredMethodItem(..) => ItemType::TyMethod, clean::MethodItem(..) => ItemType::Method, clean::StructFieldItem(..) => ItemType::StructField, clean::VariantItem(..) => ItemType::Variant, diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 2d75d1a4c0e9..0628e074fbd5 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1091,7 +1091,7 @@ fn render_assoc_item( ) { match &item.kind { clean::StrippedItem(..) => {} - clean::TyMethodItem(m) => { + clean::RequiredMethodItem(m) => { assoc_method(w, item, &m.generics, &m.decl, link, parent, cx, render_mode) } clean::MethodItem(m, _) => { @@ -1409,7 +1409,7 @@ fn render_deref_methods( fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) -> bool { let self_type_opt = match item.kind { clean::MethodItem(ref method, _) => method.decl.receiver_type(), - clean::TyMethodItem(ref method) => method.decl.receiver_type(), + clean::RequiredMethodItem(ref method) => method.decl.receiver_type(), _ => None, }; @@ -1685,7 +1685,7 @@ fn render_impl( write!(w, "
"); } match &item.kind { - clean::MethodItem(..) | clean::TyMethodItem(_) => { + clean::MethodItem(..) | clean::RequiredMethodItem(_) => { // Only render when the method is not static or we allow static methods if render_method_item { let id = cx.derive_id(format!("{item_type}.{name}")); @@ -1838,7 +1838,7 @@ fn render_impl( if !impl_.is_negative_trait_impl() { for trait_item in &impl_.items { match trait_item.kind { - clean::MethodItem(..) | clean::TyMethodItem(_) => methods.push(trait_item), + clean::MethodItem(..) | clean::RequiredMethodItem(_) => methods.push(trait_item), clean::RequiredAssocTypeItem(..) | clean::AssocTypeItem(..) => { assoc_types.push(trait_item) } diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 84bb8056e254..fe2e155c9ba7 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -837,7 +837,7 @@ pub(crate) fn get_function_type_for_search( clean::ForeignFunctionItem(ref f, _) | clean::FunctionItem(ref f) | clean::MethodItem(ref f, _) - | clean::TyMethodItem(ref f) => { + | clean::RequiredMethodItem(ref f) => { get_fn_inputs_and_outputs(f, tcx, impl_or_trait_generics, cache) } _ => return None, diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index a6da40d4329e..7c1d59390f90 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -319,7 +319,9 @@ fn from_clean_item(item: clean::Item, renderer: &JsonRenderer<'_>) -> ItemEnum { TraitItem(t) => ItemEnum::Trait((*t).into_json(renderer)), TraitAliasItem(t) => ItemEnum::TraitAlias(t.into_json(renderer)), MethodItem(m, _) => ItemEnum::Function(from_function(m, true, header.unwrap(), renderer)), - TyMethodItem(m) => ItemEnum::Function(from_function(m, false, header.unwrap(), renderer)), + RequiredMethodItem(m) => { + ItemEnum::Function(from_function(m, false, header.unwrap(), renderer)) + } ImplItem(i) => ItemEnum::Impl((*i).into_json(renderer)), StaticItem(s) => ItemEnum::Static(convert_static(s, rustc_hir::Safety::Safe, renderer)), ForeignStaticItem(s, safety) => ItemEnum::Static(convert_static(s, safety, renderer)), diff --git a/src/librustdoc/passes/propagate_stability.rs b/src/librustdoc/passes/propagate_stability.rs index 564d196dd019..c88f48c1ff18 100644 --- a/src/librustdoc/passes/propagate_stability.rs +++ b/src/librustdoc/passes/propagate_stability.rs @@ -67,7 +67,7 @@ impl DocFolder for StabilityPropagator<'_, '_> { // Don't inherit the parent's stability for these items, because they // are potentially accessible even if the parent is more unstable. ItemKind::ImplItem(..) - | ItemKind::TyMethodItem(..) + | ItemKind::RequiredMethodItem(..) | ItemKind::MethodItem(..) | ItemKind::RequiredAssocConstItem(..) | ItemKind::ProvidedAssocConstItem(..) diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index c992d8d94775..eedbbca0f8df 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -121,7 +121,7 @@ impl DocFolder for Stripper<'_, '_> { clean::ImplItem(..) => {} // tymethods etc. have no control over privacy - clean::TyMethodItem(..) + clean::RequiredMethodItem(..) | clean::RequiredAssocConstItem(..) | clean::RequiredAssocTypeItem(..) => {} diff --git a/src/librustdoc/visit.rs b/src/librustdoc/visit.rs index 293e1f3af4e1..b8b619514aad 100644 --- a/src/librustdoc/visit.rs +++ b/src/librustdoc/visit.rs @@ -35,7 +35,7 @@ pub(crate) trait DocVisitor<'a>: Sized { | StaticItem(_) | ConstantItem(..) | TraitAliasItem(_) - | TyMethodItem(_) + | RequiredMethodItem(_) | MethodItem(_, _) | StructFieldItem(_) | ForeignFunctionItem(..) From eef749819b2492f470ddcf075b372e9b13ecb7d1 Mon Sep 17 00:00:00 2001 From: hltj Date: Fri, 20 Dec 2024 11:47:02 +0800 Subject: [PATCH 14/24] fix typos in the example code in the doc comments of `Ipv4Addr::from_bits()`, `Ipv6Addr::from_bits()` & `Ipv6Addr::to_bits()` --- library/core/src/net/ip_addr.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs index 82f11f0eaac3..7dd5c2140126 100644 --- a/library/core/src/net/ip_addr.rs +++ b/library/core/src/net/ip_addr.rs @@ -527,7 +527,7 @@ impl Ipv4Addr { /// ``` /// use std::net::Ipv4Addr; /// - /// let addr = Ipv4Addr::from(0x12345678); + /// let addr = Ipv4Addr::from_bits(0x12345678); /// assert_eq!(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78), addr); /// ``` #[rustc_const_stable(feature = "ip_bits", since = "1.80.0")] @@ -1294,7 +1294,7 @@ impl Ipv6Addr { /// 0x1020, 0x3040, 0x5060, 0x7080, /// 0x90A0, 0xB0C0, 0xD0E0, 0xF00D, /// ); - /// assert_eq!(0x102030405060708090A0B0C0D0E0F00D_u128, u128::from(addr)); + /// assert_eq!(0x102030405060708090A0B0C0D0E0F00D_u128, addr.to_bits()); /// ``` /// /// ``` @@ -1330,7 +1330,7 @@ impl Ipv6Addr { /// ``` /// use std::net::Ipv6Addr; /// - /// let addr = Ipv6Addr::from(0x102030405060708090A0B0C0D0E0F00D_u128); + /// let addr = Ipv6Addr::from_bits(0x102030405060708090A0B0C0D0E0F00D_u128); /// assert_eq!( /// Ipv6Addr::new( /// 0x1020, 0x3040, 0x5060, 0x7080, From fafe0ce4ab76b6fa6688f0827649024933b32417 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 20 Dec 2024 11:28:19 +0100 Subject: [PATCH 15/24] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 10108a6fbca0..64ce88623963 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -214587c89d527dd0ccbe1f2150c737d3bdee67b0 +8a1f8039a7ded79d3d4fe97b110016d89f2b11e2 From 05731afff2e7fb21eab3bc3c0c62c3d61a6d1d0a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 7 Aug 2024 14:44:21 +0200 Subject: [PATCH 16/24] Add `--doctest-compilation-args` option to allow passing arguments to doctest compilation --- src/librustdoc/config.rs | 5 +++++ src/librustdoc/doctest.rs | 11 +++++++++++ src/librustdoc/lib.rs | 10 +++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 34c91e33db70..af3c7cc7be34 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -172,6 +172,9 @@ pub(crate) struct Options { /// This is mainly useful for other tools that reads that debuginfo to figure out /// how to call the compiler with the same arguments. pub(crate) expanded_args: Vec, + + /// Arguments to be used when compiling doctests. + pub(crate) doctest_compilation_args: Vec, } impl fmt::Debug for Options { @@ -774,6 +777,7 @@ impl Options { let scrape_examples_options = ScrapeExamplesOptions::new(matches, dcx); let with_examples = matches.opt_strs("with-examples"); let call_locations = crate::scrape_examples::load_call_locations(with_examples, dcx); + let doctest_compilation_args = matches.opt_strs("doctest-compilation-args"); let unstable_features = rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref()); @@ -819,6 +823,7 @@ impl Options { scrape_examples_options, unstable_features, expanded_args: args, + doctest_compilation_args, }; let render_options = RenderOptions { output, diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index ce44cb1c319a..a53316dc6c15 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -78,6 +78,17 @@ pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) -> content.push(format!("-Z{unstable_option_str}")); } + for compilation_args in &options.doctest_compilation_args { + for flag in compilation_args + .split_whitespace() + .map(|flag| flag.trim()) + .filter(|flag| !flag.is_empty()) + { + // Very simple parsing implementation. Might be a good idea to correctly handle strings. + content.push(flag.to_string()); + } + } + let content = content.join("\n"); file.write_all(content.as_bytes()) diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 7655c2e0e15e..ff1c9c61720f 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -642,6 +642,15 @@ fn opts() -> Vec { "Includes trait implementations and other crate info from provided path. Only use with --merge=finalize", "path/to/doc.parts/", ), + opt(Unstable, Flag, "", "html-no-source", "Disable HTML source code pages generation", ""), + opt( + Unstable, + Multi, + "", + "doctest-compilation-args", + "", + "add arguments to be used when compiling doctests", + ), // deprecated / removed options opt(Unstable, FlagMulti, "", "disable-minification", "removed", ""), opt( @@ -684,7 +693,6 @@ fn opts() -> Vec { "removed, see issue #44136 for more information", "[rust]", ), - opt(Unstable, Flag, "", "html-no-source", "Disable HTML source code pages generation", ""), ] } From 2bd869082bdf4fb950febbf5a6f7b64a81dfe2d1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 7 Aug 2024 14:50:50 +0200 Subject: [PATCH 17/24] Add regression test for `--doctest-compilation-args` --- tests/rustdoc-ui/doctest/rustflags.rs | 12 ++++++++++++ tests/rustdoc-ui/doctest/rustflags.stdout | 6 ++++++ 2 files changed, 18 insertions(+) create mode 100644 tests/rustdoc-ui/doctest/rustflags.rs create mode 100644 tests/rustdoc-ui/doctest/rustflags.stdout diff --git a/tests/rustdoc-ui/doctest/rustflags.rs b/tests/rustdoc-ui/doctest/rustflags.rs new file mode 100644 index 000000000000..fa460e355472 --- /dev/null +++ b/tests/rustdoc-ui/doctest/rustflags.rs @@ -0,0 +1,12 @@ +//@ check-pass +//@ compile-flags: --test -Zunstable-options --doctest-compilation-args=--cfg=testcase_must_be_present +//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// ``` +/// #[cfg(testcase_must_be_present)] +/// fn must_be_present() {} +/// +/// fn main() { must_be_present() } +/// ``` +pub struct Bar; diff --git a/tests/rustdoc-ui/doctest/rustflags.stdout b/tests/rustdoc-ui/doctest/rustflags.stdout new file mode 100644 index 000000000000..b9da6637745b --- /dev/null +++ b/tests/rustdoc-ui/doctest/rustflags.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/rustflags.rs - Bar (line 6) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + From d3c970a1986d960ee92d3a12ded89b3a8293d82f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 7 Aug 2024 14:55:47 +0200 Subject: [PATCH 18/24] Add explanations about `--doctest-compilation-args` in rustdoc book --- src/doc/rustdoc/src/unstable-features.md | 94 +++++++++++++++++++----- 1 file changed, 76 insertions(+), 18 deletions(-) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index f19c3a51f619..f1aa8a53422d 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -315,7 +315,7 @@ Markdown file, the URL given to `--markdown-playground-url` will take precedence `--playground-url` and `#![doc(html_playground_url = "url")]` are present when rendering crate docs, the attribute will take precedence. -### `--sort-modules-by-appearance`: control how items on module pages are sorted +## `--sort-modules-by-appearance`: control how items on module pages are sorted Using this flag looks like this: @@ -328,7 +328,7 @@ some consideration for their stability, and names that end in a number). Giving `rustdoc` will disable this sorting and instead make it print the items in the order they appear in the source. -### `--show-type-layout`: add a section to each type's docs describing its memory layout +## `--show-type-layout`: add a section to each type's docs describing its memory layout * Tracking issue: [#113248](https://github.com/rust-lang/rust/issues/113248) @@ -346,7 +346,7 @@ of that type will take in memory. Note that most layout information is **completely unstable** and may even differ between compilations. -### `--resource-suffix`: modifying the name of CSS/JavaScript in crate docs +## `--resource-suffix`: modifying the name of CSS/JavaScript in crate docs * Tracking issue: [#54765](https://github.com/rust-lang/rust/issues/54765) @@ -361,7 +361,7 @@ all these files are linked from every page, changing where they are can be cumbe specially cache them. This flag will rename all these files in the output to include the suffix in the filename. For example, `light.css` would become `light-suf.css` with the above command. -### `--extern-html-root-url`: control how rustdoc links to non-local crates +## `--extern-html-root-url`: control how rustdoc links to non-local crates Using this flag looks like this: @@ -376,7 +376,7 @@ flags to control that behavior. When the `--extern-html-root-url` flag is given one of your dependencies, rustdoc use that URL for those docs. Keep in mind that if those docs exist in the output directory, those local docs will still override this flag. -### `-Z force-unstable-if-unmarked` +## `-Z force-unstable-if-unmarked` Using this flag looks like this: @@ -389,7 +389,7 @@ This is an internal flag intended for the standard library and compiler that app allows `rustdoc` to be able to generate documentation for the compiler crates and the standard library, as an equivalent command-line argument is provided to `rustc` when building those crates. -### `--index-page`: provide a top-level landing page for docs +## `--index-page`: provide a top-level landing page for docs This feature allows you to generate an index-page with a given markdown file. A good example of it is the [rust documentation index](https://doc.rust-lang.org/nightly/index.html). @@ -398,18 +398,18 @@ With this, you'll have a page which you can customize as much as you want at the Using `index-page` option enables `enable-index-page` option as well. -### `--enable-index-page`: generate a default index page for docs +## `--enable-index-page`: generate a default index page for docs This feature allows the generation of a default index-page which lists the generated crates. -### `--nocapture`: disable output capture for test +## `--nocapture`: disable output capture for test When this flag is used with `--test`, the output (stdout and stderr) of your tests won't be captured by rustdoc. Instead, the output will be directed to your terminal, as if you had run the test executable manually. This is especially useful for debugging your tests! -### `--check`: only checks the documentation +## `--check`: only checks the documentation When this flag is supplied, rustdoc will type check and lint your code, but will not generate any documentation or run your doctests. @@ -420,7 +420,7 @@ Using this flag looks like: rustdoc -Z unstable-options --check src/lib.rs ``` -### `--static-root-path`: control how static files are loaded in HTML output +## `--static-root-path`: control how static files are loaded in HTML output Using this flag looks like this: @@ -435,7 +435,7 @@ JavaScript, and font files in a single location, rather than duplicating it once files like the search index will still load from the documentation root, but anything that gets renamed with `--resource-suffix` will load from the given path. -### `--persist-doctests`: persist doctest executables after running +## `--persist-doctests`: persist doctest executables after running * Tracking issue: [#56925](https://github.com/rust-lang/rust/issues/56925) @@ -449,7 +449,7 @@ This flag allows you to keep doctest executables around after they're compiled o Usually, rustdoc will immediately discard a compiled doctest after it's been tested, but with this option, you can keep those binaries around for farther testing. -### `--show-coverage`: calculate the percentage of items with documentation +## `--show-coverage`: calculate the percentage of items with documentation * Tracking issue: [#58154](https://github.com/rust-lang/rust/issues/58154) @@ -500,7 +500,7 @@ Calculating code examples follows these rules: * typedef 2. If one of the previously listed items has a code example, then it'll be counted. -#### JSON output +### JSON output When using `--output-format json` with this option, it will display the coverage information in JSON format. For example, here is the JSON for a file with one documented item and one @@ -522,7 +522,7 @@ Note that the third item is the crate root, which in this case is undocumented. If you want the JSON output to be displayed on `stdout` instead of having a file generated, you can use `-o -`. -### `-w`/`--output-format`: output format +## `-w`/`--output-format`: output format `--output-format json` emits documentation in the experimental [JSON format](https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc_json_types/). `--output-format html` has no effect, @@ -542,7 +542,7 @@ It can also be used with `--show-coverage`. Take a look at its [documentation](#--show-coverage-calculate-the-percentage-of-items-with-documentation) for more information. -### `--enable-per-target-ignores`: allow `ignore-foo` style filters for doctests +## `--enable-per-target-ignores`: allow `ignore-foo` style filters for doctests * Tracking issue: [#64245](https://github.com/rust-lang/rust/issues/64245) @@ -577,7 +577,7 @@ struct Foo; In older versions, this will be ignored on all targets, but on newer versions `ignore-gnu` will override `ignore`. -### `--runtool`, `--runtool-arg`: program to run tests with; args to pass to it +## `--runtool`, `--runtool-arg`: program to run tests with; args to pass to it * Tracking issue: [#64245](https://github.com/rust-lang/rust/issues/64245) @@ -596,7 +596,7 @@ $ rustdoc src/lib.rs -Z unstable-options --runtool valgrind Another use case would be to run a test inside an emulator, or through a Virtual Machine. -### `--with-examples`: include examples of uses of items as documentation +## `--with-examples`: include examples of uses of items as documentation * Tracking issue: [#88791](https://github.com/rust-lang/rust/issues/88791) @@ -625,7 +625,7 @@ crate being documented (`foobar`) and a path to output the calls To scrape examples from test code, e.g. functions marked `#[test]`, then add the `--scrape-tests` flag. -### `--generate-link-to-definition`: Generate links on types in source code +## `--generate-link-to-definition`: Generate links on types in source code * Tracking issue: [#89095](https://github.com/rust-lang/rust/issues/89095) @@ -664,3 +664,61 @@ Similar to cargo `build.rustc-wrapper` option, this flag takes a `rustc` wrapper The first argument to the program will be the test builder program. This flag can be passed multiple times to nest wrappers. + +## Passing arguments to rustc when compiling doctests + +You can use the `--doctest-compilation-args` option if you want to add options when compiling the +doctest. For example if you have: + +```rust,no_run +/// ``` +/// #![deny(warnings)] +/// #![feature(async_await)] +/// +/// let x = 12; +/// ``` +pub struct Bar; +``` + +And you run `rustdoc --test` on it, you will get: + +```console +running 1 test +test foo.rs - Bar (line 1) ... FAILED + +failures: + +---- foo.rs - Bar (line 1) stdout ---- +error: the feature `async_await` has been stable since 1.39.0 and no longer requires an attribute to enable + --> foo.rs:2:12 + | +3 | #![feature(async_await)] + | ^^^^^^^^^^^ + | +note: the lint level is defined here + --> foo.rs:1:9 + | +2 | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(stable_features)]` implied by `#[deny(warnings)]` + +error: aborting due to 1 previous error + +Couldn't compile the test. + +failures: + foo.rs - Bar (line 1) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s +``` + +But if you can limit the lint level to warning by using `--doctest_compilation_args=--cap-lints=warn`: + +```console +$ rustdoc --test --doctest_compilation_args=--cap-lints=warn file.rs + +running 1 test +test tests/rustdoc-ui/doctest/rustflags.rs - Bar (line 5) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s +``` From 24fafe7d14303643de24cc31bb6d1acc0568bcb5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 19 Aug 2024 17:52:21 +0200 Subject: [PATCH 19/24] Update `run-make/rustdoc-default-output` test --- tests/run-make/rustdoc-default-output/output-default.stdout | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/run-make/rustdoc-default-output/output-default.stdout b/tests/run-make/rustdoc-default-output/output-default.stdout index 125443ce6196..c2d9309ba2e6 100644 --- a/tests/run-make/rustdoc-default-output/output-default.stdout +++ b/tests/run-make/rustdoc-default-output/output-default.stdout @@ -189,6 +189,10 @@ Options: --include-parts-dir path/to/doc.parts/ Includes trait implementations and other crate info from provided path. Only use with --merge=finalize + --html-no-source + Disable HTML source code pages generation + --doctest-compilation-args add arguments to be used when compiling doctests + --disable-minification removed --plugin-path DIR @@ -209,8 +213,6 @@ Options: removed, see issue #44136 for more information - --html-no-source - Disable HTML source code pages generation @path Read newline separated options from `path` From cbb3df41fb48d0a5ebcdd0f4b44cc3ad6a5a837a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 28 Aug 2024 16:19:52 +0200 Subject: [PATCH 20/24] Split arguments from `--doctest-compilation-args` like a shell would --- src/librustdoc/doctest.rs | 72 ++++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index a53316dc6c15..a93e2f927182 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -50,6 +50,46 @@ pub(crate) struct GlobalTestOptions { pub(crate) args_file: PathBuf, } +/// Function used to split command line arguments just like a shell would. +fn split_args(args: &str) -> Vec { + let mut out = Vec::new(); + let mut iter = args.chars(); + let mut current = String::new(); + + while let Some(c) = iter.next() { + if c == '\\' { + if let Some(c) = iter.next() { + // If it's escaped, even a quote or a whitespace will be ignored. + current.push(c); + } + } else if c == '"' || c == '\'' { + while let Some(new_c) = iter.next() { + if new_c == c { + break; + } else if new_c == '\\' { + if let Some(c) = iter.next() { + // If it's escaped, even a quote will be ignored. + current.push(c); + } + } else { + current.push(new_c); + } + } + } else if " \n\t\r".contains(c) { + if !current.is_empty() { + out.push(current.clone()); + current.clear(); + } + } else { + current.push(c); + } + } + if !current.is_empty() { + out.push(current); + } + out +} + pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) -> Result<(), String> { let mut file = File::create(file_path) .map_err(|error| format!("failed to create args file: {error:?}"))?; @@ -79,14 +119,7 @@ pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) -> } for compilation_args in &options.doctest_compilation_args { - for flag in compilation_args - .split_whitespace() - .map(|flag| flag.trim()) - .filter(|flag| !flag.is_empty()) - { - // Very simple parsing implementation. Might be a good idea to correctly handle strings. - content.push(flag.to_string()); - } + content.extend(split_args(compilation_args)); } let content = content.join("\n"); @@ -1003,6 +1036,29 @@ fn doctest_run_fn( Ok(()) } +#[cfg(test)] +#[test] +fn check_split_args() { + fn compare(input: &str, expected: &[&str]) { + let output = split_args(input); + let expected = expected.iter().map(|s| s.to_string()).collect::>(); + assert_eq!(expected, output, "test failed for {input:?}"); + } + + compare("'a' \"b\"c", &["a", "bc"]); + compare("'a' \"b \"c d", &["a", "b c", "d"]); + compare("'a' \"b\\\"c\"", &["a", "b\"c"]); + compare("'a\"'", &["a\""]); + compare("\"a'\"", &["a'"]); + compare("\\ a", &[" a"]); + compare("\\\\", &["\\"]); + compare("a'", &["a"]); + compare("a ", &["a"]); + compare("a b", &["a", "b"]); + compare("a\n\t \rb", &["a", "b"]); + compare("a\n\t1 \rb", &["a", "1", "b"]); +} + #[cfg(test)] // used in tests impl DocTestVisitor for Vec { fn visit_test(&mut self, _test: String, _config: LangString, rel_line: MdRelLine) { From 55653a5178c07a0a854066e79062de4c585561a5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 20 Dec 2024 12:35:57 +0100 Subject: [PATCH 21/24] Add explanations on how arguments are split --- src/doc/rustdoc/src/unstable-features.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index f1aa8a53422d..667f07cf9563 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -722,3 +722,22 @@ test tests/rustdoc-ui/doctest/rustflags.rs - Bar (line 5) ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s ``` + +The parsing of arguments works as follows: if it encounters a `"` or a `'`, it will continue +until it finds the character unescaped (without a prepending `\`). If not inside a string, a +whitespace character will also split arguments. Example: + +```text +"hello 'a'\" ok" how are 'you today?' +``` + +will be split as follows: + +```text +[ + "hello 'a'\" ok", + "how", + "are", + "you today?", +] +``` From bc03e40a29574c18ebfc04bd179065815ebe83f8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 20 Dec 2024 15:14:08 +0100 Subject: [PATCH 22/24] Move test into the `tests.rs` file --- src/librustdoc/doctest.rs | 23 ----------------------- src/librustdoc/doctest/tests.rs | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index a93e2f927182..e6e5123d0bba 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -1036,29 +1036,6 @@ fn doctest_run_fn( Ok(()) } -#[cfg(test)] -#[test] -fn check_split_args() { - fn compare(input: &str, expected: &[&str]) { - let output = split_args(input); - let expected = expected.iter().map(|s| s.to_string()).collect::>(); - assert_eq!(expected, output, "test failed for {input:?}"); - } - - compare("'a' \"b\"c", &["a", "bc"]); - compare("'a' \"b \"c d", &["a", "b c", "d"]); - compare("'a' \"b\\\"c\"", &["a", "b\"c"]); - compare("'a\"'", &["a\""]); - compare("\"a'\"", &["a'"]); - compare("\\ a", &[" a"]); - compare("\\\\", &["\\"]); - compare("a'", &["a"]); - compare("a ", &["a"]); - compare("a b", &["a", "b"]); - compare("a\n\t \rb", &["a", "b"]); - compare("a\n\t1 \rb", &["a", "1", "b"]); -} - #[cfg(test)] // used in tests impl DocTestVisitor for Vec { fn visit_test(&mut self, _test: String, _config: LangString, rel_line: MdRelLine) { diff --git a/src/librustdoc/doctest/tests.rs b/src/librustdoc/doctest/tests.rs index 160d0f222b4e..fa6cca3681be 100644 --- a/src/librustdoc/doctest/tests.rs +++ b/src/librustdoc/doctest/tests.rs @@ -379,3 +379,25 @@ fn main() { let (output, len) = make_test(input, None, false, &opts, None); assert_eq!((output, len), (expected, 1)); } + +#[test] +fn check_split_args() { + fn compare(input: &str, expected: &[&str]) { + let output = super::split_args(input); + let expected = expected.iter().map(|s| s.to_string()).collect::>(); + assert_eq!(expected, output, "test failed for {input:?}"); + } + + compare("'a' \"b\"c", &["a", "bc"]); + compare("'a' \"b \"c d", &["a", "b c", "d"]); + compare("'a' \"b\\\"c\"", &["a", "b\"c"]); + compare("'a\"'", &["a\""]); + compare("\"a'\"", &["a'"]); + compare("\\ a", &[" a"]); + compare("\\\\", &["\\"]); + compare("a'", &["a"]); + compare("a ", &["a"]); + compare("a b", &["a", "b"]); + compare("a\n\t \rb", &["a", "b"]); + compare("a\n\t1 \rb", &["a", "1", "b"]); +} From 2d914bed2dea1316fdbb55010f3bb2c5412942cb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 20 Dec 2024 15:39:26 +0100 Subject: [PATCH 23/24] Add test to ensure passing `--doctest_compilation_args` multiple times work --- src/doc/rustdoc/src/unstable-features.md | 2 +- .../doctest/rustflags-multiple-args.rs | 17 +++++++++++++++++ .../doctest/rustflags-multiple-args.stdout | 6 ++++++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 tests/rustdoc-ui/doctest/rustflags-multiple-args.rs create mode 100644 tests/rustdoc-ui/doctest/rustflags-multiple-args.stdout diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 667f07cf9563..d1d42e473225 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -667,7 +667,7 @@ This flag can be passed multiple times to nest wrappers. ## Passing arguments to rustc when compiling doctests -You can use the `--doctest-compilation-args` option if you want to add options when compiling the +You can use the `--doctest-compilation-args` flag if you want to add options when compiling the doctest. For example if you have: ```rust,no_run diff --git a/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs b/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs new file mode 100644 index 000000000000..8519920e53be --- /dev/null +++ b/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs @@ -0,0 +1,17 @@ +// This test checks that the test behave when `--doctest-compilation-args` is passed +// multiple times. + +//@ check-pass +//@ compile-flags: --test -Zunstable-options --doctest-compilation-args=--cfg=testcase_must_be_present +//@ compile-flags: --doctest-compilation-args=--cfg=another +//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// ``` +/// #[cfg(testcase_must_be_present)] +/// #[cfg(another)] +/// fn must_be_present() {} +/// +/// fn main() { must_be_present() } +/// ``` +pub struct Bar; diff --git a/tests/rustdoc-ui/doctest/rustflags-multiple-args.stdout b/tests/rustdoc-ui/doctest/rustflags-multiple-args.stdout new file mode 100644 index 000000000000..0e8a9e1efcf6 --- /dev/null +++ b/tests/rustdoc-ui/doctest/rustflags-multiple-args.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/rustflags-multiple-args.rs - Bar (line 10) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + From 9659fbcf704d1e78a85d7252757c9d1be84835a6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 20 Dec 2024 11:30:38 +0100 Subject: [PATCH 24/24] fmt --- src/tools/miri/src/helpers.rs | 4 +- src/tools/miri/src/machine.rs | 2 +- src/tools/miri/src/shims/foreign_items.rs | 64 +++------ .../src/shims/unix/android/foreign_items.rs | 11 +- .../miri/src/shims/unix/foreign_items.rs | 2 +- .../src/shims/unix/freebsd/foreign_items.rs | 21 +-- .../src/shims/unix/linux/foreign_items.rs | 27 ++-- .../miri/src/shims/unix/linux_like/syscall.rs | 1 - .../src/shims/unix/macos/foreign_items.rs | 60 +++----- .../src/shims/unix/solarish/foreign_items.rs | 27 ++-- .../miri/src/shims/wasi/foreign_items.rs | 6 +- .../miri/src/shims/windows/foreign_items.rs | 135 ++++++------------ src/tools/miri/src/shims/x86/aesni.rs | 12 +- src/tools/miri/src/shims/x86/avx.rs | 48 +++---- src/tools/miri/src/shims/x86/avx2.rs | 54 +++---- src/tools/miri/src/shims/x86/bmi.rs | 5 +- src/tools/miri/src/shims/x86/gfni.rs | 11 +- src/tools/miri/src/shims/x86/mod.rs | 6 +- src/tools/miri/src/shims/x86/sha.rs | 9 +- src/tools/miri/src/shims/x86/sse.rs | 18 +-- src/tools/miri/src/shims/x86/sse2.rs | 36 ++--- src/tools/miri/src/shims/x86/sse3.rs | 6 +- src/tools/miri/src/shims/x86/sse41.rs | 27 ++-- src/tools/miri/src/shims/x86/sse42.rs | 15 +- src/tools/miri/src/shims/x86/ssse3.rs | 15 +- 25 files changed, 211 insertions(+), 411 deletions(-) diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 8b9ad3c1ade8..444ff7251396 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -925,7 +925,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { if fn_abi.conv != exp_abi { throw_ub_format!( "calling a function with ABI {:?} using caller ABI {:?}", - exp_abi, fn_abi.conv); + exp_abi, + fn_abi.conv + ); } interp_ok(()) } diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 592a54ff50d2..33cefd607646 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -13,7 +13,6 @@ use rand::{Rng, SeedableRng}; use rustc_abi::{Align, ExternAbi, Size}; use rustc_attr_parsing::InlineAttr; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_target::callconv::FnAbi; #[allow(unused)] use rustc_data_structures::static_assert_size; use rustc_middle::mir; @@ -25,6 +24,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_session::config::InliningThreshold; use rustc_span::def_id::{CrateNum, DefId}; use rustc_span::{Span, SpanData, Symbol}; +use rustc_target::callconv::FnAbi; use crate::concurrency::cpu_affinity::{self, CpuAffinityMask}; use crate::concurrency::data_race::{self, NaReadType, NaWriteType}; diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 7b2a0d6f4d64..8c8850ba7e0a 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -9,12 +9,11 @@ use rustc_ast::expand::allocator::alloc_error_handler_name; use rustc_hir::def::DefKind; use rustc_hir::def_id::CrateNum; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use rustc_middle::{mir, ty}; use rustc_middle::ty::Ty; +use rustc_middle::{mir, ty}; use rustc_span::Symbol; use rustc_target::callconv::{Conv, FnAbi}; - use self::helpers::{ToHost, ToSoft}; use super::alloc::EvalContextExt as _; use super::backtrace::EvalContextExt as _; @@ -279,7 +278,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Miri-specific extern functions "miri_start_unwind" => { - let [payload] = this.check_shim(abi, Conv::Rust, link_name, args)?; + let [payload] = this.check_shim(abi, Conv::Rust, link_name, args)?; this.handle_miri_start_unwind(payload)?; return interp_ok(EmulateItemResult::NeedsUnwind); } @@ -288,7 +287,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.run_provenance_gc(); } "miri_get_alloc_id" => { - let [ptr] = this.check_shim(abi, Conv::Rust, link_name, args)?; + let [ptr] = this.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let (alloc_id, _, _) = this.ptr_get_alloc_id(ptr, 0).map_err_kind(|_e| { err_machine_stop!(TerminationInfo::Abort(format!( @@ -298,7 +297,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_u64(alloc_id.0.get()), dest)?; } "miri_print_borrow_state" => { - let [id, show_unnamed] = this.check_shim(abi, Conv::Rust, link_name, args)?; + let [id, show_unnamed] = this.check_shim(abi, Conv::Rust, link_name, args)?; let id = this.read_scalar(id)?.to_u64()?; let show_unnamed = this.read_scalar(show_unnamed)?.to_bool()?; if let Some(id) = std::num::NonZero::new(id).map(AllocId) @@ -312,8 +311,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "miri_pointer_name" => { // This associates a name to a tag. Very useful for debugging, and also makes // tests more strict. - let [ptr, nth_parent, name] = - this.check_shim(abi, Conv::Rust, link_name, args)?; + let [ptr, nth_parent, name] = this.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let nth_parent = this.read_scalar(nth_parent)?.to_u8()?; let name = this.read_immediate(name)?; @@ -337,8 +335,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.machine.static_roots.push(alloc_id); } "miri_host_to_target_path" => { - let [ptr, out, out_size] = - this.check_shim(abi, Conv::Rust, link_name, args)?; + let [ptr, out, out_size] = this.check_shim(abi, Conv::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let out = this.read_pointer(out)?; let out_size = this.read_scalar(out_size)?.to_target_usize(this)?; @@ -429,13 +426,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Aborting the process. "exit" => { - let [code] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [code] = this.check_shim(abi, Conv::C, link_name, args)?; let code = this.read_scalar(code)?.to_i32()?; throw_machine_stop!(TerminationInfo::Exit { code: code.into(), leak_check: false }); } "abort" => { - let [] = this.check_shim(abi, Conv::C , link_name, args)?; + let [] = this.check_shim(abi, Conv::C, link_name, args)?; throw_machine_stop!(TerminationInfo::Abort( "the program aborted execution".to_owned() )) @@ -443,8 +439,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Standard C allocation "malloc" => { - let [size] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [size] = this.check_shim(abi, Conv::C, link_name, args)?; let size = this.read_target_usize(size)?; if size <= this.max_size_of_val().bytes() { let res = this.malloc(size, /*zero_init:*/ false)?; @@ -458,8 +453,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "calloc" => { - let [items, elem_size] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [items, elem_size] = this.check_shim(abi, Conv::C, link_name, args)?; let items = this.read_target_usize(items)?; let elem_size = this.read_target_usize(elem_size)?; if let Some(size) = this.compute_size_in_bytes(Size::from_bytes(elem_size), items) { @@ -474,14 +468,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "free" => { - let [ptr] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [ptr] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr = this.read_pointer(ptr)?; this.free(ptr)?; } "realloc" => { - let [old_ptr, new_size] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [old_ptr, new_size] = this.check_shim(abi, Conv::C, link_name, args)?; let old_ptr = this.read_pointer(old_ptr)?; let new_size = this.read_target_usize(new_size)?; if new_size <= this.max_size_of_val().bytes() { @@ -619,8 +611,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // C memory handling functions "memcmp" => { - let [left, right, n] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [left, right, n] = this.check_shim(abi, Conv::C, link_name, args)?; let left = this.read_pointer(left)?; let right = this.read_pointer(right)?; let n = Size::from_bytes(this.read_target_usize(n)?); @@ -644,8 +635,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_i32(result), dest)?; } "memrchr" => { - let [ptr, val, num] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [ptr, val, num] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr = this.read_pointer(ptr)?; let val = this.read_scalar(val)?.to_i32()?; let num = this.read_target_usize(num)?; @@ -671,8 +661,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "memchr" => { - let [ptr, val, num] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [ptr, val, num] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr = this.read_pointer(ptr)?; let val = this.read_scalar(val)?.to_i32()?; let num = this.read_target_usize(num)?; @@ -695,8 +684,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "strlen" => { - let [ptr] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [ptr] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr = this.read_pointer(ptr)?; // This reads at least 1 byte, so we are already enforcing that this is a valid pointer. let n = this.read_c_str(ptr)?.len(); @@ -706,8 +694,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; } "wcslen" => { - let [ptr] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [ptr] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr = this.read_pointer(ptr)?; // This reads at least 1 byte, so we are already enforcing that this is a valid pointer. let n = this.read_wchar_t_str(ptr)?.len(); @@ -717,8 +704,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; } "memcpy" => { - let [ptr_dest, ptr_src, n] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [ptr_dest, ptr_src, n] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr_dest = this.read_pointer(ptr_dest)?; let ptr_src = this.read_pointer(ptr_src)?; let n = this.read_target_usize(n)?; @@ -732,8 +718,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_pointer(ptr_dest, dest)?; } "strcpy" => { - let [ptr_dest, ptr_src] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [ptr_dest, ptr_src] = this.check_shim(abi, Conv::C, link_name, args)?; let ptr_dest = this.read_pointer(ptr_dest)?; let ptr_src = this.read_pointer(ptr_src)?; @@ -878,8 +863,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "lgammaf_r" => { - let [x, signp] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [x, signp] = this.check_shim(abi, Conv::C, link_name, args)?; let x = this.read_scalar(x)?.to_f32()?; let signp = this.deref_pointer(signp)?; @@ -890,8 +874,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "lgamma_r" => { - let [x, signp] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [x, signp] = this.check_shim(abi, Conv::C, link_name, args)?; let x = this.read_scalar(x)?.to_f64()?; let signp = this.deref_pointer(signp)?; @@ -904,8 +887,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // LLVM intrinsics "llvm.prefetch" => { - let [p, rw, loc, ty] = - this.check_shim(abi, Conv::C , link_name, args)?; + let [p, rw, loc, ty] = this.check_shim(abi, Conv::C, link_name, args)?; let _ = this.read_pointer(p)?; let rw = this.read_scalar(rw)?.to_i32()?; @@ -932,7 +914,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the x86 `_mm{,256,512}_popcnt_epi{8,16,32,64}` and wasm // `{i,u}8x16_popcnt` functions. name if name.starts_with("llvm.ctpop.v") => { - let [op] = this.check_shim(abi, Conv::C , link_name, args)?; + let [op] = this.check_shim(abi, Conv::C, link_name, args)?; let (op, op_len) = this.project_to_simd(op)?; let (dest, dest_len) = this.project_to_simd(dest)?; diff --git a/src/tools/miri/src/shims/unix/android/foreign_items.rs b/src/tools/miri/src/shims/unix/android/foreign_items.rs index 1a2fa7cfc0f6..0e7cf7153f5b 100644 --- a/src/tools/miri/src/shims/unix/android/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/android/foreign_items.rs @@ -2,8 +2,6 @@ use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::{Conv, FnAbi}; - - use crate::shims::unix::android::thread::prctl; use crate::shims::unix::linux_like::epoll::EvalContextExt as _; use crate::shims::unix::linux_like::eventfd::EvalContextExt as _; @@ -27,14 +25,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // epoll, eventfd "epoll_create1" => { - let [flag] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [flag] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.epoll_create1(flag)?; this.write_scalar(result, dest)?; } "epoll_ctl" => { - let [epfd, op, fd, event] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [epfd, op, fd, event] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.epoll_ctl(epfd, op, fd, event)?; this.write_scalar(result, dest)?; } @@ -44,8 +40,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.epoll_wait(epfd, events, maxevents, timeout, dest)?; } "eventfd" => { - let [val, flag] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [val, flag] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.eventfd(val, flag)?; this.write_scalar(result, dest)?; } diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index ff316e782b0b..f47a96b10fe5 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -2,8 +2,8 @@ use std::ffi::OsStr; use std::str; use rustc_abi::Size; -use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::Ty; +use rustc_middle::ty::layout::LayoutOf; use rustc_span::Symbol; use rustc_target::callconv::{Conv, FnAbi}; diff --git a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs index b617e00e5d5e..5381234e28ca 100644 --- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs @@ -22,8 +22,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Threading "pthread_set_name_np" => { - let [thread, name] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [thread, name] = this.check_shim(abi, Conv::C, link_name, args)?; let max_len = usize::MAX; // FreeBSD does not seem to have a limit. // FreeBSD's pthread_set_name_np does not return anything. this.pthread_setname_np( @@ -34,8 +33,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; } "pthread_get_name_np" => { - let [thread, name, len] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [thread, name, len] = this.check_shim(abi, Conv::C, link_name, args)?; // FreeBSD's pthread_get_name_np does not return anything // and uses strlcpy, which truncates the resulting value, // but always adds a null terminator (except for zero-sized buffers). @@ -52,26 +50,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // For those, we both intercept `func` and `call@FBSD_1.0` symbols cases // since freebsd 12 the former form can be expected. "stat" | "stat@FBSD_1.0" => { - let [path, buf] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_stat(path, buf)?; this.write_scalar(result, dest)?; } "lstat" | "lstat@FBSD_1.0" => { - let [path, buf] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_lstat(path, buf)?; this.write_scalar(result, dest)?; } "fstat" | "fstat@FBSD_1.0" => { - let [fd, buf] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [fd, buf] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_fstat(fd, buf)?; this.write_scalar(result, dest)?; } "readdir_r" | "readdir_r@FBSD_1.0" => { - let [dirp, entry, result] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [dirp, entry, result] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_readdir_r(dirp, entry, result)?; this.write_scalar(result, dest)?; } @@ -86,8 +80,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Incomplete shims that we "stub out" just to get pre-main initialization code to work. // These shims are enabled only when the caller is in the standard library. "pthread_attr_get_np" if this.frame_in_std() => { - let [_thread, _attr] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [_thread, _attr] = this.check_shim(abi, Conv::C, link_name, args)?; this.write_null(dest)?; } diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs index 0a9d8a66b7cd..10af245dcc08 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -36,14 +36,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // File related shims "readdir64" => { - let [dirp] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [dirp] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.linux_solarish_readdir64("dirent64", dirp)?; this.write_scalar(result, dest)?; } "sync_file_range" => { - let [fd, offset, nbytes, flags] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [fd, offset, nbytes, flags] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.sync_file_range(fd, offset, nbytes, flags)?; this.write_scalar(result, dest)?; } @@ -56,14 +54,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // epoll, eventfd "epoll_create1" => { - let [flag] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [flag] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.epoll_create1(flag)?; this.write_scalar(result, dest)?; } "epoll_ctl" => { - let [epfd, op, fd, event] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [epfd, op, fd, event] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.epoll_ctl(epfd, op, fd, event)?; this.write_scalar(result, dest)?; } @@ -73,16 +69,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.epoll_wait(epfd, events, maxevents, timeout, dest)?; } "eventfd" => { - let [val, flag] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [val, flag] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.eventfd(val, flag)?; this.write_scalar(result, dest)?; } // Threading "pthread_setname_np" => { - let [thread, name] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [thread, name] = this.check_shim(abi, Conv::C, link_name, args)?; let res = match this.pthread_setname_np( this.read_scalar(thread)?, this.read_scalar(name)?, @@ -97,8 +91,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "pthread_getname_np" => { - let [thread, name, len] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [thread, name, len] = this.check_shim(abi, Conv::C, link_name, args)?; // The function's behavior isn't portable between platforms. // In case of glibc, the length of the output buffer must // be not shorter than TASK_COMM_LEN. @@ -146,8 +139,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(ptr, dest)?; } "__xpg_strerror_r" => { - let [errnum, buf, buflen] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [errnum, buf, buflen] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.strerror_r(errnum, buf, buflen)?; this.write_scalar(result, dest)?; } @@ -170,8 +162,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Incomplete shims that we "stub out" just to get pre-main initialization code to work. // These shims are enabled only when the caller is in the standard library. "pthread_getattr_np" if this.frame_in_std() => { - let [_thread, _attr] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [_thread, _attr] = this.check_shim(abi, Conv::C, link_name, args)?; this.write_null(dest)?; } diff --git a/src/tools/miri/src/shims/unix/linux_like/syscall.rs b/src/tools/miri/src/shims/unix/linux_like/syscall.rs index 57f10ace6a78..5fb262e176f0 100644 --- a/src/tools/miri/src/shims/unix/linux_like/syscall.rs +++ b/src/tools/miri/src/shims/unix/linux_like/syscall.rs @@ -2,7 +2,6 @@ use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::{Conv, FnAbi}; - use crate::helpers::check_min_arg_count; use crate::shims::unix::linux_like::eventfd::EvalContextExt as _; use crate::shims::unix::linux_like::sync::futex; diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs index 3be6967b7c2f..aa291639a6db 100644 --- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs @@ -33,44 +33,37 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // File related shims "close$NOCANCEL" => { - let [result] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [result] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.close(result)?; this.write_scalar(result, dest)?; } "stat" | "stat64" | "stat$INODE64" => { - let [path, buf] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_stat(path, buf)?; this.write_scalar(result, dest)?; } "lstat" | "lstat64" | "lstat$INODE64" => { - let [path, buf] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_lstat(path, buf)?; this.write_scalar(result, dest)?; } "fstat" | "fstat64" | "fstat$INODE64" => { - let [fd, buf] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [fd, buf] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_fstat(fd, buf)?; this.write_scalar(result, dest)?; } "opendir$INODE64" => { - let [name] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [name] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.opendir(name)?; this.write_scalar(result, dest)?; } "readdir_r" | "readdir_r$INODE64" => { - let [dirp, entry, result] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [dirp, entry, result] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_readdir_r(dirp, entry, result)?; this.write_scalar(result, dest)?; } "realpath$DARWIN_EXTSN" => { - let [path, resolved_path] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [path, resolved_path] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.realpath(path, resolved_path)?; this.write_scalar(result, dest)?; } @@ -84,8 +77,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Random data generation "CCRandomGenerateBytes" => { - let [bytes, count] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [bytes, count] = this.check_shim(abi, Conv::C, link_name, args)?; let bytes = this.read_pointer(bytes)?; let count = this.read_target_usize(count)?; let success = this.eval_libc_i32("kCCSuccess"); @@ -101,8 +93,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "mach_timebase_info" => { - let [info] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [info] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.mach_timebase_info(info)?; this.write_scalar(result, dest)?; } @@ -117,8 +108,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_pointer(this.machine.argv.expect("machine must be initialized"), dest)?; } "_NSGetExecutablePath" => { - let [buf, bufsize] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [buf, bufsize] = this.check_shim(abi, Conv::C, link_name, args)?; this.check_no_isolation("`_NSGetExecutablePath`")?; let buf_ptr = this.read_pointer(buf)?; @@ -143,8 +133,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Thread-local storage "_tlv_atexit" => { - let [dtor, data] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [dtor, data] = this.check_shim(abi, Conv::C, link_name, args)?; let dtor = this.read_pointer(dtor)?; let dtor = this.get_ptr_fn(dtor)?.as_instance()?; let data = this.read_scalar(data)?; @@ -154,15 +143,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Querying system information "pthread_get_stackaddr_np" => { - let [thread] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [thread] = this.check_shim(abi, Conv::C, link_name, args)?; this.read_target_usize(thread)?; let stack_addr = Scalar::from_uint(this.machine.stack_addr, this.pointer_size()); this.write_scalar(stack_addr, dest)?; } "pthread_get_stacksize_np" => { - let [thread] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [thread] = this.check_shim(abi, Conv::C, link_name, args)?; this.read_target_usize(thread)?; let stack_size = Scalar::from_uint(this.machine.stack_size, this.pointer_size()); this.write_scalar(stack_size, dest)?; @@ -170,8 +157,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Threading "pthread_setname_np" => { - let [name] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [name] = this.check_shim(abi, Conv::C, link_name, args)?; // The real implementation has logic in two places: // * in userland at https://github.com/apple-oss-distributions/libpthread/blob/c032e0b076700a0a47db75528a282b8d3a06531a/src/pthread.c#L1178-L1200, @@ -198,8 +184,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "pthread_getname_np" => { - let [thread, name, len] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [thread, name, len] = this.check_shim(abi, Conv::C, link_name, args)?; // The function's behavior isn't portable between platforms. // In case of macOS, a truncated name (due to a too small buffer) @@ -224,28 +209,23 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "os_unfair_lock_lock" => { - let [lock_op] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [lock_op] = this.check_shim(abi, Conv::C, link_name, args)?; this.os_unfair_lock_lock(lock_op)?; } "os_unfair_lock_trylock" => { - let [lock_op] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [lock_op] = this.check_shim(abi, Conv::C, link_name, args)?; this.os_unfair_lock_trylock(lock_op, dest)?; } "os_unfair_lock_unlock" => { - let [lock_op] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [lock_op] = this.check_shim(abi, Conv::C, link_name, args)?; this.os_unfair_lock_unlock(lock_op)?; } "os_unfair_lock_assert_owner" => { - let [lock_op] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [lock_op] = this.check_shim(abi, Conv::C, link_name, args)?; this.os_unfair_lock_assert_owner(lock_op)?; } "os_unfair_lock_assert_not_owner" => { - let [lock_op] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [lock_op] = this.check_shim(abi, Conv::C, link_name, args)?; this.os_unfair_lock_assert_not_owner(lock_op)?; } diff --git a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs index 63b03c5277ce..c99e8ae7c6ef 100644 --- a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs @@ -23,8 +23,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Threading "pthread_setname_np" => { - let [thread, name] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [thread, name] = this.check_shim(abi, Conv::C, link_name, args)?; // THREAD_NAME_MAX allows a thread name of 31+1 length // https://github.com/illumos/illumos-gate/blob/7671517e13b8123748eda4ef1ee165c6d9dba7fe/usr/src/uts/common/sys/thread.h#L613 let max_len = 32; @@ -42,8 +41,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "pthread_getname_np" => { - let [thread, name, len] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [thread, name, len] = this.check_shim(abi, Conv::C, link_name, args)?; // See https://illumos.org/man/3C/pthread_getname_np for the error codes. let res = match this.pthread_getname_np( this.read_scalar(thread)?, @@ -60,26 +58,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // File related shims "stat" | "stat64" => { - let [path, buf] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_stat(path, buf)?; this.write_scalar(result, dest)?; } "lstat" | "lstat64" => { - let [path, buf] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_lstat(path, buf)?; this.write_scalar(result, dest)?; } "fstat" | "fstat64" => { - let [fd, buf] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [fd, buf] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.macos_fbsd_solaris_fstat(fd, buf)?; this.write_scalar(result, dest)?; } "readdir" => { - let [dirp] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [dirp] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.linux_solarish_readdir64("dirent", dirp)?; this.write_scalar(result, dest)?; } @@ -92,8 +86,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "stack_getbounds" => { - let [stack] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [stack] = this.check_shim(abi, Conv::C, link_name, args)?; let stack = this.deref_pointer_as(stack, this.libc_ty_layout("stack_t"))?; this.write_int_fields_named( @@ -111,8 +104,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "pset_info" => { - let [pset, tpe, cpus, list] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [pset, tpe, cpus, list] = this.check_shim(abi, Conv::C, link_name, args)?; // We do not need to handle the current process cpu mask, available_parallelism // implementation pass null anyway. We only care for the number of // cpus. @@ -141,8 +133,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "__sysconf_xpg7" => { - let [val] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [val] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.sysconf(val)?; this.write_scalar(result, dest)?; } diff --git a/src/tools/miri/src/shims/wasi/foreign_items.rs b/src/tools/miri/src/shims/wasi/foreign_items.rs index facb6f8ce3a9..90de62b9e574 100644 --- a/src/tools/miri/src/shims/wasi/foreign_items.rs +++ b/src/tools/miri/src/shims/wasi/foreign_items.rs @@ -22,14 +22,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Allocation "posix_memalign" => { - let [memptr, align, size] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [memptr, align, size] = this.check_shim(abi, Conv::C, link_name, args)?; let result = this.posix_memalign(memptr, align, size)?; this.write_scalar(result, dest)?; } "aligned_alloc" => { - let [align, size] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [align, size] = this.check_shim(abi, Conv::C, link_name, args)?; let res = this.aligned_alloc(align, size)?; this.write_pointer(res, dest)?; } diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index dd531c5956f6..fe4d2158ff95 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -108,50 +108,42 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Environment related shims "GetEnvironmentVariableW" => { - let [name, buf, size] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [name, buf, size] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.GetEnvironmentVariableW(name, buf, size)?; this.write_scalar(result, dest)?; } "SetEnvironmentVariableW" => { - let [name, value] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [name, value] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.SetEnvironmentVariableW(name, value)?; this.write_scalar(result, dest)?; } "GetEnvironmentStringsW" => { - let [] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.GetEnvironmentStringsW()?; this.write_pointer(result, dest)?; } "FreeEnvironmentStringsW" => { - let [env_block] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [env_block] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.FreeEnvironmentStringsW(env_block)?; this.write_scalar(result, dest)?; } "GetCurrentDirectoryW" => { - let [size, buf] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [size, buf] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.GetCurrentDirectoryW(size, buf)?; this.write_scalar(result, dest)?; } "SetCurrentDirectoryW" => { - let [path] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [path] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.SetCurrentDirectoryW(path)?; this.write_scalar(result, dest)?; } "GetUserProfileDirectoryW" => { - let [token, buf, size] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [token, buf, size] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.GetUserProfileDirectoryW(token, buf, size)?; this.write_scalar(result, dest)?; } "GetCurrentProcessId" => { - let [] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.GetCurrentProcessId()?; this.write_scalar(result, dest)?; } @@ -257,8 +249,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Allocation "HeapAlloc" => { - let [handle, flags, size] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [handle, flags, size] = this.check_shim(abi, sys_conv, link_name, args)?; this.read_target_isize(handle)?; let flags = this.read_scalar(flags)?.to_u32()?; let size = this.read_target_usize(size)?; @@ -281,8 +272,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_pointer(ptr, dest)?; } "HeapFree" => { - let [handle, flags, ptr] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [handle, flags, ptr] = this.check_shim(abi, sys_conv, link_name, args)?; this.read_target_isize(handle)?; this.read_scalar(flags)?.to_u32()?; let ptr = this.read_pointer(ptr)?; @@ -314,8 +304,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_pointer(new_ptr, dest)?; } "LocalFree" => { - let [ptr] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [ptr] = this.check_shim(abi, sys_conv, link_name, args)?; let ptr = this.read_pointer(ptr)?; // "If the hMem parameter is NULL, LocalFree ignores the parameter and returns NULL." // (https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-localfree) @@ -327,14 +316,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // errno "SetLastError" => { - let [error] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [error] = this.check_shim(abi, sys_conv, link_name, args)?; let error = this.read_scalar(error)?; this.set_last_error(error)?; } "GetLastError" => { - let [] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [] = this.check_shim(abi, sys_conv, link_name, args)?; let last_error = this.get_last_error()?; this.write_scalar(last_error, dest)?; } @@ -342,8 +329,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Querying system information "GetSystemInfo" => { // Also called from `page_size` crate. - let [system_info] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [system_info] = this.check_shim(abi, sys_conv, link_name, args)?; let system_info = this.deref_pointer_as(system_info, this.windows_ty_layout("SYSTEM_INFO"))?; // Initialize with `0`. @@ -366,22 +352,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // This just creates a key; Windows does not natively support TLS destructors. // Create key and return it. - let [] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [] = this.check_shim(abi, sys_conv, link_name, args)?; let key = this.machine.tls.create_tls_key(None, dest.layout.size)?; this.write_scalar(Scalar::from_uint(key, dest.layout.size), dest)?; } "TlsGetValue" => { - let [key] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [key] = this.check_shim(abi, sys_conv, link_name, args)?; let key = u128::from(this.read_scalar(key)?.to_u32()?); let active_thread = this.active_thread(); let ptr = this.machine.tls.load_tls(key, active_thread, this)?; this.write_scalar(ptr, dest)?; } "TlsSetValue" => { - let [key, new_ptr] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [key, new_ptr] = this.check_shim(abi, sys_conv, link_name, args)?; let key = u128::from(this.read_scalar(key)?.to_u32()?); let active_thread = this.active_thread(); let new_data = this.read_scalar(new_ptr)?; @@ -401,8 +384,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Access to command-line arguments "GetCommandLineW" => { - let [] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [] = this.check_shim(abi, sys_conv, link_name, args)?; this.write_pointer( this.machine.cmd_line.expect("machine must be initialized"), dest, @@ -412,27 +394,23 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Time related shims "GetSystemTimeAsFileTime" | "GetSystemTimePreciseAsFileTime" => { #[allow(non_snake_case)] - let [LPFILETIME] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [LPFILETIME] = this.check_shim(abi, sys_conv, link_name, args)?; this.GetSystemTimeAsFileTime(link_name.as_str(), LPFILETIME)?; } "QueryPerformanceCounter" => { #[allow(non_snake_case)] - let [lpPerformanceCount] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [lpPerformanceCount] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.QueryPerformanceCounter(lpPerformanceCount)?; this.write_scalar(result, dest)?; } "QueryPerformanceFrequency" => { #[allow(non_snake_case)] - let [lpFrequency] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [lpFrequency] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.QueryPerformanceFrequency(lpFrequency)?; this.write_scalar(result, dest)?; } "Sleep" => { - let [timeout] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [timeout] = this.check_shim(abi, sys_conv, link_name, args)?; this.Sleep(timeout)?; } @@ -456,8 +434,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.InitOnceBeginInitialize(ptr, flags, pending, context, dest)?; } "InitOnceComplete" => { - let [ptr, flags, context] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [ptr, flags, context] = this.check_shim(abi, sys_conv, link_name, args)?; let result = this.InitOnceComplete(ptr, flags, context)?; this.write_scalar(result, dest)?; } @@ -468,14 +445,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.WaitOnAddress(ptr_op, compare_op, size_op, timeout_op, dest)?; } "WakeByAddressSingle" => { - let [ptr_op] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [ptr_op] = this.check_shim(abi, sys_conv, link_name, args)?; this.WakeByAddressSingle(ptr_op)?; } "WakeByAddressAll" => { - let [ptr_op] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [ptr_op] = this.check_shim(abi, sys_conv, link_name, args)?; this.WakeByAddressAll(ptr_op)?; } @@ -483,8 +458,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Dynamic symbol loading "GetProcAddress" => { #[allow(non_snake_case)] - let [hModule, lpProcName] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [hModule, lpProcName] = this.check_shim(abi, sys_conv, link_name, args)?; this.read_target_isize(hModule)?; let name = this.read_c_str(this.read_pointer(lpProcName)?)?; if let Ok(name) = str::from_utf8(name) @@ -508,15 +482,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Handle::Thread(thread_id).to_scalar(this), dest)?; } "WaitForSingleObject" => { - let [handle, timeout] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [handle, timeout] = this.check_shim(abi, sys_conv, link_name, args)?; let ret = this.WaitForSingleObject(handle, timeout)?; this.write_scalar(ret, dest)?; } "GetCurrentThread" => { - let [] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [] = this.check_shim(abi, sys_conv, link_name, args)?; this.write_scalar( Handle::Pseudo(PseudoHandle::CurrentThread).to_scalar(this), @@ -524,8 +496,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; } "SetThreadDescription" => { - let [handle, name] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [handle, name] = this.check_shim(abi, sys_conv, link_name, args)?; let handle = this.read_scalar(handle)?; let name = this.read_wide_str(this.read_pointer(name)?)?; @@ -549,8 +520,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "GetThreadDescription" => { - let [handle, name_ptr] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [handle, name_ptr] = this.check_shim(abi, sys_conv, link_name, args)?; let handle = this.read_scalar(handle)?; let name_ptr = this.deref_pointer(name_ptr)?; // the pointer where we should store the ptr to the name @@ -581,16 +551,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Miscellaneous "ExitProcess" => { - let [code] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [code] = this.check_shim(abi, sys_conv, link_name, args)?; let code = this.read_scalar(code)?.to_u32()?; throw_machine_stop!(TerminationInfo::Exit { code: code.into(), leak_check: false }); } "SystemFunction036" => { // used by getrandom 0.1 // This is really 'RtlGenRandom'. - let [ptr, len] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [ptr, len] = this.check_shim(abi, sys_conv, link_name, args)?; let ptr = this.read_pointer(ptr)?; let len = this.read_scalar(len)?.to_u32()?; this.gen_random(ptr, len.into())?; @@ -598,8 +566,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "ProcessPrng" => { // used by `std` - let [ptr, len] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [ptr, len] = this.check_shim(abi, sys_conv, link_name, args)?; let ptr = this.read_pointer(ptr)?; let len = this.read_target_usize(len)?; this.gen_random(ptr, len)?; @@ -642,8 +609,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "GetConsoleScreenBufferInfo" => { // `term` needs this, so we fake it. - let [console, buffer_info] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [console, buffer_info] = this.check_shim(abi, sys_conv, link_name, args)?; this.read_target_isize(console)?; // FIXME: this should use deref_pointer_as, but CONSOLE_SCREEN_BUFFER_INFO is not in std this.deref_pointer(buffer_info)?; @@ -652,8 +618,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_null(dest)?; } "GetStdHandle" => { - let [which] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [which] = this.check_shim(abi, sys_conv, link_name, args)?; let which = this.read_scalar(which)?.to_i32()?; // We just make this the identity function, so we know later in `NtWriteFile` which // one it is. This is very fake, but libtest needs it so we cannot make it a @@ -662,16 +627,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_target_isize(which.into(), this), dest)?; } "CloseHandle" => { - let [handle] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [handle] = this.check_shim(abi, sys_conv, link_name, args)?; let ret = this.CloseHandle(handle)?; this.write_scalar(ret, dest)?; } "GetModuleFileNameW" => { - let [handle, filename, size] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [handle, filename, size] = this.check_shim(abi, sys_conv, link_name, args)?; this.check_no_isolation("`GetModuleFileNameW`")?; let handle = this.read_target_usize(handle)?; @@ -740,16 +703,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Incomplete shims that we "stub out" just to get pre-main initialization code to work. // These shims are enabled only when the caller is in the standard library. "GetProcessHeap" if this.frame_in_std() => { - let [] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [] = this.check_shim(abi, sys_conv, link_name, args)?; // Just fake a HANDLE // It's fine to not use the Handle type here because its a stub this.write_int(1, dest)?; } "GetModuleHandleA" if this.frame_in_std() => { #[allow(non_snake_case)] - let [_lpModuleName] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [_lpModuleName] = this.check_shim(abi, sys_conv, link_name, args)?; // We need to return something non-null here to make `compat_fn!` work. this.write_int(1, dest)?; } @@ -761,8 +722,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_null(dest)?; } "GetConsoleMode" if this.frame_in_std() => { - let [console, mode] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [console, mode] = this.check_shim(abi, sys_conv, link_name, args)?; this.read_target_isize(console)?; this.deref_pointer(mode)?; // Indicate an error. @@ -770,29 +730,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "GetFileType" if this.frame_in_std() => { #[allow(non_snake_case)] - let [_hFile] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [_hFile] = this.check_shim(abi, sys_conv, link_name, args)?; // Return unknown file type. this.write_null(dest)?; } "AddVectoredExceptionHandler" if this.frame_in_std() => { #[allow(non_snake_case)] - let [_First, _Handler] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [_First, _Handler] = this.check_shim(abi, sys_conv, link_name, args)?; // Any non zero value works for the stdlib. This is just used for stack overflows anyway. this.write_int(1, dest)?; } "SetThreadStackGuarantee" if this.frame_in_std() => { #[allow(non_snake_case)] - let [_StackSizeInBytes] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [_StackSizeInBytes] = this.check_shim(abi, sys_conv, link_name, args)?; // Any non zero value works for the stdlib. This is just used for stack overflows anyway. this.write_int(1, dest)?; } // this is only callable from std because we know that std ignores the return value "SwitchToThread" if this.frame_in_std() => { - let [] = - this.check_shim(abi, sys_conv, link_name, args)?; + let [] = this.check_shim(abi, sys_conv, link_name, args)?; this.yield_active_thread(); @@ -811,8 +767,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); } // This function looks and behaves excatly like miri_start_unwind. - let [payload] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [payload] = this.check_shim(abi, Conv::C, link_name, args)?; this.handle_miri_start_unwind(payload)?; return interp_ok(EmulateItemResult::NeedsUnwind); } diff --git a/src/tools/miri/src/shims/x86/aesni.rs b/src/tools/miri/src/shims/x86/aesni.rs index a89a2bb0cd08..c6784db67fb8 100644 --- a/src/tools/miri/src/shims/x86/aesni.rs +++ b/src/tools/miri/src/shims/x86/aesni.rs @@ -26,8 +26,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `state` with the corresponding 128-bit key of `key`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdec_si128 "aesdec" | "aesdec.256" | "aesdec.512" => { - let [state, key] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [state, key] = this.check_shim(abi, Conv::C, link_name, args)?; aes_round(this, state, key, dest, |state, key| { let key = aes::Block::from(key.to_le_bytes()); let mut state = aes::Block::from(state.to_le_bytes()); @@ -43,8 +42,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `state` with the corresponding 128-bit key of `key`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdeclast_si128 "aesdeclast" | "aesdeclast.256" | "aesdeclast.512" => { - let [state, key] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [state, key] = this.check_shim(abi, Conv::C, link_name, args)?; aes_round(this, state, key, dest, |state, key| { let mut state = aes::Block::from(state.to_le_bytes()); @@ -68,8 +66,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `state` with the corresponding 128-bit key of `key`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenc_si128 "aesenc" | "aesenc.256" | "aesenc.512" => { - let [state, key] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [state, key] = this.check_shim(abi, Conv::C, link_name, args)?; aes_round(this, state, key, dest, |state, key| { let key = aes::Block::from(key.to_le_bytes()); let mut state = aes::Block::from(state.to_le_bytes()); @@ -85,8 +82,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `state` with the corresponding 128-bit key of `key`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenclast_si128 "aesenclast" | "aesenclast.256" | "aesenclast.512" => { - let [state, key] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [state, key] = this.check_shim(abi, Conv::C, link_name, args)?; aes_round(this, state, key, dest, |state, key| { let mut state = aes::Block::from(state.to_le_bytes()); // `aes::hazmat::cipher_round` does the following operations: diff --git a/src/tools/miri/src/shims/x86/avx.rs b/src/tools/miri/src/shims/x86/avx.rs index 07bbd0731d81..3aeb2b429dad 100644 --- a/src/tools/miri/src/shims/x86/avx.rs +++ b/src/tools/miri/src/shims/x86/avx.rs @@ -33,8 +33,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // matches the IEEE min/max operations, while x86 has different // semantics. "min.ps.256" | "max.ps.256" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "min.ps.256" => FloatBinOp::Min, @@ -46,8 +45,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Used to implement _mm256_min_pd and _mm256_max_pd functions. "min.pd.256" | "max.pd.256" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "min.pd.256" => FloatBinOp::Min, @@ -60,16 +58,14 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the _mm256_round_ps function. // Rounds the elements of `op` according to `rounding`. "round.ps.256" => { - let [op, rounding] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [op, rounding] = this.check_shim(abi, Conv::C, link_name, args)?; round_all::(this, op, rounding, dest)?; } // Used to implement the _mm256_round_pd function. // Rounds the elements of `op` according to `rounding`. "round.pd.256" => { - let [op, rounding] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [op, rounding] = this.check_shim(abi, Conv::C, link_name, args)?; round_all::(this, op, rounding, dest)?; } @@ -88,8 +84,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Used to implement the _mm256_dp_ps function. "dp.ps.256" => { - let [left, right, imm] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; conditional_dot_product(this, left, right, imm, dest)?; } @@ -97,8 +92,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Horizontally add/subtract adjacent floating point values // in `left` and `right`. "hadd.ps.256" | "hadd.pd.256" | "hsub.ps.256" | "hsub.pd.256" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "hadd.ps.256" | "hadd.pd.256" => mir::BinOp::Add, @@ -113,8 +107,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // and `right`. For each component, returns 0 if false or u32::MAX // if true. "cmp.ps.256" => { - let [left, right, imm] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -126,8 +119,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // and `right`. For each component, returns 0 if false or u64::MAX // if true. "cmp.pd.256" => { - let [left, right, imm] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -156,8 +148,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // sequence of 4-element arrays, and we shuffle each of these arrays, where // `control` determines which element of the current `data` array is written. "vpermilvar.ps" | "vpermilvar.ps.256" => { - let [data, control] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [data, control] = this.check_shim(abi, Conv::C, link_name, args)?; let (data, data_len) = this.project_to_simd(data)?; let (control, control_len) = this.project_to_simd(control)?; @@ -190,8 +181,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // where `right` determines which element of the current `left` array is // written. "vpermilvar.pd" | "vpermilvar.pd.256" => { - let [data, control] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [data, control] = this.check_shim(abi, Conv::C, link_name, args)?; let (data, data_len) = this.project_to_simd(data)?; let (control, control_len) = this.project_to_simd(control)?; @@ -223,8 +213,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // For each 128-bit element of `dest`, copies one from `left`, `right` or // zero, according to `imm`. "vperm2f128.ps.256" | "vperm2f128.pd.256" | "vperm2f128.si.256" => { - let [left, right, imm] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; assert_eq!(dest.layout, left.layout); assert_eq!(dest.layout, right.layout); @@ -267,8 +256,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // is one, it is loaded from `ptr.wrapping_add(i)`, otherwise zero is // loaded. "maskload.ps" | "maskload.pd" | "maskload.ps.256" | "maskload.pd.256" => { - let [ptr, mask] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [ptr, mask] = this.check_shim(abi, Conv::C, link_name, args)?; mask_load(this, ptr, mask, dest)?; } @@ -278,8 +266,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // is one, it is stored into `ptr.wapping_add(i)`. // Unlike SSE2's _mm_maskmoveu_si128, these are not non-temporal stores. "maskstore.ps" | "maskstore.pd" | "maskstore.ps.256" | "maskstore.pd.256" => { - let [ptr, mask, value] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [ptr, mask, value] = this.check_shim(abi, Conv::C, link_name, args)?; mask_store(this, ptr, mask, value)?; } @@ -289,8 +276,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // the data crosses a cache line, but for Miri this is just a regular // unaligned read. "ldu.dq.256" => { - let [src_ptr] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [src_ptr] = this.check_shim(abi, Conv::C, link_name, args)?; let src_ptr = this.read_pointer(src_ptr)?; let dest = dest.force_mplace(this)?; @@ -302,8 +288,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Tests `op & mask == 0`, `op & mask == mask` or // `op & mask != 0 && op & mask != mask` "ptestz.256" | "ptestc.256" | "ptestnzc.256" => { - let [op, mask] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [op, mask] = this.check_shim(abi, Conv::C, link_name, args)?; let (all_zero, masked_set) = test_bits_masked(this, op, mask)?; let res = match unprefixed_name { @@ -326,8 +311,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "vtestz.pd.256" | "vtestc.pd.256" | "vtestnzc.pd.256" | "vtestz.pd" | "vtestc.pd" | "vtestnzc.pd" | "vtestz.ps.256" | "vtestc.ps.256" | "vtestnzc.ps.256" | "vtestz.ps" | "vtestc.ps" | "vtestnzc.ps" => { - let [op, mask] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [op, mask] = this.check_shim(abi, Conv::C, link_name, args)?; let (direct, negated) = test_high_bits_masked(this, op, mask)?; let res = match unprefixed_name { diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs index 76e4b06d5cfd..c79899285cd4 100644 --- a/src/tools/miri/src/shims/x86/avx2.rs +++ b/src/tools/miri/src/shims/x86/avx2.rs @@ -36,8 +36,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Horizontally add / add with saturation / subtract adjacent 16/32-bit // integer values in `left` and `right`. "phadd.w" | "phadd.sw" | "phadd.d" | "phsub.w" | "phsub.sw" | "phsub.d" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (which, saturating) = match unprefixed_name { "phadd.w" | "phadd.d" => (mir::BinOp::Add, false), @@ -115,8 +114,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // intermediate signed 32-bit integers. Horizontally add adjacent pairs of // intermediate 32-bit integers, and pack the results in `dest`. "pmadd.wd" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -152,8 +150,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // the saturating sum of the products with indices `2*i` and `2*i+1` // produces the output at index `i`. "pmadd.ub.sw" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -187,8 +184,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // is one, it is loaded from `ptr.wrapping_add(i)`, otherwise zero is // loaded. "maskload.d" | "maskload.q" | "maskload.d.256" | "maskload.q.256" => { - let [ptr, mask] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [ptr, mask] = this.check_shim(abi, Conv::C, link_name, args)?; mask_load(this, ptr, mask, dest)?; } @@ -198,8 +194,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // is one, it is stored into `ptr.wapping_add(i)`. // Unlike SSE2's _mm_maskmoveu_si128, these are not non-temporal stores. "maskstore.d" | "maskstore.q" | "maskstore.d.256" | "maskstore.q.256" => { - let [ptr, mask, value] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [ptr, mask, value] = this.check_shim(abi, Conv::C, link_name, args)?; mask_store(this, ptr, mask, value)?; } @@ -210,8 +205,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // offsets specified in `imm`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_mpsadbw_epu8 "mpsadbw" => { - let [left, right, imm] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; mpsadbw(this, left, right, imm, dest)?; } @@ -222,8 +216,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // 1 and then taking the bits `1..=16`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_mulhrs_epi16 "pmul.hr.sw" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; pmulhrsw(this, left, right, dest)?; } @@ -231,8 +224,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Converts two 16-bit integer vectors to a single 8-bit integer // vector with signed saturation. "packsswb" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; packsswb(this, left, right, dest)?; } @@ -240,8 +232,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Converts two 32-bit integer vectors to a single 16-bit integer // vector with signed saturation. "packssdw" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; packssdw(this, left, right, dest)?; } @@ -249,8 +240,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Converts two 16-bit signed integer vectors to a single 8-bit // unsigned integer vector with saturation. "packuswb" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; packuswb(this, left, right, dest)?; } @@ -258,8 +248,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Concatenates two 32-bit signed integer vectors and converts // the result to a 16-bit unsigned integer vector with saturation. "packusdw" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; packusdw(this, left, right, dest)?; } @@ -268,8 +257,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Shuffles `left` using the three low bits of each element of `right` // as indices. "permd" | "permps" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -289,8 +277,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the _mm256_permute2x128_si256 function. // Shuffles 128-bit blocks of `a` and `b` using `imm` as pattern. "vperm2i128" => { - let [left, right, imm] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; assert_eq!(left.layout.size.bits(), 256); assert_eq!(right.layout.size.bits(), 256); @@ -327,8 +314,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // in `dest`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_sad_epu8 "psad.bw" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -360,8 +346,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Shuffles bytes from `left` using `right` as pattern. // Each 128-bit block is shuffled independently. "pshuf.b" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -392,8 +377,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // is writen to the corresponding output element. // Basically, we multiply `left` with `right.signum()`. "psign.b" | "psign.w" | "psign.d" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; psign(this, left, right, dest)?; } @@ -407,8 +391,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // is copied to remaining bits. "psll.w" | "psrl.w" | "psra.w" | "psll.d" | "psrl.d" | "psra.d" | "psll.q" | "psrl.q" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "psll.w" | "psll.d" | "psll.q" => ShiftOp::Left, @@ -423,8 +406,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // (except _mm{,256}_srav_epi64, which are not available in AVX2). "psllv.d" | "psllv.d.256" | "psllv.q" | "psllv.q.256" | "psrlv.d" | "psrlv.d.256" | "psrlv.q" | "psrlv.q.256" | "psrav.d" | "psrav.d.256" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "psllv.d" | "psllv.d.256" | "psllv.q" | "psllv.q.256" => ShiftOp::Left, diff --git a/src/tools/miri/src/shims/x86/bmi.rs b/src/tools/miri/src/shims/x86/bmi.rs index b52807647384..8af59df0a68b 100644 --- a/src/tools/miri/src/shims/x86/bmi.rs +++ b/src/tools/miri/src/shims/x86/bmi.rs @@ -1,5 +1,5 @@ -use rustc_span::Symbol; use rustc_middle::ty::Ty; +use rustc_span::Symbol; use rustc_target::callconv::{Conv, FnAbi}; use crate::*; @@ -34,8 +34,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { return interp_ok(EmulateItemResult::NotSupported); } - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let left = this.read_scalar(left)?; let right = this.read_scalar(right)?; diff --git a/src/tools/miri/src/shims/x86/gfni.rs b/src/tools/miri/src/shims/x86/gfni.rs index 48718ea609c4..4774ec9f9d8f 100644 --- a/src/tools/miri/src/shims/x86/gfni.rs +++ b/src/tools/miri/src/shims/x86/gfni.rs @@ -1,5 +1,5 @@ -use rustc_span::Symbol; use rustc_middle::ty::Ty; +use rustc_span::Symbol; use rustc_target::callconv::{Conv, FnAbi}; use crate::*; @@ -30,16 +30,14 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // See `affine_transform` for details. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8affine_ "vgf2p8affineqb.128" | "vgf2p8affineqb.256" | "vgf2p8affineqb.512" => { - let [left, right, imm8] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right, imm8] = this.check_shim(abi, Conv::C, link_name, args)?; affine_transform(this, left, right, imm8, dest, /* inverse */ false)?; } // Used to implement the `_mm{, 256, 512}_gf2p8affineinv_epi64_epi8` functions. // See `affine_transform` for details. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8affineinv "vgf2p8affineinvqb.128" | "vgf2p8affineinvqb.256" | "vgf2p8affineinvqb.512" => { - let [left, right, imm8] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right, imm8] = this.check_shim(abi, Conv::C, link_name, args)?; affine_transform(this, left, right, imm8, dest, /* inverse */ true)?; } // Used to implement the `_mm{, 256, 512}_gf2p8mul_epi8` functions. @@ -48,8 +46,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // polynomial representation with the reduction polynomial x^8 + x^4 + x^3 + x + 1. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8mul "vgf2p8mulb.128" | "vgf2p8mulb.256" | "vgf2p8mulb.512" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; let (dest, dest_len) = this.project_to_simd(dest)?; diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 13439f421286..e57217dc6f29 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -68,8 +68,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { if is_u64 && this.tcx.sess.target.arch != "x86_64" { return interp_ok(EmulateItemResult::NotSupported); } - let [c_in, a, b, out] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [c_in, a, b, out] = this.check_shim(abi, Conv::C, link_name, args)?; let out = this.deref_pointer_as( out, if is_u64 { this.machine.layouts.u64 } else { this.machine.layouts.u32 }, @@ -105,8 +104,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { len = 8; } - let [left, right, imm] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; pclmulqdq(this, left, right, imm, dest, len)?; } diff --git a/src/tools/miri/src/shims/x86/sha.rs b/src/tools/miri/src/shims/x86/sha.rs index 07cc87a35bf5..6d2c151243ca 100644 --- a/src/tools/miri/src/shims/x86/sha.rs +++ b/src/tools/miri/src/shims/x86/sha.rs @@ -52,8 +52,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match unprefixed_name { // Used to implement the _mm_sha256rnds2_epu32 function. "256rnds2" => { - let [a, b, k] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [a, b, k] = this.check_shim(abi, Conv::C, link_name, args)?; let (a_reg, a_len) = this.project_to_simd(a)?; let (b_reg, b_len) = this.project_to_simd(b)?; @@ -74,8 +73,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Used to implement the _mm_sha256msg1_epu32 function. "256msg1" => { - let [a, b] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [a, b] = this.check_shim(abi, Conv::C, link_name, args)?; let (a_reg, a_len) = this.project_to_simd(a)?; let (b_reg, b_len) = this.project_to_simd(b)?; @@ -93,8 +91,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Used to implement the _mm_sha256msg2_epu32 function. "256msg2" => { - let [a, b] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [a, b] = this.check_shim(abi, Conv::C, link_name, args)?; let (a_reg, a_len) = this.project_to_simd(a)?; let (b_reg, b_len) = this.project_to_simd(b)?; diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs index e13265fba4f0..fd7aba2437a5 100644 --- a/src/tools/miri/src/shims/x86/sse.rs +++ b/src/tools/miri/src/shims/x86/sse.rs @@ -33,8 +33,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Performs the operations on the first component of `left` and // `right` and copies the remaining components from `left`. "min.ss" | "max.ss" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "min.ss" => FloatBinOp::Min, @@ -50,8 +49,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // matches the IEEE min/max operations, while x86 has different // semantics. "min.ps" | "max.ps" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "min.ps" => FloatBinOp::Min, @@ -97,8 +95,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // _mm_cmp{eq,lt,le,gt,ge,neq,nlt,nle,ngt,nge,ord,unord}_ss are SSE functions // with hard-coded operations. "cmp.ss" => { - let [left, right, imm] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -114,8 +111,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // _mm_cmp{eq,lt,le,gt,ge,neq,nlt,nle,ngt,nge,ord,unord}_ps are SSE functions // with hard-coded operations. "cmp.ps" => { - let [left, right, imm] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -128,8 +124,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "comieq.ss" | "comilt.ss" | "comile.ss" | "comigt.ss" | "comige.ss" | "comineq.ss" | "ucomieq.ss" | "ucomilt.ss" | "ucomile.ss" | "ucomigt.ss" | "ucomige.ss" | "ucomineq.ss" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -185,8 +180,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // are copied from `left`. // https://www.felixcloutier.com/x86/cvtsi2ss "cvtsi2ss" | "cvtsi642ss" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (dest, dest_len) = this.project_to_simd(dest)?; diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index 959590e9791f..e0695b7cb7b7 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -40,8 +40,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // intermediate signed 32-bit integers. Horizontally add adjacent pairs of // intermediate 32-bit integers, and pack the results in `dest`. "pmadd.wd" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -79,8 +78,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sad_epu8 "psad.bw" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -118,8 +116,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // is copied to remaining bits. "psll.w" | "psrl.w" | "psra.w" | "psll.d" | "psrl.d" | "psra.d" | "psll.q" | "psrl.q" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "psll.w" | "psll.d" | "psll.q" => ShiftOp::Left, @@ -171,8 +168,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Converts two 16-bit integer vectors to a single 8-bit integer // vector with signed saturation. "packsswb.128" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; packsswb(this, left, right, dest)?; } @@ -180,8 +176,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Converts two 16-bit signed integer vectors to a single 8-bit // unsigned integer vector with saturation. "packuswb.128" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; packuswb(this, left, right, dest)?; } @@ -189,8 +184,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Converts two 32-bit integer vectors to a single 16-bit integer // vector with signed saturation. "packssdw.128" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; packssdw(this, left, right, dest)?; } @@ -200,8 +194,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // matches the IEEE min/max operations, while x86 has different // semantics. "min.sd" | "max.sd" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "min.sd" => FloatBinOp::Min, @@ -217,8 +210,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // matches the IEEE min/max operations, while x86 has different // semantics. "min.pd" | "max.pd" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "min.pd" => FloatBinOp::Min, @@ -237,8 +229,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // _mm_cmp{eq,lt,le,gt,ge,neq,nlt,nle,ngt,nge,ord,unord}_sd are SSE2 functions // with hard-coded operations. "cmp.sd" => { - let [left, right, imm] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -254,8 +245,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // _mm_cmp{eq,lt,le,gt,ge,neq,nlt,nle,ngt,nge,ord,unord}_pd are SSE2 functions // with hard-coded operations. "cmp.pd" => { - let [left, right, imm] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -268,8 +258,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "comieq.sd" | "comilt.sd" | "comile.sd" | "comigt.sd" | "comige.sd" | "comineq.sd" | "ucomieq.sd" | "ucomilt.sd" | "ucomile.sd" | "ucomigt.sd" | "ucomige.sd" | "ucomineq.sd" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -323,8 +312,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Converts the first f64/f32 from `right` to f32/f64 and copies // the remaining elements from `left` "cvtsd2ss" | "cvtss2sd" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, _) = this.project_to_simd(right)?; diff --git a/src/tools/miri/src/shims/x86/sse3.rs b/src/tools/miri/src/shims/x86/sse3.rs index 4ebd0240b1d3..60b7764a01e9 100644 --- a/src/tools/miri/src/shims/x86/sse3.rs +++ b/src/tools/miri/src/shims/x86/sse3.rs @@ -25,8 +25,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Horizontally add/subtract adjacent floating point values // in `left` and `right`. "hadd.ps" | "hadd.pd" | "hsub.ps" | "hsub.pd" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let which = match unprefixed_name { "hadd.ps" | "hadd.pd" => mir::BinOp::Add, @@ -42,8 +41,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // the data crosses a cache line, but for Miri this is just a regular // unaligned read. "ldu.dq" => { - let [src_ptr] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [src_ptr] = this.check_shim(abi, Conv::C, link_name, args)?; let src_ptr = this.read_pointer(src_ptr)?; let dest = dest.force_mplace(this)?; diff --git a/src/tools/miri/src/shims/x86/sse41.rs b/src/tools/miri/src/shims/x86/sse41.rs index 41b7feab857b..93d689a3044e 100644 --- a/src/tools/miri/src/shims/x86/sse41.rs +++ b/src/tools/miri/src/shims/x86/sse41.rs @@ -27,8 +27,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // bits `4..=5` if `imm`, and `i`th bit specifies whether element // `i` is zeroed. "insertps" => { - let [left, right, imm] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -63,8 +62,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Concatenates two 32-bit signed integer vectors and converts // the result to a 16-bit unsigned integer vector with saturation. "packusdw" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; packusdw(this, left, right, dest)?; } @@ -74,8 +72,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // products, and conditionally stores the sum in `dest` using the low // 4 bits of `imm`. "dpps" | "dppd" => { - let [left, right, imm] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; conditional_dot_product(this, left, right, imm, dest)?; } @@ -83,16 +80,14 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // functions. Rounds the first element of `right` according to `rounding` // and copies the remaining elements from `left`. "round.ss" => { - let [left, right, rounding] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right, rounding] = this.check_shim(abi, Conv::C, link_name, args)?; round_first::(this, left, right, rounding, dest)?; } // Used to implement the _mm_floor_ps, _mm_ceil_ps and _mm_round_ps // functions. Rounds the elements of `op` according to `rounding`. "round.ps" => { - let [op, rounding] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [op, rounding] = this.check_shim(abi, Conv::C, link_name, args)?; round_all::(this, op, rounding, dest)?; } @@ -100,16 +95,14 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // functions. Rounds the first element of `right` according to `rounding` // and copies the remaining elements from `left`. "round.sd" => { - let [left, right, rounding] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right, rounding] = this.check_shim(abi, Conv::C, link_name, args)?; round_first::(this, left, right, rounding, dest)?; } // Used to implement the _mm_floor_pd, _mm_ceil_pd and _mm_round_pd // functions. Rounds the elements of `op` according to `rounding`. "round.pd" => { - let [op, rounding] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [op, rounding] = this.check_shim(abi, Conv::C, link_name, args)?; round_all::(this, op, rounding, dest)?; } @@ -151,8 +144,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // offsets specified in `imm`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mpsadbw_epu8 "mpsadbw" => { - let [left, right, imm] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?; mpsadbw(this, left, right, imm, dest)?; } @@ -161,8 +153,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Tests `(op & mask) == 0`, `(op & mask) == mask` or // `(op & mask) != 0 && (op & mask) != mask` "ptestz" | "ptestc" | "ptestnzc" => { - let [op, mask] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [op, mask] = this.check_shim(abi, Conv::C, link_name, args)?; let (all_zero, masked_set) = test_bits_masked(this, op, mask)?; let res = match unprefixed_name { diff --git a/src/tools/miri/src/shims/x86/sse42.rs b/src/tools/miri/src/shims/x86/sse42.rs index 6ac69d22a934..02336a722f7e 100644 --- a/src/tools/miri/src/shims/x86/sse42.rs +++ b/src/tools/miri/src/shims/x86/sse42.rs @@ -223,8 +223,7 @@ fn deconstruct_args<'tcx>( }; if is_explicit { - let [str1, len1, str2, len2, imm] = - ecx.check_shim(abi, Conv::C, link_name, args)?; + let [str1, len1, str2, len2, imm] = ecx.check_shim(abi, Conv::C, link_name, args)?; let imm = ecx.read_scalar(imm)?.to_u8()?; let default_len = default_len::(imm); @@ -237,8 +236,7 @@ fn deconstruct_args<'tcx>( interp_ok((str1, str2, Some((len1, len2)), imm)) } else { - let [str1, str2, imm] = - ecx.check_shim(abi, Conv::C, link_name, args)?; + let [str1, str2, imm] = ecx.check_shim(abi, Conv::C, link_name, args)?; let imm = ecx.read_scalar(imm)?.to_u8()?; let array_layout = array_layout_fn(ecx, imm)?; @@ -388,8 +386,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // search for a null terminator (see `deconstruct_args` for more details). // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=924,925 "pcmpistriz128" | "pcmpistris128" => { - let [str1, str2, imm] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [str1, str2, imm] = this.check_shim(abi, Conv::C, link_name, args)?; let imm = this.read_scalar(imm)?.to_u8()?; let str = if unprefixed_name == "pcmpistris128" { str1 } else { str2 }; @@ -409,8 +406,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // than 16 for byte-sized operands or 8 for word-sized operands. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=1046,1047 "pcmpestriz128" | "pcmpestris128" => { - let [_, len1, _, len2, imm] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [_, len1, _, len2, imm] = this.check_shim(abi, Conv::C, link_name, args)?; let len = if unprefixed_name == "pcmpestris128" { len1 } else { len2 }; let len = this.read_scalar(len)?.to_i32()?; let imm = this.read_scalar(imm)?.to_u8()?; @@ -437,8 +433,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { return interp_ok(EmulateItemResult::NotSupported); } - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let left = this.read_scalar(left)?; let right = this.read_scalar(right)?; diff --git a/src/tools/miri/src/shims/x86/ssse3.rs b/src/tools/miri/src/shims/x86/ssse3.rs index d3971d0c92f1..f3e9ac0e5dc9 100644 --- a/src/tools/miri/src/shims/x86/ssse3.rs +++ b/src/tools/miri/src/shims/x86/ssse3.rs @@ -32,8 +32,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Shuffles bytes from `left` using `right` as pattern. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_shuffle_epi8 "pshuf.b.128" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -62,8 +61,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // integer values in `left` and `right`. "phadd.w.128" | "phadd.sw.128" | "phadd.d.128" | "phsub.w.128" | "phsub.sw.128" | "phsub.d.128" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (which, saturating) = match unprefixed_name { "phadd.w.128" | "phadd.d.128" => (mir::BinOp::Add, false), @@ -82,8 +80,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // produces the output at index `i`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_maddubs_epi16 "pmadd.ub.sw.128" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -118,8 +115,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // 1 and then taking the bits `1..=16`. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mulhrs_epi16 "pmul.hr.sw.128" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; pmulhrsw(this, left, right, dest)?; } @@ -129,8 +125,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // is writen to the corresponding output element. // Basically, we multiply `left` with `right.signum()`. "psign.b.128" | "psign.w.128" | "psign.d.128" => { - let [left, right] = - this.check_shim(abi, Conv::C, link_name, args)?; + let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?; psign(this, left, right, dest)?; }