Skip to content
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

Rollup of 8 pull requests #41641

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
768 changes: 256 additions & 512 deletions RELEASES.md

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions src/bootstrap/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,7 @@ pub fn distcheck(build: &Build) {
return
}

println!("Distcheck");
let dir = build.out.join("tmp").join("distcheck");
let _ = fs::remove_dir_all(&dir);
t!(fs::create_dir_all(&dir));
Expand All @@ -594,6 +595,26 @@ pub fn distcheck(build: &Build) {
build.run(Command::new(build_helper::make(&build.config.build))
.arg("check")
.current_dir(&dir));

// Now make sure that rust-src has all of libstd's dependencies
println!("Distcheck rust-src");
let dir = build.out.join("tmp").join("distcheck-src");
let _ = fs::remove_dir_all(&dir);
t!(fs::create_dir_all(&dir));

let mut cmd = Command::new("tar");
cmd.arg("-xzf")
.arg(dist::rust_src_installer(build))
.arg("--strip-components=1")
.current_dir(&dir);
build.run(&mut cmd);

let toml = dir.join("rust-src/lib/rustlib/src/rust/src/libstd/Cargo.toml");
build.run(Command::new(&build.cargo)
.arg("generate-lockfile")
.arg("--manifest-path")
.arg(&toml)
.current_dir(&dir));
}

/// Test the build system itself
Expand Down
7 changes: 7 additions & 0 deletions src/bootstrap/dist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,11 +315,18 @@ pub fn std(build: &Build, compiler: &Compiler, target: &str) {
t!(fs::remove_dir_all(&image));
}

/// The path to the complete rustc-src tarball
pub fn rust_src_location(build: &Build) -> PathBuf {
let plain_name = format!("rustc-{}-src", build.rust_package_vers());
distdir(build).join(&format!("{}.tar.gz", plain_name))
}

/// The path to the rust-src component installer
pub fn rust_src_installer(build: &Build) -> PathBuf {
let name = pkgname(build, "rust-src");
distdir(build).join(&format!("{}.tar.gz", name))
}

/// Creates a tarball of save-analysis metadata, if available.
pub fn analysis(build: &Build, compiler: &Compiler, target: &str) {
assert!(build.config.extended);
Expand Down
18 changes: 18 additions & 0 deletions src/libcollections/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1604,6 +1604,15 @@ impl FromIterator<String> for String {
}
}

#[stable(feature = "herd_cows", since = "1.19.0")]
impl<'a> FromIterator<Cow<'a, str>> for String {
fn from_iter<I: IntoIterator<Item = Cow<'a, str>>>(iter: I) -> String {
let mut buf = String::new();
buf.extend(iter);
buf
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Extend<char> for String {
fn extend<I: IntoIterator<Item = char>>(&mut self, iter: I) {
Expand Down Expand Up @@ -1641,6 +1650,15 @@ impl Extend<String> for String {
}
}

#[stable(feature = "herd_cows", since = "1.19.0")]
impl<'a> Extend<Cow<'a, str>> for String {
fn extend<I: IntoIterator<Item = Cow<'a, str>>>(&mut self, iter: I) {
for s in iter {
self.push_str(&s)
}
}
}

/// A convenience impl that delegates to the impl for `&str`
#[unstable(feature = "pattern",
reason = "API not fully fleshed out and ready to be stabilized",
Expand Down
24 changes: 24 additions & 0 deletions src/libcore/benches/num/flt2dec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ mod strategy {
mod grisu;
}

use std::f64;
use std::io::Write;
use std::vec::Vec;
use test::Bencher;
use core::num::flt2dec::{decode, DecodableFloat, FullDecoded, Decoded};
use core::num::flt2dec::MAX_SIG_DIGITS;

Expand All @@ -22,3 +26,23 @@ pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
full_decoded => panic!("expected finite, got {:?} instead", full_decoded)
}
}

#[bench]
fn bench_small_shortest(b: &mut Bencher) {
let mut buf = Vec::with_capacity(20);

b.iter(|| {
buf.clear();
write!(&mut buf, "{}", 3.1415926f64).unwrap()
});
}

#[bench]
fn bench_big_shortest(b: &mut Bencher) {
let mut buf = Vec::with_capacity(300);

b.iter(|| {
buf.clear();
write!(&mut buf, "{}", f64::MAX).unwrap()
});
}
98 changes: 80 additions & 18 deletions src/libcore/fmt/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,43 @@
// except according to those terms.

use fmt::{Formatter, Result, LowerExp, UpperExp, Display, Debug};
use mem;
use num::flt2dec;

// Don't inline this so callers don't use the stack space this function
// requires unless they have to.
#[inline(never)]
fn float_to_decimal_common_exact<T>(fmt: &mut Formatter, num: &T,
sign: flt2dec::Sign, precision: usize) -> Result
where T: flt2dec::DecodableFloat
{
unsafe {
let mut buf: [u8; 1024] = mem::uninitialized(); // enough for f32 and f64
let mut parts: [flt2dec::Part; 5] = mem::uninitialized();
let formatted = flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact,
*num, sign, precision,
false, &mut buf, &mut parts);
fmt.pad_formatted_parts(&formatted)
}
}

