Auto merge of #70722 - Centril:rollup-ar4gn1x, r=Centril

Rollup of 7 pull requests

Successful merges:

 - #70487 (Stabilize float::to_int_unchecked)
 - #70595 (Remove unused discriminant reads from MIR bodies)
 - #70691 (Improve docs in `AllocRef`)
 - #70694 (Use Self over specific type in return position)
 - #70700 (Expand on platform details of `include_xxx` macros)
 - #70708 (Fix typo in u8::to_ascii_uppercase and u8::to_ascii_lowercase)
 - #70716 (Unerase regions in infer_placeholder_type)

Failed merges:

r? @ghost
This commit is contained in:
bors 2020-04-02 22:32:52 +00:00
commit c520802785
17 changed files with 150 additions and 65 deletions

View File

@ -33,9 +33,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[unstable(feature = "allocator_api", issue = "32838")]
pub enum AllocInit {
/// The contents of the new memory are undefined.
///
/// Reading uninitialized memory is Undefined Behavior; it must be initialized before use.
/// The contents of the new memory are uninitialized.
Uninitialized,
/// The new memory is guaranteed to be zeroed.
Zeroed,
@ -196,7 +194,11 @@ pub unsafe trait AllocRef {
///
/// # Safety
///
/// `memory` must be a memory block returned by this allocator.
/// * `ptr` must be [*currently allocated*] via this allocator, and
/// * `layout` must [*fit*] the `ptr`.
///
/// [*currently allocated*]: #currently-allocated-memory
/// [*fit*]: #memory-fitting
unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout);
/// Attempts to extend the memory block.
@ -237,7 +239,7 @@ pub unsafe trait AllocRef {
// * `new_size must be strictly greater than `memory.size` or both are zero
/// * `new_size` must be greater than or equal to `layout.size()`
/// * `new_size`, when rounded up to the nearest multiple of `layout.align()`, must not overflow
/// (i.e., the rounded value must be less than `usize::MAX`).
/// (i.e., the rounded value must be less than or equal to `usize::MAX`).
///
/// [*currently allocated*]: #currently-allocated-memory
/// [*fit*]: #memory-fitting

View File

@ -13,9 +13,9 @@ pub trait Sealed {}
/// Typically doesnt need to be used directly.
#[unstable(feature = "convert_float_to_int", issue = "67057")]
pub trait FloatToInt<Int>: private::Sealed + Sized {
#[unstable(feature = "float_approx_unchecked_to", issue = "67058")]
#[unstable(feature = "convert_float_to_int", issue = "67057")]
#[doc(hidden)]
unsafe fn approx_unchecked(self) -> Int;
unsafe fn to_int_unchecked(self) -> Int;
}
macro_rules! impl_float_to_int {
@ -27,8 +27,15 @@ impl private::Sealed for $Float {}
impl FloatToInt<$Int> for $Float {
#[doc(hidden)]
#[inline]
unsafe fn approx_unchecked(self) -> $Int {
crate::intrinsics::float_to_int_approx_unchecked(self)
unsafe fn to_int_unchecked(self) -> $Int {
#[cfg(bootstrap)]
{
crate::intrinsics::float_to_int_approx_unchecked(self)
}
#[cfg(not(bootstrap))]
{
crate::intrinsics::float_to_int_unchecked(self)
}
}
}
)+

View File

@ -1582,8 +1582,16 @@
/// Convert with LLVMs fptoui/fptosi, which may return undef for values out of range
/// (<https://github.com/rust-lang/rust/issues/10184>)
/// This is under stabilization at <https://github.com/rust-lang/rust/issues/67058>
#[cfg(bootstrap)]
pub fn float_to_int_approx_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
/// Convert with LLVMs fptoui/fptosi, which may return undef for values out of range
/// (<https://github.com/rust-lang/rust/issues/10184>)
///
/// Stabilized as `f32::to_int_unchecked` and `f64::to_int_unchecked`.
#[cfg(not(bootstrap))]
pub fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
/// Returns the number of bits set in an integer type `T`
///
/// The stabilized versions of this intrinsic are available on the integer

View File

@ -1070,8 +1070,10 @@ macro_rules! stringify {
/// Includes a utf8-encoded file as a string.
///
/// The file is located relative to the current file. (similarly to how
/// modules are found)
/// The file is located relative to the current file (similarly to how
/// modules are found). The provided path is interpreted in a platform-specific
/// way at compile time. So, for instance, an invocation with a Windows path
/// containing backslashes `\` would not compile correctly on Unix.
///
/// This macro will yield an expression of type `&'static str` which is the
/// contents of the file.
@ -1108,8 +1110,10 @@ macro_rules! include_str {
/// Includes a file as a reference to a byte array.
///
/// The file is located relative to the current file. (similarly to how
/// modules are found)
/// The file is located relative to the current file (similarly to how
/// modules are found). The provided path is interpreted in a platform-specific
/// way at compile time. So, for instance, an invocation with a Windows path
/// containing backslashes `\` would not compile correctly on Unix.
///
/// This macro will yield an expression of type `&'static [u8; N]` which is
/// the contents of the file.
@ -1202,7 +1206,9 @@ macro_rules! cfg {
/// Parses a file as an expression or an item according to the context.
///
/// The file is located relative to the current file (similarly to how
/// modules are found).
/// modules are found). The provided path is interpreted in a platform-specific
/// way at compile time. So, for instance, an invocation with a Windows path
/// containing backslashes `\` would not compile correctly on Unix.
///
/// Using this macro is often a bad idea, because if the file is
/// parsed as an expression, it is going to be placed in the

View File

@ -464,14 +464,12 @@ pub fn min(self, other: f32) -> f32 {
/// assuming that the value is finite and fits in that type.
///
/// ```
/// #![feature(float_approx_unchecked_to)]
///
/// let value = 4.6_f32;
/// let rounded = unsafe { value.approx_unchecked_to::<u16>() };
/// let rounded = unsafe { value.to_int_unchecked::<u16>() };
/// assert_eq!(rounded, 4);
///
/// let value = -128.9_f32;
/// let rounded = unsafe { value.approx_unchecked_to::<i8>() };
/// let rounded = unsafe { value.to_int_unchecked::<i8>() };
/// assert_eq!(rounded, std::i8::MIN);
/// ```
///
@ -482,13 +480,13 @@ pub fn min(self, other: f32) -> f32 {
/// * Not be `NaN`
/// * Not be infinite
/// * Be representable in the return type `Int`, after truncating off its fractional part
#[unstable(feature = "float_approx_unchecked_to", issue = "67058")]
#[stable(feature = "float_approx_unchecked_to", since = "1.44.0")]
#[inline]
pub unsafe fn approx_unchecked_to<Int>(self) -> Int
pub unsafe fn to_int_unchecked<Int>(self) -> Int
where
Self: FloatToInt<Int>,
{
FloatToInt::<Int>::approx_unchecked(self)
FloatToInt::<Int>::to_int_unchecked(self)
}
/// Raw transmutation to `u32`.

View File

@ -478,14 +478,12 @@ pub fn min(self, other: f64) -> f64 {
/// assuming that the value is finite and fits in that type.
///
/// ```
/// #![feature(float_approx_unchecked_to)]
///
/// let value = 4.6_f32;
/// let rounded = unsafe { value.approx_unchecked_to::<u16>() };
/// let rounded = unsafe { value.to_int_unchecked::<u16>() };
/// assert_eq!(rounded, 4);
///
/// let value = -128.9_f32;
/// let rounded = unsafe { value.approx_unchecked_to::<i8>() };
/// let rounded = unsafe { value.to_int_unchecked::<i8>() };
/// assert_eq!(rounded, std::i8::MIN);
/// ```
///
@ -496,13 +494,13 @@ pub fn min(self, other: f64) -> f64 {
/// * Not be `NaN`
/// * Not be infinite
/// * Be representable in the return type `Int`, after truncating off its fractional part
#[unstable(feature = "float_approx_unchecked_to", issue = "67058")]
#[stable(feature = "float_approx_unchecked_to", since = "1.44.0")]
#[inline]
pub unsafe fn approx_unchecked_to<Int>(self) -> Int
pub unsafe fn to_int_unchecked<Int>(self) -> Int
where
Self: FloatToInt<Int>,
{
FloatToInt::<Int>::approx_unchecked(self)
FloatToInt::<Int>::to_int_unchecked(self)
}
/// Raw transmutation to `u64`.

View File

@ -4376,7 +4376,7 @@ pub const fn is_ascii(&self) -> bool {
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[inline]
pub fn to_ascii_uppercase(&self) -> u8 {
// Unset the fith bit if this is a lowercase letter
// Unset the fifth bit if this is a lowercase letter
*self & !((self.is_ascii_lowercase() as u8) << 5)
}
@ -4399,7 +4399,7 @@ pub fn to_ascii_uppercase(&self) -> u8 {
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[inline]
pub fn to_ascii_lowercase(&self) -> u8 {
// Set the fith bit if this is an uppercase letter
// Set the fifth bit if this is an uppercase letter
*self | ((self.is_ascii_uppercase() as u8) << 5)
}

View File

@ -543,13 +543,13 @@ fn codegen_intrinsic_call(
}
}
"float_to_int_approx_unchecked" => {
"float_to_int_unchecked" => {
if float_type_width(arg_tys[0]).is_none() {
span_invalid_monomorphization_error(
tcx.sess,
span,
&format!(
"invalid monomorphization of `float_to_int_approx_unchecked` \
"invalid monomorphization of `float_to_int_unchecked` \
intrinsic: expected basic float type, \
found `{}`",
arg_tys[0]
@ -570,7 +570,7 @@ fn codegen_intrinsic_call(
tcx.sess,
span,
&format!(
"invalid monomorphization of `float_to_int_approx_unchecked` \
"invalid monomorphization of `float_to_int_unchecked` \
intrinsic: expected basic integer type, \
found `{}`",
ret_ty

View File

@ -368,18 +368,22 @@ fn visit_local(&mut self, local: &Local, ctx: PlaceContext, location: Location)
if location.statement_index != block.statements.len() {
let stmt = &block.statements[location.statement_index];
if let StatementKind::Assign(box (p, Rvalue::Use(Operand::Constant(c)))) =
&stmt.kind
{
match c.literal.val {
// Keep assignments from unevaluated constants around, since the evaluation
// may report errors, even if the use of the constant is dead code.
ty::ConstKind::Unevaluated(..) => {}
_ => {
if !p.is_indirect() {
trace!("skipping store of const value {:?} to {:?}", c, p);
return;
if let StatementKind::Assign(box (dest, rvalue)) = &stmt.kind {
if !dest.is_indirect() && dest.local == *local {
if let Rvalue::Use(Operand::Constant(c)) = rvalue {
match c.literal.val {
// Keep assignments from unevaluated constants around, since the
// evaluation may report errors, even if the use of the constant
// is dead code.
ty::ConstKind::Unevaluated(..) => {}
_ => {
trace!("skipping store of const value {:?} to {:?}", c, dest);
return;
}
}
} else if let Rvalue::Discriminant(d) = rvalue {
trace!("skipping store of discriminant value {:?} to {:?}", d, dest);
return;
}
}
}

View File

@ -275,7 +275,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
"fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" => {
(1, vec![param(0), param(0)], param(0))
}
"float_to_int_approx_unchecked" => (2, vec![param(0)], param(1)),
"float_to_int_unchecked" => (2, vec![param(0)], param(1)),
"assume" => (0, vec![tcx.types.bool], tcx.mk_unit()),
"likely" => (0, vec![tcx.types.bool], tcx.types.bool),

View File

@ -655,7 +655,11 @@ fn infer_placeholder_type(
}
}
ty
// Typeck doesn't expect erased regions to be returned from `type_of`.
tcx.fold_regions(&ty, &mut false, |r, _| match r {
ty::ReErased => tcx.lifetimes.re_static,
_ => r,
})
}
fn report_assoc_ty_on_inherent_impl(tcx: TyCtxt<'_>, span: Span) {

View File

@ -734,7 +734,7 @@ impl OpenOptions {
/// let file = options.read(true).open("foo.txt");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new() -> OpenOptions {
pub fn new() -> Self {
OpenOptions(fs_imp::OpenOptions::new())
}
@ -751,7 +751,7 @@ pub fn new() -> OpenOptions {
/// let file = OpenOptions::new().read(true).open("foo.txt");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn read(&mut self, read: bool) -> &mut OpenOptions {
pub fn read(&mut self, read: bool) -> &mut Self {
self.0.read(read);
self
}
@ -772,7 +772,7 @@ pub fn read(&mut self, read: bool) -> &mut OpenOptions {
/// let file = OpenOptions::new().write(true).open("foo.txt");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn write(&mut self, write: bool) -> &mut OpenOptions {
pub fn write(&mut self, write: bool) -> &mut Self {
self.0.write(write);
self
}
@ -819,7 +819,7 @@ pub fn write(&mut self, write: bool) -> &mut OpenOptions {
/// let file = OpenOptions::new().append(true).open("foo.txt");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn append(&mut self, append: bool) -> &mut OpenOptions {
pub fn append(&mut self, append: bool) -> &mut Self {
self.0.append(append);
self
}
@ -839,7 +839,7 @@ pub fn append(&mut self, append: bool) -> &mut OpenOptions {
/// let file = OpenOptions::new().write(true).truncate(true).open("foo.txt");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn truncate(&mut self, truncate: bool) -> &mut OpenOptions {
pub fn truncate(&mut self, truncate: bool) -> &mut Self {
self.0.truncate(truncate);
self
}
@ -860,7 +860,7 @@ pub fn truncate(&mut self, truncate: bool) -> &mut OpenOptions {
/// let file = OpenOptions::new().write(true).create(true).open("foo.txt");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn create(&mut self, create: bool) -> &mut OpenOptions {
pub fn create(&mut self, create: bool) -> &mut Self {
self.0.create(create);
self
}
@ -893,7 +893,7 @@ pub fn create(&mut self, create: bool) -> &mut OpenOptions {
/// .open("foo.txt");
/// ```
#[stable(feature = "expand_open_options2", since = "1.9.0")]
pub fn create_new(&mut self, create_new: bool) -> &mut OpenOptions {
pub fn create_new(&mut self, create_new: bool) -> &mut Self {
self.0.create_new(create_new);
self
}

View File

@ -0,0 +1,12 @@
fn map(x: Option<Box<()>>) -> Option<Box<()>> {
match x {
None => None,
Some(x) => Some(x),
}
}
fn main() {
map(None);
}
// EMIT_MIR rustc.map.SimplifyLocals.diff

View File

@ -0,0 +1,37 @@
- // MIR for `map` before SimplifyLocals
+ // MIR for `map` after SimplifyLocals
fn map(_1: std::option::Option<std::boxed::Box<()>>) -> std::option::Option<std::boxed::Box<()>> {
debug x => _1; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:8: 1:9
let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:31: 1:46
let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15
- let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:25: 4:26
- let mut _5: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2
- let mut _6: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2
scope 1 {
debug x => _3; // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15
}
bb0: {
_2 = discriminant(_1); // bb0[0]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
switchInt(move _2) -> [0isize: bb2, otherwise: bb1]; // bb0[1]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
}
bb1: {
_0 = move _1; // bb1[0]: scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:20: 4:27
goto -> bb3; // bb1[1]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:2:5: 5:6
}
bb2: {
discriminant(_0) = 0; // bb2[0]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:17: 3:21
goto -> bb3; // bb2[1]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:2:5: 5:6
}
bb3: {
- _5 = discriminant(_1); // bb3[0]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2
- return; // bb3[1]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:2: 6:2
+ return; // bb3[0]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:2: 6:2
}
}

View File

@ -183,25 +183,24 @@ fn main() {
// fn try_identity(_1: std::result::Result<u32, i32>) -> std::result::Result<u32, i32> {
// debug x => _1;
// let mut _0: std::result::Result<u32, i32>;
// let mut _2: isize;
// let _3: i32;
// let _4: u32;
// let _2: i32;
// let _3: u32;
// scope 1 {
// debug y => _4;
// debug y => _3;
// }
// scope 2 {
// debug err => _3;
// debug err => _2;
// scope 3 {
// scope 7 {
// debug t => _3;
// debug t => _2;
// }
// scope 8 {
// debug v => _3;
// debug v => _2;
// }
// }
// }
// scope 4 {
// debug val => _4;
// debug val => _3;
// scope 5 {
// }
// }
@ -209,7 +208,6 @@ fn main() {
// debug self => _1;
// }
// bb0: {
// _2 = discriminant(_1);
// _0 = move _1;
// return;
// }

View File

@ -35,6 +35,11 @@ fn main() {}
//~| HELP provide a type for the item
//~| SUGGESTION C: i32
const D = &&42;
//~^ ERROR missing type for `const` item
//~| HELP provide a type for the item
//~| SUGGESTION D: &&i32
static S = Vec::<String>::new();
//~^ ERROR missing type for `static` item
//~| HELP provide a type for the item

View File

@ -4,14 +4,20 @@ error: missing type for `const` item
LL | const C = 42;
| ^ help: provide a type for the item: `C: i32`
error: missing type for `const` item
--> $DIR/const-no-type.rs:38:7
|
LL | const D = &&42;
| ^ help: provide a type for the item: `D: &&i32`
error: missing type for `static` item
--> $DIR/const-no-type.rs:38:8
--> $DIR/const-no-type.rs:43:8
|
LL | static S = Vec::<String>::new();
| ^ help: provide a type for the item: `S: std::vec::Vec<std::string::String>`
error: missing type for `static mut` item
--> $DIR/const-no-type.rs:43:12
--> $DIR/const-no-type.rs:48:12
|
LL | static mut SM = "abc";
| ^^ help: provide a type for the item: `SM: &str`
@ -34,5 +40,5 @@ error: missing type for `static mut` item
LL | static mut SM2 = "abc";
| ^^^ help: provide a type for the item: `SM2: <type>`
error: aborting due to 6 previous errors
error: aborting due to 7 previous errors