Skip to content

Rollup of 5 pull requests #69484

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

Merged
merged 19 commits into from
Feb 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
14999dd
Add methods to leak RefCell borrows to references
HeroicKatora Jan 29, 2020
99b4357
Add tracking number, adjust documentation wording
HeroicKatora Feb 12, 2020
bd12cd3
Formatter::sign is &'static str
Mark-Simulacrum Feb 15, 2020
6c45e45
Drop unused argument to float functions
Mark-Simulacrum Feb 15, 2020
34ef8f5
Move to using an extern type for opaqueness
Mark-Simulacrum Feb 15, 2020
f6bfdc9
Move the show_usize marker function to a static
Mark-Simulacrum Feb 16, 2020
03ca0e2
Allow getting `no_std` from the config file
Ericson2314 Feb 22, 2020
329022d
Address method comments
HeroicKatora Feb 24, 2020
4dbdadf
rustc_metadata: Use binary search from standard library
petrochenkov Feb 24, 2020
245e15b
parse: extract `parse_stmt_item` & `parse_stmt_path_start`.
Centril Feb 23, 2020
32295ae
parse: simplify `parse_stmt_without_recovery`.
Centril Feb 23, 2020
1eb0844
parse: move condition into guard
Centril Feb 24, 2020
4f15867
bootstrap: Further centralize target defaulting logic.
Ericson2314 Feb 25, 2020
7876711
parse: address nitpick
Centril Feb 25, 2020
86b9377
Rollup merge of #68712 - HeroicKatora:finalize-ref-cell, r=dtolnay
Dylan-DPC Feb 26, 2020
e028f26
Rollup merge of #69209 - Mark-Simulacrum:strip-unsafe, r=dtolnay
Dylan-DPC Feb 26, 2020
d799f2d
Rollup merge of #69381 - QuiltOS:no-std-from-config, r=Mark-Simulacrum
Dylan-DPC Feb 26, 2020
c076027
Rollup merge of #69434 - petrochenkov:metabs, r=Mark-Simulacrum
Dylan-DPC Feb 26, 2020
ae383e2
Rollup merge of #69447 - Centril:minor-stmt-refactor, r=estebank
Dylan-DPC Feb 26, 2020
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
15 changes: 14 additions & 1 deletion src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,15 @@ pub struct Target {
pub no_std: bool,
}

impl Target {
pub fn from_triple(triple: &str) -> Self {
let mut target: Self = Default::default();
if triple.contains("-none-") || triple.contains("nvptx") {
target.no_std = true;
}
target
}
}
/// Structure of the `config.toml` file that configuration is read from.
///
/// This structure uses `Decodable` to automatically decode a TOML configuration
Expand Down Expand Up @@ -353,6 +362,7 @@ struct TomlTarget {
musl_root: Option<String>,
wasi_root: Option<String>,
qemu_rootfs: Option<String>,
no_std: Option<bool>,
}

