Skip to content

Rollup of 7 pull requests #59692

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 21 commits into from
Closed
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f48a5dc
Document std::fs::File close behavior ignoring errors
czipperz Mar 27, 2019
d8a6b63
update stdsimd
RalfJung Mar 30, 2019
25e4447
renamed `inner_deref` feature's `deref*()` methods `as_deref*()` as p…
Xandkeeper Apr 1, 2019
b6ebe1b
Document using `sync_all`
czipperz Apr 2, 2019
e1fb2b7
added `deref_mut_*` versions of `inner_deref` methods as per discussi…
Xandkeeper Apr 1, 2019
e71e71b
fixed breaking changes
Xandkeeper Apr 2, 2019
76e82d6
Link to sync_all
czipperz Apr 3, 2019
5e3b1fc
update miri
RalfJung Mar 30, 2019
087999e
try to fix rand feature flags
RalfJung Mar 31, 2019
c75a5a2
update miri
RalfJung Apr 3, 2019
c2e0d7f
Never return uninhabited values at all
cuviper Apr 3, 2019
a969d40
File: Add documentation about dropping to sync_all
czipperz Apr 4, 2019
4c9c2cf
Add description for -Os and -Oz in rustc.1
tesuji Apr 4, 2019
42d652e
Disable stack probing for gnux32.
crlf0710 Apr 4, 2019
bfb7f34
Rollup merge of #59470 - czipperz:document-fs-file-close, r=dtolnay
Centril Apr 4, 2019
1eec471
Rollup merge of #59555 - RalfJung:miri, r=oli-obk
Centril Apr 4, 2019
5fb8949
Rollup merge of #59556 - RalfJung:stdsimd, r=gnzlbg
Centril Apr 4, 2019
06aa86a
Rollup merge of #59628 - U007D:master, r=Kimundi
Centril Apr 4, 2019
4380fde
Rollup merge of #59639 - cuviper:ignore-uninhabited, r=eddyb
Centril Apr 4, 2019
1f65027
Rollup merge of #59685 - lzutao:patch-1, r=GuillaumeGomez
Centril Apr 4, 2019
03a6ae6
Rollup merge of #59686 - crlf0710:disable_gnux32_stackprobe, r=luqmana
Centril Apr 4, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 1 addition & 23 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -2054,18 +2054,6 @@ dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "rand"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "rand"
version = "0.6.1"
@@ -2093,14 +2081,6 @@ dependencies = [
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "rand_core"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "rand_core"
version = "0.3.0"
@@ -2560,7 +2540,7 @@ version = "1.0.0"
dependencies = [
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -4206,10 +4186,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
"checksum racer 2.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "37c88638777cc178684cf648ca0e1dad56646ce105b8593dfe665c436300adc3"
"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
"checksum rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9d223d52ae411a33cf7e54ec6034ec165df296ccd23533d671a28252b6f66a"
"checksum rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "771b009e3a508cb67e8823dda454aaa5368c7bc1c16829fb77d3e980440dd34a"
"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372"
"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db"
"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
2 changes: 1 addition & 1 deletion src/doc/man/rustc.1
Original file line number Diff line number Diff line change
@@ -261,7 +261,7 @@ full debug info with variable and type information.
.RE
.TP
\fBopt\-level\fR=\fIVAL\fR
Optimize with possible levels 0\[en]3
Optimize with possible levels 0\[en]3, s (optimize for size), or z (for minimal size)

.SH ENVIRONMENT

21 changes: 16 additions & 5 deletions src/libcore/option.rs
Original file line number Diff line number Diff line change
@@ -136,7 +136,7 @@
#![stable(feature = "rust1", since = "1.0.0")]

use iter::{FromIterator, FusedIterator, TrustedLen};
use {hint, mem, ops::{self, Deref}};
use {hint, mem, ops::{self, Deref, DerefMut}};
use pin::Pin;

// Note that this is not a lang item per se, but it has a hidden dependency on
@@ -991,15 +991,26 @@ impl<T: Default> Option<T> {

#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
impl<T: Deref> Option<T> {
/// Converts from `&Option<T>` to `Option<&T::Target>`.
/// Converts from `Option<T>` (or `&Option<T>`) to `Option<&T::Target>`.
///
/// Leaves the original Option in-place, creating a new one with a reference
/// to the original one, additionally coercing the contents via `Deref`.
pub fn deref(&self) -> Option<&T::Target> {
/// Leaves the original `Option` in-place, creating a new one containing a reference to the
/// inner type's `Deref::Target` type.
pub fn as_deref(&self) -> Option<&T::Target> {
self.as_ref().map(|t| t.deref())
}
}

#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
impl<T: DerefMut> Option<T> {
/// Converts from `Option<T>` (or `&mut Option<T>`) to `Option<&mut T::Target>`.
///
/// Leaves the original `Option` in-place, creating a new one containing a mutable reference to
/// the inner type's `Deref::Target` type.
pub fn as_deref_mut(&mut self) -> Option<&mut T::Target> {
self.as_mut().map(|t| t.deref_mut())
}
}

impl<T, E> Option<Result<T, E>> {
/// Transposes an `Option` of a `Result` into a `Result` of an `Option`.
///
65 changes: 49 additions & 16 deletions src/libcore/result.rs
Original file line number Diff line number Diff line change
@@ -232,7 +232,7 @@

use fmt;
use iter::{FromIterator, FusedIterator, TrustedLen};
use ops::{self, Deref};
use ops::{self, Deref, DerefMut};

/// `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]).
///
@@ -927,42 +927,75 @@ impl<T: Default, E> Result<T, E> {

#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
impl<T: Deref, E> Result<T, E> {
/// Converts from `&Result<T, E>` to `Result<&T::Target, &E>`.
/// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&T::Target, &E>`.
///
/// Leaves the original Result in-place, creating a new one with a reference
/// to the original one, additionally coercing the `Ok` arm of the Result via
/// `Deref`.
pub fn deref_ok(&self) -> Result<&T::Target, &E> {
/// Leaves the original `Result` in-place, creating a new one containing a reference to the
/// `Ok` type's `Deref::Target` type.
pub fn as_deref_ok(&self) -> Result<&T::Target, &E> {
self.as_ref().map(|t| t.deref())
}
}

#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
impl<T, E: Deref> Result<T, E> {
/// Converts from `&Result<T, E>` to `Result<&T, &E::Target>`.
/// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&T, &E::Target>`.
///
/// Leaves the original Result in-place, creating a new one with a reference
/// to the original one, additionally coercing the `Err` arm of the Result via
/// `Deref`.
pub fn deref_err(&self) -> Result<&T, &E::Target>
/// Leaves the original `Result` in-place, creating a new one containing a reference to the
/// `Err` type's `Deref::Target` type.
pub fn as_deref_err(&self) -> Result<&T, &E::Target>
{
self.as_ref().map_err(|e| e.deref())
}
}

#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
impl<T: Deref, E: Deref> Result<T, E> {
/// Converts from `&Result<T, E>` to `Result<&T::Target, &E::Target>`.
/// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&T::Target, &E::Target>`.
///
/// Leaves the original Result in-place, creating a new one with a reference
/// to the original one, additionally coercing both the `Ok` and `Err` arms
/// of the Result via `Deref`.
pub fn deref(&self) -> Result<&T::Target, &E::Target>
/// Leaves the original `Result` in-place, creating a new one containing a reference to both
/// the `Ok` and `Err` types' `Deref::Target` types.
pub fn as_deref(&self) -> Result<&T::Target, &E::Target>
{
self.as_ref().map(|t| t.deref()).map_err(|e| e.deref())
}
}

#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
impl<T: DerefMut, E> Result<T, E> {
/// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to `Result<&mut T::Target, &mut E>`.
///
/// Leaves the original `Result` in-place, creating a new one containing a mutable reference to
/// the `Ok` type's `Deref::Target` type.
pub fn as_deref_mut_ok(&mut self) -> Result<&mut T::Target, &mut E> {
self.as_mut().map(|t| t.deref_mut())
}
}

#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
impl<T, E: DerefMut> Result<T, E> {
/// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to `Result<&mut T, &mut E::Target>`.
///
/// Leaves the original `Result` in-place, creating a new one containing a mutable reference to
/// the `Err` type's `Deref::Target` type.
pub fn as_deref_mut_err(&mut self) -> Result<&mut T, &mut E::Target>
{
self.as_mut().map_err(|e| e.deref_mut())
}
}

#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
impl<T: DerefMut, E: DerefMut> Result<T, E> {
/// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to
/// `Result<&mut T::Target, &mut E::Target>`.
///
/// Leaves the original `Result` in-place, creating a new one containing a mutable reference to
/// both the `Ok` and `Err` types' `Deref::Target` types.
pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E::Target>
{
self.as_mut().map(|t| t.deref_mut()).map_err(|e| e.deref_mut())
}
}

impl<T, E> Result<Option<T>, E> {
/// Transposes a `Result` of an `Option` into an `Option` of a `Result`.
///
30 changes: 25 additions & 5 deletions src/libcore/tests/option.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use core::option::*;
use core::mem;
use core::clone::Clone;
use core::array::FixedSizeArray;
use core::ops::DerefMut;

#[test]
fn test_get_ptr() {
@@ -310,20 +312,38 @@ fn test_try() {
}

#[test]
fn test_option_deref() {
fn test_option_as_deref() {
// Some: &Option<T: Deref>::Some(T) -> Option<&T::Deref::Target>::Some(&*T)
let ref_option = &Some(&42);
assert_eq!(ref_option.deref(), Some(&42));
assert_eq!(ref_option.as_deref(), Some(&42));

let ref_option = &Some(String::from("a result"));
assert_eq!(ref_option.deref(), Some("a result"));
assert_eq!(ref_option.as_deref(), Some("a result"));

let ref_option = &Some(vec![1, 2, 3, 4, 5]);
assert_eq!(ref_option.deref(), Some(&[1, 2, 3, 4, 5][..]));
assert_eq!(ref_option.as_deref(), Some([1, 2, 3, 4, 5].as_slice()));

// None: &Option<T: Deref>>::None -> None
let ref_option: &Option<&i32> = &None;
assert_eq!(ref_option.deref(), None);
assert_eq!(ref_option.as_deref(), None);
}

#[test]
fn test_option_as_deref_mut() {
// Some: &mut Option<T: Deref>::Some(T) -> Option<&mut T::Deref::Target>::Some(&mut *T)
let mut val = 42;
let ref_option = &mut Some(&mut val);
assert_eq!(ref_option.as_deref_mut(), Some(&mut 42));

let ref_option = &mut Some(String::from("a result"));
assert_eq!(ref_option.as_deref_mut(), Some(String::from("a result").deref_mut()));

let ref_option = &mut Some(vec![1, 2, 3, 4, 5]);
assert_eq!(ref_option.as_deref_mut(), Some([1, 2, 3, 4, 5].as_mut_slice()));

// None: &mut Option<T: Deref>>::None -> None
let ref_option: &mut Option<&mut i32> = &mut None;
assert_eq!(ref_option.as_deref_mut(), None);
}

#[test]
185 changes: 153 additions & 32 deletions src/libcore/tests/result.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use core::option::*;
use core::array::FixedSizeArray;
use core::ops::DerefMut;

fn op1() -> Result<isize, &'static str> { Ok(666) }
fn op2() -> Result<isize, &'static str> { Err("sadface") }
@@ -225,94 +227,213 @@ fn test_try() {
}

#[test]
fn test_result_deref() {
// &Result<T: Deref, E>::Ok(T).deref_ok() ->
fn test_result_as_deref() {
// &Result<T: Deref, E>::Ok(T).as_deref_ok() ->
// Result<&T::Deref::Target, &E>::Ok(&*T)
let ref_ok = &Result::Ok::<&i32, u8>(&42);
let expected_result = Result::Ok::<&i32, &u8>(&42);
assert_eq!(ref_ok.deref_ok(), expected_result);
assert_eq!(ref_ok.as_deref_ok(), expected_result);

let ref_ok = &Result::Ok::<String, u32>(String::from("a result"));
let expected_result = Result::Ok::<&str, &u32>("a result");
assert_eq!(ref_ok.deref_ok(), expected_result);
assert_eq!(ref_ok.as_deref_ok(), expected_result);

let ref_ok = &Result::Ok::<Vec<i32>, u32>(vec![1, 2, 3, 4, 5]);
let expected_result = Result::Ok::<&[i32], &u32>(&[1, 2, 3, 4, 5][..]);
assert_eq!(ref_ok.deref_ok(), expected_result);
let expected_result = Result::Ok::<&[i32], &u32>([1, 2, 3, 4, 5].as_slice());
assert_eq!(ref_ok.as_deref_ok(), expected_result);

// &Result<T: Deref, E: Deref>::Ok(T).deref() ->
// &Result<T: Deref, E: Deref>::Ok(T).as_deref() ->
// Result<&T::Deref::Target, &E::Deref::Target>::Ok(&*T)
let ref_ok = &Result::Ok::<&i32, &u8>(&42);
let expected_result = Result::Ok::<&i32, &u8>(&42);
assert_eq!(ref_ok.deref(), expected_result);
assert_eq!(ref_ok.as_deref(), expected_result);

let ref_ok = &Result::Ok::<String, &u32>(String::from("a result"));
let expected_result = Result::Ok::<&str, &u32>("a result");
assert_eq!(ref_ok.deref(), expected_result);
assert_eq!(ref_ok.as_deref(), expected_result);

let ref_ok = &Result::Ok::<Vec<i32>, &u32>(vec![1, 2, 3, 4, 5]);
let expected_result = Result::Ok::<&[i32], &u32>(&[1, 2, 3, 4, 5][..]);
assert_eq!(ref_ok.deref(), expected_result);
let expected_result = Result::Ok::<&[i32], &u32>([1, 2, 3, 4, 5].as_slice());
assert_eq!(ref_ok.as_deref(), expected_result);

// &Result<T, E: Deref>::Err(T).deref_err() ->
// &Result<T, E: Deref>::Err(T).as_deref_err() ->
// Result<&T, &E::Deref::Target>::Err(&*E)
let ref_err = &Result::Err::<u8, &i32>(&41);
let expected_result = Result::Err::<&u8, &i32>(&41);
assert_eq!(ref_err.deref_err(), expected_result);
assert_eq!(ref_err.as_deref_err(), expected_result);

let ref_err = &Result::Err::<u32, String>(String::from("an error"));
let expected_result = Result::Err::<&u32, &str>("an error");
assert_eq!(ref_err.deref_err(), expected_result);
assert_eq!(ref_err.as_deref_err(), expected_result);

let ref_err = &Result::Err::<u32, Vec<i32>>(vec![5, 4, 3, 2, 1]);
let expected_result = Result::Err::<&u32, &[i32]>(&[5, 4, 3, 2, 1][..]);
assert_eq!(ref_err.deref_err(), expected_result);
let expected_result = Result::Err::<&u32, &[i32]>([5, 4, 3, 2, 1].as_slice());
assert_eq!(ref_err.as_deref_err(), expected_result);

// &Result<T: Deref, E: Deref>::Err(T).deref_err() ->
// &Result<T: Deref, E: Deref>::Err(T).as_deref_err() ->
// Result<&T, &E::Deref::Target>::Err(&*E)
let ref_err = &Result::Err::<&u8, &i32>(&41);
let expected_result = Result::Err::<&u8, &i32>(&41);
assert_eq!(ref_err.deref(), expected_result);
assert_eq!(ref_err.as_deref(), expected_result);

let ref_err = &Result::Err::<&u32, String>(String::from("an error"));
let expected_result = Result::Err::<&u32, &str>("an error");
assert_eq!(ref_err.deref(), expected_result);
assert_eq!(ref_err.as_deref(), expected_result);

let ref_err = &Result::Err::<&u32, Vec<i32>>(vec![5, 4, 3, 2, 1]);
let expected_result = Result::Err::<&u32, &[i32]>(&[5, 4, 3, 2, 1][..]);
assert_eq!(ref_err.deref(), expected_result);
let expected_result = Result::Err::<&u32, &[i32]>([5, 4, 3, 2, 1].as_slice());
assert_eq!(ref_err.as_deref(), expected_result);

// The following cases test calling deref_* with the wrong variant (i.e.
// `deref_ok()` with a `Result::Err()`, or `deref_err()` with a `Result::Ok()`.
// While unusual, these cases are supported to ensure that an `inner_deref`
// The following cases test calling `as_deref_*` with the wrong variant (i.e.
// `as_deref_ok()` with a `Result::Err()`, or `as_deref_err()` with a `Result::Ok()`.
// While uncommon, these cases are supported to ensure that an `as_deref_*`
// call can still be made even when one of the Result types does not implement
// `Deref` (for example, std::io::Error).

// &Result<T, E: Deref>::Ok(T).deref_err() ->
// &Result<T, E: Deref>::Ok(T).as_deref_err() ->
// Result<&T, &E::Deref::Target>::Ok(&T)
let ref_ok = &Result::Ok::<i32, &u8>(42);
let expected_result = Result::Ok::<&i32, &u8>(&42);
assert_eq!(ref_ok.deref_err(), expected_result);
assert_eq!(ref_ok.as_deref_err(), expected_result);

let ref_ok = &Result::Ok::<&str, &u32>("a result");
let expected_result = Result::Ok::<&&str, &u32>(&"a result");
assert_eq!(ref_ok.deref_err(), expected_result);
assert_eq!(ref_ok.as_deref_err(), expected_result);

let ref_ok = &Result::Ok::<[i32; 5], &u32>([1, 2, 3, 4, 5]);
let expected_result = Result::Ok::<&[i32; 5], &u32>(&[1, 2, 3, 4, 5]);
assert_eq!(ref_ok.deref_err(), expected_result);
assert_eq!(ref_ok.as_deref_err(), expected_result);

// &Result<T: Deref, E>::Err(E).deref_ok() ->
// &Result<T: Deref, E>::Err(E).as_deref_ok() ->
// Result<&T::Deref::Target, &E>::Err(&E)
let ref_err = &Result::Err::<&u8, i32>(41);
let expected_result = Result::Err::<&u8, &i32>(&41);
assert_eq!(ref_err.deref_ok(), expected_result);
assert_eq!(ref_err.as_deref_ok(), expected_result);

let ref_err = &Result::Err::<&u32, &str>("an error");
let expected_result = Result::Err::<&u32, &&str>(&"an error");
assert_eq!(ref_err.deref_ok(), expected_result);
assert_eq!(ref_err.as_deref_ok(), expected_result);

let ref_err = &Result::Err::<&u32, [i32; 5]>([5, 4, 3, 2, 1]);
let expected_result = Result::Err::<&u32, &[i32; 5]>(&[5, 4, 3, 2, 1]);
assert_eq!(ref_err.deref_ok(), expected_result);
assert_eq!(ref_err.as_deref_ok(), expected_result);
}

#[test]
fn test_result_as_deref_mut() {
// &mut Result<T: Deref, E>::Ok(T).as_deref_mut_ok() ->
// Result<&mut T::Deref::Target, &mut E>::Ok(&mut *T)
let mut val = 42;
let mut expected_val = 42;
let mut_ok = &mut Result::Ok::<&mut i32, u8>(&mut val);
let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val);
assert_eq!(mut_ok.as_deref_mut_ok(), expected_result);

let mut expected_string = String::from("a result");
let mut_ok = &mut Result::Ok::<String, u32>(expected_string.clone());
let expected_result = Result::Ok::<&mut str, &mut u32>(expected_string.deref_mut());
assert_eq!(mut_ok.as_deref_mut_ok(), expected_result);

let mut expected_vec = vec![1, 2, 3, 4, 5];
let mut_ok = &mut Result::Ok::<Vec<i32>, u32>(expected_vec.clone());
let expected_result = Result::Ok::<&mut [i32], &mut u32>(expected_vec.as_mut_slice());
assert_eq!(mut_ok.as_deref_mut_ok(), expected_result);

// &mut Result<T: Deref, E: Deref>::Ok(T).as_deref_mut() ->
// Result<&mut T::Deref::Target, &mut E::Deref::Target>::Ok(&mut *T)
let mut val = 42;
let mut expected_val = 42;
let mut_ok = &mut Result::Ok::<&mut i32, &mut u8>(&mut val);
let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val);
assert_eq!(mut_ok.as_deref_mut(), expected_result);

let mut expected_string = String::from("a result");
let mut_ok = &mut Result::Ok::<String, &mut u32>(expected_string.clone());
let expected_result = Result::Ok::<&mut str, &mut u32>(expected_string.deref_mut());
assert_eq!(mut_ok.as_deref_mut(), expected_result);

let mut expected_vec = vec![1, 2, 3, 4, 5];
let mut_ok = &mut Result::Ok::<Vec<i32>, &mut u32>(expected_vec.clone());
let expected_result = Result::Ok::<&mut [i32], &mut u32>(expected_vec.as_mut_slice());
assert_eq!(mut_ok.as_deref_mut(), expected_result);

// &mut Result<T, E: Deref>::Err(T).as_deref_mut_err() ->
// Result<&mut T, &mut E::Deref::Target>::Err(&mut *E)
let mut val = 41;
let mut expected_val = 41;
let mut_err = &mut Result::Err::<u8, &mut i32>(&mut val);
let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val);
assert_eq!(mut_err.as_deref_mut_err(), expected_result);

let mut expected_string = String::from("an error");
let mut_err = &mut Result::Err::<u32, String>(expected_string.clone());
let expected_result = Result::Err::<&mut u32, &mut str>(expected_string.deref_mut());
assert_eq!(mut_err.as_deref_mut_err(), expected_result);

let mut expected_vec = vec![5, 4, 3, 2, 1];
let mut_err = &mut Result::Err::<u32, Vec<i32>>(expected_vec.clone());
let expected_result = Result::Err::<&mut u32, &mut [i32]>(expected_vec.as_mut_slice());
assert_eq!(mut_err.as_deref_mut_err(), expected_result);

// &mut Result<T: Deref, E: Deref>::Err(T).as_deref_mut_err() ->
// Result<&mut T, &mut E::Deref::Target>::Err(&mut *E)
let mut val = 41;
let mut expected_val = 41;
let mut_err = &mut Result::Err::<&mut u8, &mut i32>(&mut val);
let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val);
assert_eq!(mut_err.as_deref_mut(), expected_result);

let mut expected_string = String::from("an error");
let mut_err = &mut Result::Err::<&mut u32, String>(expected_string.clone());
let expected_result = Result::Err::<&mut u32, &mut str>(expected_string.as_mut_str());
assert_eq!(mut_err.as_deref_mut(), expected_result);

let mut expected_vec = vec![5, 4, 3, 2, 1];
let mut_err = &mut Result::Err::<&mut u32, Vec<i32>>(expected_vec.clone());
let expected_result = Result::Err::<&mut u32, &mut [i32]>(expected_vec.as_mut_slice());
assert_eq!(mut_err.as_deref_mut(), expected_result);

// The following cases test calling `as_deref_mut_*` with the wrong variant (i.e.
// `as_deref_mut_ok()` with a `Result::Err()`, or `as_deref_mut_err()` with a `Result::Ok()`.
// While uncommon, these cases are supported to ensure that an `as_deref_mut_*`
// call can still be made even when one of the Result types does not implement
// `Deref` (for example, std::io::Error).

// &mut Result<T, E: Deref>::Ok(T).as_deref_mut_err() ->
// Result<&mut T, &mut E::Deref::Target>::Ok(&mut T)
let mut expected_val = 42;
let mut_ok = &mut Result::Ok::<i32, &mut u8>(expected_val.clone());
let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val);
assert_eq!(mut_ok.as_deref_mut_err(), expected_result);

let string = String::from("a result");
let expected_string = string.clone();
let mut ref_str = expected_string.as_ref();
let mut_ok = &mut Result::Ok::<&str, &mut u32>(string.as_str());
let expected_result = Result::Ok::<&mut &str, &mut u32>(&mut ref_str);
assert_eq!(mut_ok.as_deref_mut_err(), expected_result);

let mut expected_arr = [1, 2, 3, 4, 5];
let mut_ok = &mut Result::Ok::<[i32; 5], &mut u32>(expected_arr.clone());
let expected_result = Result::Ok::<&mut [i32; 5], &mut u32>(&mut expected_arr);
assert_eq!(mut_ok.as_deref_mut_err(), expected_result);

// &mut Result<T: Deref, E>::Err(E).as_deref_mut_ok() ->
// Result<&mut T::Deref::Target, &mut E>::Err(&mut E)
let mut expected_val = 41;
let mut_err = &mut Result::Err::<&mut u8, i32>(expected_val.clone());
let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val);
assert_eq!(mut_err.as_deref_mut_ok(), expected_result);

let string = String::from("an error");
let expected_string = string.clone();
let mut ref_str = expected_string.as_ref();
let mut_err = &mut Result::Err::<&mut u32, &str>(string.as_str());
let expected_result = Result::Err::<&mut u32, &mut &str>(&mut ref_str);
assert_eq!(mut_err.as_deref_mut_ok(), expected_result);

let mut expected_arr = [5, 4, 3, 2, 1];
let mut_err = &mut Result::Err::<&mut u32, [i32; 5]>(expected_arr.clone());
let expected_result = Result::Err::<&mut u32, &mut [i32; 5]>(&mut expected_arr);
assert_eq!(mut_err.as_deref_mut_ok(), expected_result);
}
7 changes: 7 additions & 0 deletions src/librustc_codegen_ssa/mir/block.rs
Original file line number Diff line number Diff line change
@@ -238,6 +238,13 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
}
if self.fn_ty.ret.layout.abi.is_uninhabited() {
// Functions with uninhabited return values are marked `noreturn`,
// so we should make sure that we never actually do.
bx.abort();
bx.unreachable();
return;
}
let llval = match self.fn_ty.ret.mode {
PassMode::Ignore(IgnoreMode::Zst) | PassMode::Indirect(..) => {
bx.ret_void();
3 changes: 2 additions & 1 deletion src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs
Original file line number Diff line number Diff line change
@@ -5,7 +5,8 @@ pub fn target() -> TargetResult {
base.cpu = "x86-64".to_string();
base.max_atomic_width = Some(64);
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mx32".to_string());
base.stack_probes = true;
// BUG: temporarily workaround #59674
base.stack_probes = false;
base.has_elf_tls = false;
// BUG(GabrielMajeri): disabling the PLT on x86_64 Linux with x32 ABI
// breaks code gen. See LLVM bug 36743
8 changes: 4 additions & 4 deletions src/librustdoc/html/render.rs
Original file line number Diff line number Diff line change
@@ -1147,7 +1147,7 @@ themePicker.onblur = handleThemeButtonsBlur;
title: "Index of crates",
css_class: "mod",
root_path: "./",
static_root_path: cx.shared.static_root_path.deref(),
static_root_path: cx.shared.static_root_path.as_deref(),
description: "List of crates",
keywords: BASIC_KEYWORDS,
resource_suffix: &cx.shared.resource_suffix,
@@ -1479,7 +1479,7 @@ impl<'a> SourceCollector<'a> {
title: &title,
css_class: "source",
root_path: &root_path,
static_root_path: self.scx.static_root_path.deref(),
static_root_path: self.scx.static_root_path.as_deref(),
description: &desc,
keywords: BASIC_KEYWORDS,
resource_suffix: &self.scx.resource_suffix,
@@ -2077,7 +2077,7 @@ impl Context {
title: "List of all items in this crate",
css_class: "mod",
root_path: "../",
static_root_path: self.shared.static_root_path.deref(),
static_root_path: self.shared.static_root_path.as_deref(),
description: "List of all items in this crate",
keywords: BASIC_KEYWORDS,
resource_suffix: &self.shared.resource_suffix,
@@ -2158,7 +2158,7 @@ impl Context {
let page = layout::Page {
css_class: tyname,
root_path: &self.root_path(),
static_root_path: self.shared.static_root_path.deref(),
static_root_path: self.shared.static_root_path.as_deref(),
title: &title,
description: &desc,
keywords: &keywords,
11 changes: 9 additions & 2 deletions src/libstd/fs.rs
Original file line number Diff line number Diff line change
@@ -21,7 +21,9 @@ use crate::time::SystemTime;
/// it was opened with. Files also implement [`Seek`] to alter the logical cursor
/// that the file contains internally.
///
/// Files are automatically closed when they go out of scope.
/// Files are automatically closed when they go out of scope. Errors detected
/// on closing are ignored by the implementation of `Drop`. Use the method
/// [`sync_all`] if these errors must be manually handled.
///
/// # Examples
///
@@ -84,6 +86,7 @@ use crate::time::SystemTime;
/// [`Read`]: ../io/trait.Read.html
/// [`Write`]: ../io/trait.Write.html
/// [`BufReader<R>`]: ../io/struct.BufReader.html
/// [`sync_all`]: struct.File.html#method.sync_all
#[stable(feature = "rust1", since = "1.0.0")]
pub struct File {
inner: fs_imp::File,
@@ -391,9 +394,13 @@ impl File {

/// Attempts to sync all OS-internal metadata to disk.
///
/// This function will attempt to ensure that all in-core data reaches the
/// This function will attempt to ensure that all in-memory data reaches the
/// filesystem before returning.
///
/// This can be used to handle errors that would otherwise only be caught
/// when the `File` is closed. Dropping a file will ignore errors in
/// synchronizing this in-memory data.
///
/// # Examples
///
/// ```no_run
2 changes: 1 addition & 1 deletion src/stdsimd
32 changes: 32 additions & 0 deletions src/test/codegen/noreturn-uninhabited.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// compile-flags: -g -C no-prepopulate-passes
// ignore-tidy-linelength

#![crate_type = "lib"]

#[derive(Clone, Copy)]
pub enum EmptyEnum {}

#[no_mangle]
pub fn empty(x: &EmptyEnum) -> EmptyEnum {
// CHECK: @empty({{.*}}) unnamed_addr #0
// CHECK-NOT: ret void
// CHECK: call void @llvm.trap()
// CHECK: unreachable
*x
}

pub struct Foo(String, EmptyEnum);

#[no_mangle]
pub fn foo(x: String, y: &EmptyEnum) -> Foo {
// CHECK: @foo({{.*}}) unnamed_addr #0
// CHECK-NOT: ret %Foo
// CHECK: call void @llvm.trap()
// CHECK: unreachable
Foo(x, *y)
}

// CHECK: attributes #0 = {{{.*}} noreturn {{.*}}}

// CHECK: DISubprogram(name: "empty", {{.*}} DIFlagNoReturn
// CHECK: DISubprogram(name: "foo", {{.*}} DIFlagNoReturn
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#![feature(inner_deref)]

fn main() {
let _result = &Some(42).as_deref();
//~^ ERROR no method named `as_deref` found for type `std::option::Option<{integer}>`
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0599]: no method named `as_deref` found for type `std::option::Option<{integer}>` in the current scope
--> $DIR/option-as_deref.rs:4:29
|
LL | let _result = &Some(42).as_deref();
| ^^^^^^^^ help: did you mean: `as_ref`
|
= note: the method `as_deref` exists but the following trait bounds were not satisfied:
`{integer} : std::ops::Deref`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#![feature(inner_deref)]

fn main() {
let _result = &mut Some(42).as_deref_mut();
//~^ ERROR no method named `as_deref_mut` found for type `std::option::Option<{integer}>`
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0599]: no method named `as_deref_mut` found for type `std::option::Option<{integer}>` in the current scope
--> $DIR/option-as_deref_mut.rs:4:33
|
LL | let _result = &mut Some(42).as_deref_mut();
| ^^^^^^^^^^^^
|
= note: the method `as_deref_mut` exists but the following trait bounds were not satisfied:
`{integer} : std::ops::DerefMut`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#![feature(inner_deref)]

fn main() {
let _result = &Ok(42).as_deref();
//~^ ERROR no method named `as_deref` found
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0599]: no method named `as_deref` found for type `std::result::Result<{integer}, _>` in the current scope
--> $DIR/result-as_deref.rs:4:27
|
LL | let _result = &Ok(42).as_deref();
| ^^^^^^^^ help: did you mean: `as_ref`
|
= note: the method `as_deref` exists but the following trait bounds were not satisfied:
`{integer} : std::ops::Deref`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#![feature(inner_deref)]

fn main() {
let _result = &Err(41).as_deref_err();
//~^ ERROR no method named `as_deref_err` found
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0599]: no method named `as_deref_err` found for type `std::result::Result<_, {integer}>` in the current scope
--> $DIR/result-as_deref_err.rs:4:28
|
LL | let _result = &Err(41).as_deref_err();
| ^^^^^^^^^^^^ help: did you mean: `as_deref_ok`
|
= note: the method `as_deref_err` exists but the following trait bounds were not satisfied:
`{integer} : std::ops::Deref`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#![feature(inner_deref)]

fn main() {
let _result = &mut Ok(42).as_deref_mut();
//~^ ERROR no method named `as_deref_mut` found
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0599]: no method named `as_deref_mut` found for type `std::result::Result<{integer}, _>` in the current scope
--> $DIR/result-as_deref_mut.rs:4:31
|
LL | let _result = &mut Ok(42).as_deref_mut();
| ^^^^^^^^^^^^ help: did you mean: `as_deref_err`
|
= note: the method `as_deref_mut` exists but the following trait bounds were not satisfied:
`{integer} : std::ops::DerefMut`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#![feature(inner_deref)]

fn main() {
let _result = &mut Err(41).as_deref_mut_err();
//~^ ERROR no method named `as_deref_mut_err` found
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0599]: no method named `as_deref_mut_err` found for type `std::result::Result<_, {integer}>` in the current scope
--> $DIR/result-as_deref_mut_err.rs:4:32
|
LL | let _result = &mut Err(41).as_deref_mut_err();
| ^^^^^^^^^^^^^^^^ help: did you mean: `as_deref_mut_ok`
|
= note: the method `as_deref_mut_err` exists but the following trait bounds were not satisfied:
`{integer} : std::ops::DerefMut`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#![feature(inner_deref)]

fn main() {
let _result = &mut Ok(42).as_deref_mut_ok();
//~^ ERROR no method named `as_deref_mut_ok` found
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0599]: no method named `as_deref_mut_ok` found for type `std::result::Result<{integer}, _>` in the current scope
--> $DIR/result-as_deref_mut_ok.rs:4:31
|
LL | let _result = &mut Ok(42).as_deref_mut_ok();
| ^^^^^^^^^^^^^^^ help: did you mean: `as_deref_mut_err`
|
= note: the method `as_deref_mut_ok` exists but the following trait bounds were not satisfied:
`{integer} : std::ops::DerefMut`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#![feature(inner_deref)]

fn main() {
let _result = &Ok(42).as_deref_ok();
//~^ ERROR no method named `as_deref_ok` found
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0599]: no method named `as_deref_ok` found for type `std::result::Result<{integer}, _>` in the current scope
--> $DIR/result-as_deref_ok.rs:4:27
|
LL | let _result = &Ok(42).as_deref_ok();
| ^^^^^^^^^^^ help: did you mean: `as_deref_err`
|
= note: the method `as_deref_ok` exists but the following trait bounds were not satisfied:
`{integer} : std::ops::Deref`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

2 changes: 1 addition & 1 deletion src/tools/miri
2 changes: 1 addition & 1 deletion src/tools/rustc-workspace-hack/Cargo.toml
Original file line number Diff line number Diff line change
@@ -57,7 +57,7 @@ features = [
[dependencies]
curl-sys = { version = "0.4.13", features = ["http2", "libnghttp2-sys"], optional = true }
parking_lot = { version = "0.7", features = ['nightly'] }
rand = { version = "0.5.5", features = ["i128_support"] }
rand = { version = "0.6.1", features = ["i128_support"] }
serde = { version = "1.0.82", features = ['derive'] }
serde_json = { version = "1.0.31", features = ["raw_value"] }
smallvec = { version = "0.6", features = ['union', 'may_dangle'] }