Auto merge of #107980 - Dylan-DPC:rollup-u4b19bl, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - #107654 (reword descriptions of the deprecated int modules) - #107915 (Add `array::map` benchmarks) - #107961 (Avoid copy-pasting the `ilog` panic string in a bunch of places) - #107962 (Add a doc note about why `Chain` is not `ExactSizeIterator`) - #107966 (Update browser-ui-test version to 0.14.3) - #107970 (Hermit: Remove floor symbol) - #107973 (Fix unintentional UB in SIMD tests) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
20081880ad
24 changed files with 155 additions and 178 deletions
19
library/core/benches/array.rs
Normal file
19
library/core/benches/array.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
use test::black_box;
|
||||
use test::Bencher;
|
||||
|
||||
macro_rules! map_array {
|
||||
($func_name:ident, $start_item: expr, $map_item: expr, $arr_size: expr) => {
|
||||
#[bench]
|
||||
fn $func_name(b: &mut Bencher) {
|
||||
let arr = [$start_item; $arr_size];
|
||||
b.iter(|| black_box(arr).map(|_| black_box($map_item)));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
map_array!(map_8byte_8byte_8, 0u64, 1u64, 800);
|
||||
map_array!(map_8byte_8byte_64, 0u64, 1u64, 6400);
|
||||
map_array!(map_8byte_8byte_256, 0u64, 1u64, 25600);
|
||||
|
||||
map_array!(map_8byte_256byte_256, 0u64, [0u64; 4], 25600);
|
||||
map_array!(map_256byte_8byte_256, [0u64; 4], 0u64, 25600);
|
|
@ -9,6 +9,7 @@
|
|||
extern crate test;
|
||||
|
||||
mod any;
|
||||
mod array;
|
||||
mod ascii;
|
||||
mod char;
|
||||
mod fmt;
|
||||
|
|
|
@ -21,6 +21,16 @@
|
|||
///
|
||||
/// [`len`]: ExactSizeIterator::len
|
||||
///
|
||||
/// # When *shouldn't* an adapter be `ExactSizeIterator`?
|
||||
///
|
||||
/// If an adapter makes an iterator *longer*, then it's usually incorrect for
|
||||
/// that adapter to implement `ExactSizeIterator`. The inner exact-sized
|
||||
/// iterator might already be `usize::MAX`-long, and thus the length of the
|
||||
/// longer adapted iterator would no longer be exactly representable in `usize`.
|
||||
///
|
||||
/// This is why [`Chain<A, B>`](crate::iter::Chain) isn't `ExactSizeIterator`,
|
||||
/// even when `A` and `B` are both `ExactSizeIterator`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
|
|
|
@ -31,6 +31,17 @@ impl<I: FusedIterator + ?Sized> FusedIterator for &mut I {}
|
|||
/// The iterator must produce exactly the number of elements it reported
|
||||
/// or diverge before reaching the end.
|
||||
///
|
||||
/// # When *shouldn't* an adapter be `TrustedLen`?
|
||||
///
|
||||
/// If an adapter makes an iterator *shorter* by a given amount, then it's
|
||||
/// usually incorrect for that adapter to implement `TrustedLen`. The inner
|
||||
/// iterator might return more than `usize::MAX` items, but there's no way to
|
||||
/// know what `k` elements less than that will be, since the `size_hint` from
|
||||
/// the inner iterator has already saturated and lost that information.
|
||||
///
|
||||
/// This is why [`Skip<I>`](crate::iter::Skip) isn't `TrustedLen`, even when
|
||||
/// `I` implements `TrustedLen`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This trait must only be implemented when the contract is upheld. Consumers
|
||||
|
|
|
@ -138,3 +138,11 @@ pub const fn i64(val: i64) -> u32 {
|
|||
pub const fn i128(val: i128) -> u32 {
|
||||
u128(val as u128)
|
||||
}
|
||||
|
||||
/// Instantiate this panic logic once, rather than for all the ilog methods
|
||||
/// on every single primitive type.
|
||||
#[cold]
|
||||
#[track_caller]
|
||||
pub const fn panic_for_nonpositive_argument() -> ! {
|
||||
panic!("argument of integer logarithm must be positive")
|
||||
}
|
||||
|
|
|
@ -2331,14 +2331,17 @@ macro_rules! int_impl {
|
|||
/// ```
|
||||
#[stable(feature = "int_log", since = "1.67.0")]
|
||||
#[rustc_const_stable(feature = "int_log", since = "1.67.0")]
|
||||
#[rustc_allow_const_fn_unstable(const_option)]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
pub const fn ilog(self, base: Self) -> u32 {
|
||||
assert!(base >= 2, "base of integer logarithm must be at least 2");
|
||||
self.checked_ilog(base).expect("argument of integer logarithm must be positive")
|
||||
if let Some(log) = self.checked_ilog(base) {
|
||||
log
|
||||
} else {
|
||||
int_log10::panic_for_nonpositive_argument()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the base 2 logarithm of the number, rounded down.
|
||||
|
@ -2354,13 +2357,16 @@ macro_rules! int_impl {
|
|||
/// ```
|
||||
#[stable(feature = "int_log", since = "1.67.0")]
|
||||
#[rustc_const_stable(feature = "int_log", since = "1.67.0")]
|
||||
#[rustc_allow_const_fn_unstable(const_option)]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
pub const fn ilog2(self) -> u32 {
|
||||
self.checked_ilog2().expect("argument of integer logarithm must be positive")
|
||||
if let Some(log) = self.checked_ilog2() {
|
||||
log
|
||||
} else {
|
||||
int_log10::panic_for_nonpositive_argument()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the base 10 logarithm of the number, rounded down.
|
||||
|
@ -2376,13 +2382,16 @@ macro_rules! int_impl {
|
|||
/// ```
|
||||
#[stable(feature = "int_log", since = "1.67.0")]
|
||||
#[rustc_const_stable(feature = "int_log", since = "1.67.0")]
|
||||
#[rustc_allow_const_fn_unstable(const_option)]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
pub const fn ilog10(self) -> u32 {
|
||||
self.checked_ilog10().expect("argument of integer logarithm must be positive")
|
||||
if let Some(log) = self.checked_ilog10() {
|
||||
log
|
||||
} else {
|
||||
int_log10::panic_for_nonpositive_argument()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the logarithm of the number with respect to an arbitrary base,
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
//! Constants for the 128-bit signed integer type.
|
||||
//!
|
||||
//! *[See also the `i128` primitive type][i128].*
|
||||
//! Redundant constants module for the [`i128` primitive type][i128].
|
||||
//!
|
||||
//! New code should use the associated constants directly on the primitive type.
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
//! Constants for the 16-bit signed integer type.
|
||||
//!
|
||||
//! *[See also the `i16` primitive type][i16].*
|
||||
//! Redundant constants module for the [`i16` primitive type][i16].
|
||||
//!
|
||||
//! New code should use the associated constants directly on the primitive type.
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
//! Constants for the 32-bit signed integer type.
|
||||
//!
|
||||
//! *[See also the `i32` primitive type][i32].*
|
||||
//! Redundant constants module for the [`i32` primitive type][i32].
|
||||
//!
|
||||
//! New code should use the associated constants directly on the primitive type.
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
//! Constants for the 64-bit signed integer type.
|
||||
//!
|
||||
//! *[See also the `i64` primitive type][i64].*
|
||||
//! Redundant constants module for the [`i64` primitive type][i64].
|
||||
//!
|
||||
//! New code should use the associated constants directly on the primitive type.
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
//! Constants for the 8-bit signed integer type.
|
||||
//!
|
||||
//! *[See also the `i8` primitive type][i8].*
|
||||
//! Redundant constants module for the [`i8` primitive type][i8].
|
||||
//!
|
||||
//! New code should use the associated constants directly on the primitive type.
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
//! Constants for the pointer-sized signed integer type.
|
||||
//!
|
||||
//! *[See also the `isize` primitive type][isize].*
|
||||
//! Redundant constants module for the [`isize` primitive type][isize].
|
||||
//!
|
||||
//! New code should use the associated constants directly on the primitive type.
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
//! Constants for the 128-bit unsigned integer type.
|
||||
//!
|
||||
//! *[See also the `u128` primitive type][u128].*
|
||||
//! Redundant constants module for the [`u128` primitive type][u128].
|
||||
//!
|
||||
//! New code should use the associated constants directly on the primitive type.
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
//! Constants for the 16-bit unsigned integer type.
|
||||
//!
|
||||
//! *[See also the `u16` primitive type][u16].*
|
||||
//! Redundant constants module for the [`i16` primitive type][i16].
|
||||
//!
|
||||
//! New code should use the associated constants directly on the primitive type.
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
//! Constants for the 32-bit unsigned integer type.
|
||||
//!
|
||||
//! *[See also the `u32` primitive type][u32].*
|
||||
//! Redundant constants module for the [`u32` primitive type][u32].
|
||||
//!
|
||||
//! New code should use the associated constants directly on the primitive type.
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
//! Constants for the 64-bit unsigned integer type.
|
||||
//!
|
||||
//! *[See also the `u64` primitive type][u64].*
|
||||
//! Redundant constants module for the [`u64` primitive type][u64].
|
||||
//!
|
||||
//! New code should use the associated constants directly on the primitive type.
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
//! Constants for the 8-bit unsigned integer type.
|
||||
//!
|
||||
//! *[See also the `u8` primitive type][u8].*
|
||||
//! Redundant constants module for the [`u8` primitive type][u8].
|
||||
//!
|
||||
//! New code should use the associated constants directly on the primitive type.
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
//! Constants for the pointer-sized unsigned integer type.
|
||||
//!
|
||||
//! *[See also the `usize` primitive type][usize].*
|
||||
//! Redundant constants module for the [`usize` primitive type][usize].
|
||||
//!
|
||||
//! New code should use the associated constants directly on the primitive type.
|
||||
|
||||
|
|
|
@ -705,14 +705,17 @@ macro_rules! uint_impl {
|
|||
/// ```
|
||||
#[stable(feature = "int_log", since = "1.67.0")]
|
||||
#[rustc_const_stable(feature = "int_log", since = "1.67.0")]
|
||||
#[rustc_allow_const_fn_unstable(const_option)]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
pub const fn ilog(self, base: Self) -> u32 {
|
||||
assert!(base >= 2, "base of integer logarithm must be at least 2");
|
||||
self.checked_ilog(base).expect("argument of integer logarithm must be positive")
|
||||
if let Some(log) = self.checked_ilog(base) {
|
||||
log
|
||||
} else {
|
||||
int_log10::panic_for_nonpositive_argument()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the base 2 logarithm of the number, rounded down.
|
||||
|
@ -728,13 +731,16 @@ macro_rules! uint_impl {
|
|||
/// ```
|
||||
#[stable(feature = "int_log", since = "1.67.0")]
|
||||
#[rustc_const_stable(feature = "int_log", since = "1.67.0")]
|
||||
#[rustc_allow_const_fn_unstable(const_option)]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
pub const fn ilog2(self) -> u32 {
|
||||
self.checked_ilog2().expect("argument of integer logarithm must be positive")
|
||||
if let Some(log) = self.checked_ilog2() {
|
||||
log
|
||||
} else {
|
||||
int_log10::panic_for_nonpositive_argument()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the base 10 logarithm of the number, rounded down.
|
||||
|
@ -750,13 +756,16 @@ macro_rules! uint_impl {
|
|||
/// ```
|
||||
#[stable(feature = "int_log", since = "1.67.0")]
|
||||
#[rustc_const_stable(feature = "int_log", since = "1.67.0")]
|
||||
#[rustc_allow_const_fn_unstable(const_option)]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
pub const fn ilog10(self) -> u32 {
|
||||
self.checked_ilog10().expect("argument of integer logarithm must be positive")
|
||||
if let Some(log) = self.checked_ilog10() {
|
||||
log
|
||||
} else {
|
||||
int_log10::panic_for_nonpositive_argument()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the logarithm of the number with respect to an arbitrary base,
|
||||
|
|
|
@ -72,11 +72,6 @@ pub fn unsupported_err() -> crate::io::Error {
|
|||
)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn floor(x: f64) -> f64 {
|
||||
unsafe { intrinsics::floorf64(x) }
|
||||
}
|
||||
|
||||
pub fn abort_internal() -> ! {
|
||||
unsafe {
|
||||
abi::abort();
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.14.1
|
||||
0.14.3
|
|
@ -1,121 +1,59 @@
|
|||
// run-pass
|
||||
#![allow(unused_must_use)]
|
||||
// ignore-emscripten FIXME(#45351) hits an LLVM assert
|
||||
|
||||
#![feature(repr_simd, platform_intrinsics, concat_idents, test)]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
extern crate test;
|
||||
|
||||
#[repr(simd)]
|
||||
#[derive(PartialEq, Debug)]
|
||||
struct i32x4(i32, i32, i32, i32);
|
||||
#[repr(simd)]
|
||||
#[derive(PartialEq, Debug)]
|
||||
struct i8x4(i8, i8, i8, i8);
|
||||
|
||||
#[repr(simd)]
|
||||
#[derive(PartialEq, Debug)]
|
||||
struct u32x4(u32, u32, u32, u32);
|
||||
#[repr(simd)]
|
||||
#[derive(PartialEq, Debug)]
|
||||
struct u8x4(u8, u8, u8, u8);
|
||||
|
||||
#[repr(simd)]
|
||||
#[derive(PartialEq, Debug)]
|
||||
struct f32x4(f32, f32, f32, f32);
|
||||
|
||||
#[repr(simd)]
|
||||
#[derive(PartialEq, Debug)]
|
||||
struct f64x4(f64, f64, f64, f64);
|
||||
|
||||
#![feature(repr_simd, platform_intrinsics)]
|
||||
|
||||
extern "platform-intrinsic" {
|
||||
fn simd_cast<T, U>(x: T) -> U;
|
||||
}
|
||||
|
||||
const A: i32 = -1234567;
|
||||
const B: i32 = 12345678;
|
||||
const C: i32 = -123456789;
|
||||
const D: i32 = 1234567890;
|
||||
use std::cmp::{max, min};
|
||||
|
||||
trait Foo {
|
||||
fn is_float() -> bool { false }
|
||||
fn in_range(x: i32) -> bool;
|
||||
}
|
||||
impl Foo for i32 {
|
||||
fn in_range(_: i32) -> bool { true }
|
||||
}
|
||||
impl Foo for i8 {
|
||||
fn in_range(x: i32) -> bool { -128 <= x && x < 128 }
|
||||
}
|
||||
impl Foo for u32 {
|
||||
fn in_range(x: i32) -> bool { 0 <= x }
|
||||
}
|
||||
impl Foo for u8 {
|
||||
fn in_range(x: i32) -> bool { 0 <= x && x < 128 }
|
||||
}
|
||||
impl Foo for f32 {
|
||||
fn is_float() -> bool { true }
|
||||
fn in_range(_: i32) -> bool { true }
|
||||
}
|
||||
impl Foo for f64 {
|
||||
fn is_float() -> bool { true }
|
||||
fn in_range(_: i32) -> bool { true }
|
||||
}
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(simd)]
|
||||
struct V<T>([T; 2]);
|
||||
|
||||
fn main() {
|
||||
macro_rules! test {
|
||||
($from: ident, $to: ident) => {{
|
||||
// force the casts to actually happen, or else LLVM/rustc
|
||||
// may fold them and get slightly different results.
|
||||
let (a, b, c, d) = test::black_box((A as $from, B as $from, C as $from, D as $from));
|
||||
// the SIMD vectors are all FOOx4, so we can concat_idents
|
||||
// so we don't have to pass in the extra args to the macro
|
||||
let mut from = simd_cast(concat_idents!($from, x4)(a, b, c, d));
|
||||
let mut to = concat_idents!($to, x4)(a as $to,
|
||||
b as $to,
|
||||
c as $to,
|
||||
d as $to);
|
||||
// assist type inference, it needs to know what `from` is
|
||||
// for the `if` statements.
|
||||
to == from;
|
||||
|
||||
// there are platform differences for some out of range
|
||||
// casts, so we just normalize such things: it's OK for
|
||||
// "invalid" calculations to result in nonsense answers.
|
||||
// (e.g., negative float to unsigned integer goes through a
|
||||
// library routine on the default i686 platforms, and the
|
||||
// implementation of that routine differs on e.g., Linux
|
||||
// vs. macOS, resulting in different answers.)
|
||||
if $from::is_float() {
|
||||
if !$to::in_range(A) { from.0 = 0 as $to; to.0 = 0 as $to; }
|
||||
if !$to::in_range(B) { from.1 = 0 as $to; to.1 = 0 as $to; }
|
||||
if !$to::in_range(C) { from.2 = 0 as $to; to.2 = 0 as $to; }
|
||||
if !$to::in_range(D) { from.3 = 0 as $to; to.3 = 0 as $to; }
|
||||
}
|
||||
|
||||
assert!(to == from,
|
||||
"{} -> {} ({:?} != {:?})", stringify!($from), stringify!($to),
|
||||
from, to);
|
||||
}}
|
||||
}
|
||||
macro_rules! tests {
|
||||
(: $($to: ident),*) => { () };
|
||||
// repeating the list twice is easier than writing a cartesian
|
||||
// product macro
|
||||
($from: ident $(, $from_: ident)*: $($to: ident),*) => {
|
||||
fn $from() { unsafe { $( test!($from, $to); )* } }
|
||||
tests!($($from_),*: $($to),*)
|
||||
};
|
||||
($($types: ident),*) => {{
|
||||
tests!($($types),* : $($types),*);
|
||||
$($types();)*
|
||||
}}
|
||||
unsafe {
|
||||
let u = V::<u32>([i16::MIN as u32, i16::MAX as u32]);
|
||||
let i: V<i16> = simd_cast(u);
|
||||
assert_eq!(i.0[0], u.0[0] as i16);
|
||||
assert_eq!(i.0[1], u.0[1] as i16);
|
||||
}
|
||||
|
||||
// test various combinations, including truncation,
|
||||
// signed/unsigned extension, and floating point casts.
|
||||
tests!(i32, i8, u32, u8, f32);
|
||||
tests!(i32, u32, f32, f64)
|
||||
unsafe {
|
||||
let f = V::<f32>([i16::MIN as f32, i16::MAX as f32]);
|
||||
let i: V<i16> = simd_cast(f);
|
||||
assert_eq!(i.0[0], f.0[0] as i16);
|
||||
assert_eq!(i.0[1], f.0[1] as i16);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let f = V::<f32>([u8::MIN as f32, u8::MAX as f32]);
|
||||
let u: V<u8> = simd_cast(f);
|
||||
assert_eq!(u.0[0], f.0[0] as u8);
|
||||
assert_eq!(u.0[1], f.0[1] as u8);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
// We would like to do isize::MIN..=isize::MAX, but those values are not representable in
|
||||
// an f64, so we clamp to the range of an i32 to prevent running into UB.
|
||||
let f = V::<f64>([
|
||||
max(isize::MIN, i32::MIN as isize) as f64,
|
||||
min(isize::MAX, i32::MAX as isize) as f64,
|
||||
]);
|
||||
let i: V<isize> = simd_cast(f);
|
||||
assert_eq!(i.0[0], f.0[0] as isize);
|
||||
assert_eq!(i.0[1], f.0[1] as isize);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let f = V::<f64>([
|
||||
max(usize::MIN, u32::MIN as usize) as f64,
|
||||
min(usize::MAX, u32::MAX as usize) as f64,
|
||||
]);
|
||||
let u: V<usize> = simd_cast(f);
|
||||
assert_eq!(u.0[0], f.0[0] as usize);
|
||||
assert_eq!(u.0[1], f.0[1] as usize);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,9 +24,9 @@ fn main() {
|
|||
|
||||
// reading from *const
|
||||
unsafe {
|
||||
let pointer = &x[0] as *const f32;
|
||||
let pointer = x.as_ptr();
|
||||
let pointers = x4(
|
||||
pointer.offset(0) as *const f32,
|
||||
pointer.offset(0),
|
||||
pointer.offset(2),
|
||||
pointer.offset(4),
|
||||
pointer.offset(6)
|
||||
|
@ -39,9 +39,9 @@ fn main() {
|
|||
|
||||
// reading from *mut
|
||||
unsafe {
|
||||
let pointer = &mut x[0] as *mut f32;
|
||||
let pointer = x.as_mut_ptr();
|
||||
let pointers = x4(
|
||||
pointer.offset(0) as *mut f32,
|
||||
pointer.offset(0),
|
||||
pointer.offset(2),
|
||||
pointer.offset(4),
|
||||
pointer.offset(6)
|
||||
|
@ -54,9 +54,9 @@ fn main() {
|
|||
|
||||
// writing to *mut
|
||||
unsafe {
|
||||
let pointer = &mut x[0] as *mut f32;
|
||||
let pointer = x.as_mut_ptr();
|
||||
let pointers = x4(
|
||||
pointer.offset(0) as *mut f32,
|
||||
pointer.offset(0),
|
||||
pointer.offset(2),
|
||||
pointer.offset(4),
|
||||
pointer.offset(6)
|
||||
|
@ -85,9 +85,9 @@ fn main() {
|
|||
|
||||
// reading from *const
|
||||
unsafe {
|
||||
let pointer = &y[0] as *const *const f32;
|
||||
let pointer = y.as_ptr();
|
||||
let pointers = x4(
|
||||
pointer.offset(0) as *const *const f32,
|
||||
pointer.offset(0),
|
||||
pointer.offset(2),
|
||||
pointer.offset(4),
|
||||
pointer.offset(6)
|
||||
|
@ -100,9 +100,9 @@ fn main() {
|
|||
|
||||
// reading from *mut
|
||||
unsafe {
|
||||
let pointer = &mut y[0] as *mut *const f32;
|
||||
let pointer = y.as_mut_ptr();
|
||||
let pointers = x4(
|
||||
pointer.offset(0) as *mut *const f32,
|
||||
pointer.offset(0),
|
||||
pointer.offset(2),
|
||||
pointer.offset(4),
|
||||
pointer.offset(6)
|
||||
|
@ -115,9 +115,9 @@ fn main() {
|
|||
|
||||
// writing to *mut
|
||||
unsafe {
|
||||
let pointer = &mut y[0] as *mut *const f32;
|
||||
let pointer = y.as_mut_ptr();
|
||||
let pointers = x4(
|
||||
pointer.offset(0) as *mut *const f32,
|
||||
pointer.offset(0),
|
||||
pointer.offset(2),
|
||||
pointer.offset(4),
|
||||
pointer.offset(6)
|
||||
|
|
|
@ -17,13 +17,14 @@ extern "platform-intrinsic" {
|
|||
fn main() {
|
||||
let x: [usize; 4] = [10, 11, 12, 13];
|
||||
let default = x4(0_usize, 1, 2, 3);
|
||||
let mask = x4(1_i32, 1, 1, 1);
|
||||
let all_set = u8::MAX as i8; // aka -1
|
||||
let mask = x4(all_set, all_set, all_set, all_set);
|
||||
let expected = x4(10_usize, 11, 12, 13);
|
||||
|
||||
unsafe {
|
||||
let pointer = &x[0] as *const usize;
|
||||
let pointer = x.as_ptr();
|
||||
let pointers = x4(
|
||||
pointer.offset(0) as *const usize,
|
||||
pointer.offset(0),
|
||||
pointer.offset(1),
|
||||
pointer.offset(2),
|
||||
pointer.offset(3)
|
||||
|
@ -38,9 +39,9 @@ fn main() {
|
|||
let expected = x4(10_isize, 11, 12, 13);
|
||||
|
||||
unsafe {
|
||||
let pointer = &x[0] as *const isize;
|
||||
let pointer = x.as_ptr();
|
||||
let pointers = x4(
|
||||
pointer.offset(0) as *const isize,
|
||||
pointer.offset(0),
|
||||
pointer.offset(1),
|
||||
pointer.offset(2),
|
||||
pointer.offset(3)
|
||||
|
|
Loading…
Add table
Reference in a new issue