// Don't inline this so callers that call both this and the above won't wind
// up using the combined stack space of both functions in some cases.
#[inline(never)]
fn float_to_decimal_common_shortest<T>(fmt: &mut Formatter,
num: &T, sign: flt2dec::Sign) -> Result
where T: flt2dec::DecodableFloat
{
unsafe {
// enough for f32 and f64
let mut buf: [u8; flt2dec::MAX_SIG_DIGITS] = mem::uninitialized();
let mut parts: [flt2dec::Part; 5] = mem::uninitialized();
let formatted = flt2dec::to_shortest_str(flt2dec::strategy::grisu::format_shortest,
*num, sign, 0, false, &mut buf, &mut parts);
fmt.pad_formatted_parts(&formatted)
}
}

// Common code of floating point Debug and Display.
fn float_to_decimal_common<T>(fmt: &mut Formatter, num: &T, negative_zero: bool) -> Result
where T: flt2dec::DecodableFloat
Expand All @@ -23,16 +58,48 @@ fn float_to_decimal_common<T>(fmt: &mut Formatter, num: &T, negative_zero: bool)
(true, true) => flt2dec::Sign::MinusPlusRaw,
};

let mut buf = [0; 1024]; // enough for f32 and f64
let mut parts = [flt2dec::Part::Zero(0); 16];
let formatted = if let Some(precision) = fmt.precision {
flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact, *num, sign,
precision, false, &mut buf, &mut parts)
if let Some(precision) = fmt.precision {
float_to_decimal_common_exact(fmt, num, sign, precision)
} else {
flt2dec::to_shortest_str(flt2dec::strategy::grisu::format_shortest, *num, sign,
0, false, &mut buf, &mut parts)
};
fmt.pad_formatted_parts(&formatted)
float_to_decimal_common_shortest(fmt, num, sign)
}
}

// Don't inline this so callers don't use the stack space this function
// requires unless they have to.
#[inline(never)]
fn float_to_exponential_common_exact<T>(fmt: &mut Formatter, num: &T,
sign: flt2dec::Sign, precision: usize,
upper: bool) -> Result
where T: flt2dec::DecodableFloat
{
unsafe {
let mut buf: [u8; 1024] = mem::uninitialized(); // enough for f32 and f64
let mut parts: [flt2dec::Part; 7] = mem::uninitialized();
let formatted = flt2dec::to_exact_exp_str(flt2dec::strategy::grisu::format_exact,
*num, sign, precision,
upper, &mut buf, &mut parts);
fmt.pad_formatted_parts(&formatted)
}
}

// Don't inline this so callers that call both this and the above won't wind
// up using the combined stack space of both functions in some cases.
#[inline(never)]
fn float_to_exponential_common_shortest<T>(fmt: &mut Formatter,
num: &T, sign: flt2dec::Sign,
upper: bool) -> Result
where T: flt2dec::DecodableFloat
{
unsafe {
// enough for f32 and f64
let mut buf: [u8; flt2dec::MAX_SIG_DIGITS] = mem::uninitialized();
let mut parts: [flt2dec::Part; 7] = mem::uninitialized();
let formatted = flt2dec::to_shortest_exp_str(flt2dec::strategy::grisu::format_shortest,
*num, sign, (0, 0), upper,
&mut buf, &mut parts);
fmt.pad_formatted_parts(&formatted)
}
}

// Common code of floating point LowerExp and UpperExp.
Expand All @@ -45,17 +112,12 @@ fn float_to_exponential_common<T>(fmt: &mut Formatter, num: &T, upper: bool) ->
true => flt2dec::Sign::MinusPlus,
};

let mut buf = [0; 1024]; // enough for f32 and f64
let mut parts = [flt2dec::Part::Zero(0); 16];
let formatted = if let Some(precision) = fmt.precision {
if let Some(precision) = fmt.precision {
// 1 integral digit + `precision` fractional digits = `precision + 1` total digits
flt2dec::to_exact_exp_str(flt2dec::strategy::grisu::format_exact, *num, sign,
precision + 1, upper, &mut buf, &mut parts)
float_to_exponential_common_exact(fmt, num, sign, precision + 1, upper)
} else {
flt2dec::to_shortest_exp_str(flt2dec::strategy::grisu::format_shortest, *num, sign,
(0, 0), upper, &mut buf, &mut parts)
};
fmt.pad_formatted_parts(&formatted)
float_to_exponential_common_shortest(fmt, num, sign, upper)
}
}

macro_rules! floating {
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub use intrinsics::transmute;
/// `forget` is not marked as `unsafe`, because Rust's safety guarantees
/// do not include a guarantee that destructors will always run. For example,
/// a program can create a reference cycle using [`Rc`][rc], or call
/// [`process:exit`][exit] to exit without running destructors. Thus, allowing
/// [`process::exit`][exit] to exit without running destructors. Thus, allowing
/// `mem::forget` from safe code does not fundamentally change Rust's safety
/// guarantees.
///
Expand Down
6 changes: 6 additions & 0 deletions src/librustc/middle/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,12 @@ fn has_allow_dead_code_or_lang_attr(attrs: &[ast::Attribute]) -> bool {
return true;
}

// #[used] also keeps the item alive forcefully,
// e.g. for placing it in a specific section.
if attr::contains_name(attrs, "used") {
return true;
}

let dead_code = lint::builtin::DEAD_CODE.name_lower();
for attr in lint::gather_attrs(attrs) {
match attr {
Expand Down
17 changes: 17 additions & 0 deletions src/test/run-pass/issue-41628.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![deny(dead_code)]
#![feature(used)]

#[used]
static FOO: u32 = 0;

fn main() {}