impl Config {
Expand Down Expand Up @@ -595,7 +605,7 @@ impl Config {

if let Some(ref t) = toml.target {
for (triple, cfg) in t {
let mut target = Target::default();
let mut target = Target::from_triple(triple);

if let Some(ref s) = cfg.llvm_config {
target.llvm_config = Some(config.src.join(s));
Expand All @@ -606,6 +616,9 @@ impl Config {
if let Some(ref s) = cfg.android_ndk {
target.ndk = Some(config.src.join(s));
}
if let Some(s) = cfg.no_std {
target.no_std = s;
}
target.cc = cfg.cc.clone().map(PathBuf::from);
target.cxx = cfg.cxx.clone().map(PathBuf::from);
target.ar = cfg.ar.clone().map(PathBuf::from);
Expand Down
9 changes: 3 additions & 6 deletions src/bootstrap/sanity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use std::process::Command;

use build_helper::{output, t};

use crate::config::Target;
use crate::Build;

struct Finder {
Expand Down Expand Up @@ -192,13 +193,9 @@ pub fn check(build: &mut Build) {
panic!("the iOS target is only supported on macOS");
}

if target.contains("-none-") || target.contains("nvptx") {
if build.no_std(*target).is_none() {
let target = build.config.target_config.entry(target.clone()).or_default();

target.no_std = true;
}
build.config.target_config.entry(target.clone()).or_insert(Target::from_triple(target));

if target.contains("-none-") || target.contains("nvptx") {
if build.no_std(*target) == Some(false) {
panic!("All the *-none-* and nvptx* targets are no-std targets")
}
Expand Down
63 changes: 63 additions & 0 deletions src/libcore/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1245,6 +1245,38 @@ impl<'b, T: ?Sized> Ref<'b, T> {
let borrow = orig.borrow.clone();
(Ref { value: a, borrow }, Ref { value: b, borrow: orig.borrow })
}

/// Convert into a reference to the underlying data.
///
/// The underlying `RefCell` can never be mutably borrowed from again and will always appear
/// already immutably borrowed. It is not a good idea to leak more than a constant number of
/// references. The `RefCell` can be immutably borrowed again if only a smaller number of leaks
/// have occurred in total.
///
/// This is an associated function that needs to be used as
/// `Ref::leak(...)`. A method would interfere with methods of the
/// same name on the contents of a `RefCell` used through `Deref`.
///
/// # Examples
///
/// ```
/// #![feature(cell_leak)]
/// use std::cell::{RefCell, Ref};
/// let cell = RefCell::new(0);
///
/// let value = Ref::leak(cell.borrow());
/// assert_eq!(*value, 0);
///
/// assert!(cell.try_borrow().is_ok());
/// assert!(cell.try_borrow_mut().is_err());
/// ```
#[unstable(feature = "cell_leak", issue = "69099")]
pub fn leak(orig: Ref<'b, T>) -> &'b T {
// By forgetting this Ref we ensure that the borrow counter in the RefCell never goes back
// to UNUSED again. No further mutable references can be created from the original cell.
mem::forget(orig.borrow);
orig.value
}
}

#[unstable(feature = "coerce_unsized", issue = "27732")]
Expand Down Expand Up @@ -1330,6 +1362,37 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
let borrow = orig.borrow.clone();
(RefMut { value: a, borrow }, RefMut { value: b, borrow: orig.borrow })
}

/// Convert into a mutable reference to the underlying data.
///
/// The underlying `RefCell` can not be borrowed from again and will always appear already
/// mutably borrowed, making the returned reference the only to the interior.
///
/// This is an associated function that needs to be used as
/// `RefMut::leak(...)`. A method would interfere with methods of the
/// same name on the contents of a `RefCell` used through `Deref`.
///
/// # Examples
///
/// ```
/// #![feature(cell_leak)]
/// use std::cell::{RefCell, RefMut};
/// let cell = RefCell::new(0);
///
/// let value = RefMut::leak(cell.borrow_mut());
/// assert_eq!(*value, 0);
/// *value = 1;
///
/// assert!(cell.try_borrow_mut().is_err());
/// ```
#[unstable(feature = "cell_leak", issue = "69099")]
pub fn leak(orig: RefMut<'b, T>) -> &'b mut T {
// By forgetting this BorrowRefMut we ensure that the borrow counter in the RefCell never
// goes back to UNUSED again. No further references can be created from the original cell,
// making the current borrow the only reference for the remaining lifetime.
mem::forget(orig.borrow);
orig.value
}
}

struct BorrowRefMut<'b> {
Expand Down
2 changes: 0 additions & 2 deletions src/libcore/fmt/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ where
*num,
sign,
precision,
false,
buf.get_mut(),
parts.get_mut(),
);
Expand Down Expand Up @@ -59,7 +58,6 @@ where
*num,
sign,
precision,
false,
buf.get_mut(),
parts.get_mut(),
);
Expand Down
45 changes: 23 additions & 22 deletions src/libcore/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,16 +238,8 @@ pub struct Formatter<'a> {
// NB. Argument is essentially an optimized partially applied formatting function,
// equivalent to `exists T.(&T, fn(&T, &mut Formatter<'_>) -> Result`.

struct Void {
_priv: (),
/// Erases all oibits, because `Void` erases the type of the object that
/// will be used to produce formatted output. Since we do not know what
/// oibits the real types have (and they can have any or none), we need to
/// take the most conservative approach and forbid all oibits.
///
/// It was added after #45197 showed that one could share a `!Sync`
/// object across threads by passing it into `format_args!`.
_oibit_remover: PhantomData<*mut dyn Fn()>,
extern "C" {
type Opaque;
}

/// This struct represents the generic "argument" which is taken by the Xprintf
Expand All @@ -259,16 +251,23 @@ struct Void {
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
#[doc(hidden)]
pub struct ArgumentV1<'a> {
value: &'a Void,
formatter: fn(&Void, &mut Formatter<'_>) -> Result,
value: &'a Opaque,
formatter: fn(&Opaque, &mut Formatter<'_>) -> Result,
}

impl<'a> ArgumentV1<'a> {
#[inline(never)]
fn show_usize(x: &usize, f: &mut Formatter<'_>) -> Result {
Display::fmt(x, f)
}
// This gurantees a single stable value for the function pointer associated with
// indices/counts in the formatting infrastructure.
//
// Note that a function defined as such would not be correct as functions are
// always tagged unnamed_addr with the current lowering to LLVM IR, so their
// address is not considered important to LLVM and as such the as_usize cast
// could have been miscompiled. In practice, we never call as_usize on non-usize
// containing data (as a matter of static generation of the formatting
// arguments), so this is merely an additional check.
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
static USIZE_MARKER: fn(&usize, &mut Formatter<'_>) -> Result = |_, _| loop {};

impl<'a> ArgumentV1<'a> {
#[doc(hidden)]
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
pub fn new<'b, T>(x: &'b T, f: fn(&T, &mut Formatter<'_>) -> Result) -> ArgumentV1<'b> {
Expand All @@ -278,11 +277,13 @@ impl<'a> ArgumentV1<'a> {
#[doc(hidden)]
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
pub fn from_usize(x: &usize) -> ArgumentV1<'_> {
ArgumentV1::new(x, ArgumentV1::show_usize)
ArgumentV1::new(x, USIZE_MARKER)
}

fn as_usize(&self) -> Option<usize> {
if self.formatter as usize == ArgumentV1::show_usize as usize {
if self.formatter as usize == USIZE_MARKER as usize {
// SAFETY: The `formatter` field is only set to USIZE_MARKER if
// the value is a usize, so this is safe
Some(unsafe { *(self.value as *const _ as *const usize) })
} else {
None
Expand Down Expand Up @@ -1356,11 +1357,11 @@ impl<'a> Formatter<'a> {
let mut align = old_align;
if self.sign_aware_zero_pad() {
// a sign always goes first
let sign = unsafe { str::from_utf8_unchecked(formatted.sign) };
let sign = formatted.sign;
self.buf.write_str(sign)?;

// remove the sign from the formatted parts
formatted.sign = b"";
formatted.sign = "";
width = width.saturating_sub(sign.len());
align = rt::v1::Alignment::Right;
self.fill = '0';
Expand Down Expand Up @@ -1392,7 +1393,7 @@ impl<'a> Formatter<'a> {
}

if !formatted.sign.is_empty() {
write_bytes(self.buf, formatted.sign)?;
self.buf.write_str(formatted.sign)?;
}
for part in formatted.parts {
match *part {
Expand Down
6 changes: 3 additions & 3 deletions src/libcore/fmt/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,11 +369,11 @@ macro_rules! impl_Exp {
flt2dec::Part::Copy(exp_slice)
];
let sign = if !is_nonnegative {
&b"-"[..]
"-"
} else if f.sign_plus() {
&b"+"[..]
"+"
} else {
&b""[..]
""
};
let formatted = flt2dec::Formatted{sign, parts};
f.pad_formatted_parts(&formatted)
Expand Down
32 changes: 15 additions & 17 deletions src/libcore/num/flt2dec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ impl<'a> Part<'a> {
#[derive(Clone)]
pub struct Formatted<'a> {
/// A byte slice representing a sign, either `""`, `"-"` or `"+"`.
pub sign: &'static [u8],
pub sign: &'static str,
/// Formatted parts to be rendered after a sign and optional zero padding.
pub parts: &'a [Part<'a>],
}
Expand All @@ -259,7 +259,7 @@ impl<'a> Formatted<'a> {
if out.len() < self.sign.len() {
return None;
}
out[..self.sign.len()].copy_from_slice(self.sign);
out[..self.sign.len()].copy_from_slice(self.sign.as_bytes());

let mut written = self.sign.len();
for part in self.parts {
Expand Down Expand Up @@ -402,38 +402,38 @@ pub enum Sign {
}

/// Returns the static byte string corresponding to the sign to be formatted.
/// It can be either `b""`, `b"+"` or `b"-"`.
fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static [u8] {
/// It can be either `""`, `"+"` or `"-"`.
fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static str {
match (*decoded, sign) {
(FullDecoded::Nan, _) => b"",
(FullDecoded::Zero, Sign::Minus) => b"",
(FullDecoded::Nan, _) => "",
(FullDecoded::Zero, Sign::Minus) => "",
(FullDecoded::Zero, Sign::MinusRaw) => {
if negative {
b"-"
"-"
} else {
b""
""
}
}
(FullDecoded::Zero, Sign::MinusPlus) => b"+",
(FullDecoded::Zero, Sign::MinusPlus) => "+",
(FullDecoded::Zero, Sign::MinusPlusRaw) => {
if negative {
b"-"
"-"
} else {
b"+"
"+"
}
}
(_, Sign::Minus) | (_, Sign::MinusRaw) => {
if negative {
b"-"
"-"
} else {
b""
""
}
}
(_, Sign::MinusPlus) | (_, Sign::MinusPlusRaw) => {
if negative {
b"-"
"-"
} else {
b"+"
"+"
}
}
}
Expand Down Expand Up @@ -462,7 +462,6 @@ pub fn to_shortest_str<'a, T, F>(
v: T,
sign: Sign,
frac_digits: usize,
_upper: bool,
buf: &'a mut [u8],
parts: &'a mut [Part<'a>],
) -> Formatted<'a>
Expand Down Expand Up @@ -679,7 +678,6 @@ pub fn to_exact_fixed_str<'a, T, F>(
v: T,
sign: Sign,
frac_digits: usize,
_upper: bool,
buf: &'a mut [u8],
parts: &'a mut [Part<'a>],
) -> Formatted<'a>
Expand Down
Loading