Skip to content

Commit 636ee51

Browse files
committed
Merge from rust-lang/rust
2 parents f7a8a94 + 64f77fe commit 636ee51

File tree

9 files changed

+91
-19
lines changed

9 files changed

+91
-19
lines changed

src/intrinsics/mod.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -145,60 +145,60 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
145145
this.write_scalar(Scalar::from_bool(branch), dest)?;
146146
}
147147

148-
"floorf16" | "ceilf16" | "truncf16" | "roundf16" | "rintf16" => {
148+
"floorf16" | "ceilf16" | "truncf16" | "roundf16" | "round_ties_even_f16" => {
149149
let [f] = check_arg_count(args)?;
150150
let f = this.read_scalar(f)?.to_f16()?;
151151
let mode = match intrinsic_name {
152152
"floorf16" => Round::TowardNegative,
153153
"ceilf16" => Round::TowardPositive,
154154
"truncf16" => Round::TowardZero,
155155
"roundf16" => Round::NearestTiesToAway,
156-
"rintf16" => Round::NearestTiesToEven,
156+
"round_ties_even_f16" => Round::NearestTiesToEven,
157157
_ => bug!(),
158158
};
159159
let res = f.round_to_integral(mode).value;
160160
let res = this.adjust_nan(res, &[f]);
161161
this.write_scalar(res, dest)?;
162162
}
163-
"floorf32" | "ceilf32" | "truncf32" | "roundf32" | "rintf32" => {
163+
"floorf32" | "ceilf32" | "truncf32" | "roundf32" | "round_ties_even_f32" => {
164164
let [f] = check_arg_count(args)?;
165165
let f = this.read_scalar(f)?.to_f32()?;
166166
let mode = match intrinsic_name {
167167
"floorf32" => Round::TowardNegative,
168168
"ceilf32" => Round::TowardPositive,
169169
"truncf32" => Round::TowardZero,
170170
"roundf32" => Round::NearestTiesToAway,
171-
"rintf32" => Round::NearestTiesToEven,
171+
"round_ties_even_f32" => Round::NearestTiesToEven,
172172
_ => bug!(),
173173
};
174174
let res = f.round_to_integral(mode).value;
175175
let res = this.adjust_nan(res, &[f]);
176176
this.write_scalar(res, dest)?;
177177
}
178-
"floorf64" | "ceilf64" | "truncf64" | "roundf64" | "rintf64" => {
178+
"floorf64" | "ceilf64" | "truncf64" | "roundf64" | "round_ties_even_f64" => {
179179
let [f] = check_arg_count(args)?;
180180
let f = this.read_scalar(f)?.to_f64()?;
181181
let mode = match intrinsic_name {
182182
"floorf64" => Round::TowardNegative,
183183
"ceilf64" => Round::TowardPositive,
184184
"truncf64" => Round::TowardZero,
185185
"roundf64" => Round::NearestTiesToAway,
186-
"rintf64" => Round::NearestTiesToEven,
186+
"round_ties_even_f64" => Round::NearestTiesToEven,
187187
_ => bug!(),
188188
};
189189
let res = f.round_to_integral(mode).value;
190190
let res = this.adjust_nan(res, &[f]);
191191
this.write_scalar(res, dest)?;
192192
}
193-
"floorf128" | "ceilf128" | "truncf128" | "roundf128" | "rintf128" => {
193+
"floorf128" | "ceilf128" | "truncf128" | "roundf128" | "round_ties_even_f128" => {
194194
let [f] = check_arg_count(args)?;
195195
let f = this.read_scalar(f)?.to_f128()?;
196196
let mode = match intrinsic_name {
197197
"floorf128" => Round::TowardNegative,
198198
"ceilf128" => Round::TowardPositive,
199199
"truncf128" => Round::TowardZero,
200200
"roundf128" => Round::NearestTiesToAway,
201-
"rintf128" => Round::NearestTiesToEven,
201+
"round_ties_even_f128" => Round::NearestTiesToEven,
202202
_ => bug!(),
203203
};
204204
let res = f.round_to_integral(mode).value;

src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#![cfg_attr(bootstrap, feature(trait_upcasting))]
21
#![feature(rustc_private)]
32
#![feature(cell_update)]
43
#![feature(float_gamma)]
@@ -16,7 +15,6 @@
1615
#![feature(unqualified_local_imports)]
1716
#![feature(derive_coerce_pointee)]
1817
#![feature(arbitrary_self_types)]
19-
#![feature(unsigned_is_multiple_of)]
2018
#![feature(extract_if)]
2119
// Configure clippy and other lints
2220
#![allow(
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
//@normalize-stderr-test: "\d+ < \d+" -> "$$ADDR < $$ADDR"
2-
#![feature(ptr_sub_ptr)]
3-
42
fn main() {
53
let arr = [0u8; 8];
64
let ptr1 = arr.as_ptr();
75
let ptr2 = ptr1.wrapping_add(4);
8-
let _val = unsafe { ptr1.sub_ptr(ptr2) }; //~ERROR: first pointer has smaller address than second
6+
let _val = unsafe { ptr1.offset_from_unsigned(ptr2) }; //~ERROR: first pointer has smaller address than second
97
}

tests/fail/intrinsics/ptr_offset_from_unsigned_neg.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: Undefined Behavior: `ptr_offset_from_unsigned` called when first pointer has smaller address than second: $ADDR < $ADDR
22
--> tests/fail/intrinsics/ptr_offset_from_unsigned_neg.rs:LL:CC
33
|
4-
LL | let _val = unsafe { ptr1.sub_ptr(ptr2) };
5-
| ^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer has smaller address than second: $ADDR < $ADDR
4+
LL | let _val = unsafe { ptr1.offset_from_unsigned(ptr2) };
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer has smaller address than second: $ADDR < $ADDR
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information

tests/fail/ptr_swap_nonoverlapping.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11

22
thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
33
unsafe precondition(s) violated: ptr::swap_nonoverlapping requires that both pointer arguments are aligned and non-null and the specified memory ranges do not overlap
4+
5+
This indicates a bug in the program. This Undefined Behavior check is optional, and cannot be relied on for safety.
46
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
57
note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
68
thread caused non-unwinding panic. aborting.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Test that transmuting from `&dyn Trait<fn(&'static ())>` to `&dyn Trait<for<'a> fn(&'a ())>` is UB.
2+
//
3+
// The vtable of `() as Trait<fn(&'static ())>` and `() as Trait<for<'a> fn(&'a ())>` can have
4+
// different entries and, because in the former the entry for `foo` is vacant, this test will
5+
// segfault at runtime.
6+
7+
trait Trait<U> {
8+
fn foo(&self)
9+
where
10+
U: HigherRanked,
11+
{
12+
}
13+
}
14+
impl<T, U> Trait<U> for T {}
15+
16+
trait HigherRanked {}
17+
impl HigherRanked for for<'a> fn(&'a ()) {}
18+
19+
// 2nd candidate is required so that selecting `(): Trait<fn(&'static ())>` will
20+
// evaluate the candidates and fail the leak check instead of returning the
21+
// only applicable candidate.
22+
trait Unsatisfied {}
23+
impl<T: Unsatisfied> HigherRanked for T {}
24+
25+
fn main() {
26+
let x: &dyn Trait<fn(&'static ())> = &();
27+
let y: &dyn Trait<for<'a> fn(&'a ())> = unsafe { std::mem::transmute(x) };
28+
//~^ ERROR: wrong trait in wide pointer vtable
29+
y.foo();
30+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: Undefined Behavior: constructing invalid value: wrong trait in wide pointer vtable: expected `Trait<for<'a> fn(&'a ())>`, but encountered `Trait<fn(&())>`
2+
--> tests/fail/validity/dyn-transmute-inner-binder.rs:LL:CC
3+
|
4+
LL | let y: &dyn Trait<for<'a> fn(&'a ())> = unsafe { std::mem::transmute(x) };
5+
| ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: wrong trait in wide pointer vtable: expected `Trait<for<'a> fn(&'a ())>`, but encountered `Trait<fn(&())>`
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= note: BACKTRACE:
10+
= note: inside `main` at tests/fail/validity/dyn-transmute-inner-binder.rs:LL:CC
11+
12+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
13+
14+
error: aborting due to 1 previous error
15+

tests/pass/dyn-upcast.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ fn main() {
99
drop_principal();
1010
modulo_binder();
1111
modulo_assoc();
12+
bidirectional_subtyping();
1213
}
1314

1415
fn vtable_nop_cast() {
@@ -531,3 +532,32 @@ fn modulo_assoc() {
531532

532533
(&() as &dyn Trait as &dyn Middle<()>).say_hello(&0);
533534
}
535+
536+
fn bidirectional_subtyping() {
537+
// Test that transmuting between subtypes of dyn traits is fine, even in the
538+
// "wrong direction", i.e. going from a lower-ranked to a higher-ranked dyn trait.
539+
// Note that compared to the `dyn-transmute-inner-binder` test, the `for` is on the
540+
// *outside* here!
541+
542+
trait Trait<U: ?Sized> {}
543+
impl<T, U: ?Sized> Trait<U> for T {}
544+
545+
struct Wrapper<T: ?Sized>(T);
546+
547+
let x: &dyn Trait<fn(&'static ())> = &();
548+
let _y: &dyn for<'a> Trait<fn(&'a ())> = unsafe { std::mem::transmute(x) };
549+
550+
let x: &dyn for<'a> Trait<fn(&'a ())> = &();
551+
let _y: &dyn Trait<fn(&'static ())> = unsafe { std::mem::transmute(x) };
552+
553+
let x: &dyn Trait<dyn Trait<fn(&'static ())>> = &();
554+
let _y: &dyn for<'a> Trait<dyn Trait<fn(&'a ())>> = unsafe { std::mem::transmute(x) };
555+
556+
let x: &dyn for<'a> Trait<dyn Trait<fn(&'a ())>> = &();
557+
let _y: &dyn Trait<dyn Trait<fn(&'static ())>> = unsafe { std::mem::transmute(x) };
558+
559+
// This lowers to a ptr-to-ptr cast (which behaves like a transmute)
560+
// and not an unsizing coercion:
561+
let x: *const dyn for<'a> Trait<&'a ()> = &();
562+
let _y: *const Wrapper<dyn Trait<&'static ()>> = x as _;
563+
}

tests/pass/ptr_offset.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
//@compile-flags: -Zmiri-permissive-provenance
2-
#![feature(ptr_sub_ptr)]
32
use std::{mem, ptr};
43

54
fn main() {
@@ -22,7 +21,7 @@ fn smoke() {
2221
let _val = ptr.wrapping_sub(0);
2322
let _val = unsafe { ptr.sub(0) };
2423
let _val = unsafe { ptr.offset_from(ptr) };
25-
let _val = unsafe { ptr.sub_ptr(ptr) };
24+
let _val = unsafe { ptr.offset_from_unsigned(ptr) };
2625
}
2726

2827
fn test_offset_from() {
@@ -33,14 +32,14 @@ fn test_offset_from() {
3332
let y = x.offset(12);
3433

3534
assert_eq!(y.offset_from(x), 12);
36-
assert_eq!(y.sub_ptr(x), 12);
35+
assert_eq!(y.offset_from_unsigned(x), 12);
3736
assert_eq!(x.offset_from(y), -12);
3837
assert_eq!((y as *const u32).offset_from(x as *const u32), 12 / 4);
3938
assert_eq!((x as *const u32).offset_from(y as *const u32), -12 / 4);
4039

4140
let x = (((x as usize) * 2) / 2) as *const u8;
4241
assert_eq!(y.offset_from(x), 12);
43-
assert_eq!(y.sub_ptr(x), 12);
42+
assert_eq!(y.offset_from_unsigned(x), 12);
4443
assert_eq!(x.offset_from(y), -12);
4544
}
4645
}

0 commit comments

Comments
 (0)