Skip to content

Commit 78f6318

Browse files
committed
Auto merge of #41643 - frewsxcv:rollup, r=frewsxcv
Rollup of 6 pull requests - Successful merges: #41449, #41509, #41608, #41613, #41636, #41637 - Failed merges:
2 parents ba5b911 + 43cb7c4 commit 78f6318

File tree

9 files changed

+430
-531
lines changed

9 files changed

+430
-531
lines changed

RELEASES.md

+256-512
Large diffs are not rendered by default.

src/bootstrap/check.rs

+21
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,7 @@ pub fn distcheck(build: &Build) {
577577
return
578578
}
579579

580+
println!("Distcheck");
580581
let dir = build.out.join("tmp").join("distcheck");
581582
let _ = fs::remove_dir_all(&dir);
582583
t!(fs::create_dir_all(&dir));
@@ -594,6 +595,26 @@ pub fn distcheck(build: &Build) {
594595
build.run(Command::new(build_helper::make(&build.config.build))
595596
.arg("check")
596597
.current_dir(&dir));
598+
599+
// Now make sure that rust-src has all of libstd's dependencies
600+
println!("Distcheck rust-src");
601+
let dir = build.out.join("tmp").join("distcheck-src");
602+
let _ = fs::remove_dir_all(&dir);
603+
t!(fs::create_dir_all(&dir));
604+
605+
let mut cmd = Command::new("tar");
606+
cmd.arg("-xzf")
607+
.arg(dist::rust_src_installer(build))
608+
.arg("--strip-components=1")
609+
.current_dir(&dir);
610+
build.run(&mut cmd);
611+
612+
let toml = dir.join("rust-src/lib/rustlib/src/rust/src/libstd/Cargo.toml");
613+
build.run(Command::new(&build.cargo)
614+
.arg("generate-lockfile")
615+
.arg("--manifest-path")
616+
.arg(&toml)
617+
.current_dir(&dir));
597618
}
598619

599620
/// Test the build system itself

src/bootstrap/dist.rs

+7
Original file line numberDiff line numberDiff line change
@@ -315,11 +315,18 @@ pub fn std(build: &Build, compiler: &Compiler, target: &str) {
315315
t!(fs::remove_dir_all(&image));
316316
}
317317

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

324+
/// The path to the rust-src component installer
325+
pub fn rust_src_installer(build: &Build) -> PathBuf {
326+
let name = pkgname(build, "rust-src");
327+
distdir(build).join(&format!("{}.tar.gz", name))
328+
}
329+
323330
/// Creates a tarball of save-analysis metadata, if available.
324331
pub fn analysis(build: &Build, compiler: &Compiler, target: &str) {
325332
assert!(build.config.extended);

src/libcollections/string.rs

+18
Original file line numberDiff line numberDiff line change
@@ -1604,6 +1604,15 @@ impl FromIterator<String> for String {
16041604
}
16051605
}
16061606

1607+
#[stable(feature = "herd_cows", since = "1.19.0")]
1608+
impl<'a> FromIterator<Cow<'a, str>> for String {
1609+
fn from_iter<I: IntoIterator<Item = Cow<'a, str>>>(iter: I) -> String {
1610+
let mut buf = String::new();
1611+
buf.extend(iter);
1612+
buf
1613+
}
1614+
}
1615+
16071616
#[stable(feature = "rust1", since = "1.0.0")]
16081617
impl Extend<char> for String {
16091618
fn extend<I: IntoIterator<Item = char>>(&mut self, iter: I) {
@@ -1641,6 +1650,15 @@ impl Extend<String> for String {
16411650
}
16421651
}
16431652

1653+
#[stable(feature = "herd_cows", since = "1.19.0")]
1654+
impl<'a> Extend<Cow<'a, str>> for String {
1655+
fn extend<I: IntoIterator<Item = Cow<'a, str>>>(&mut self, iter: I) {
1656+
for s in iter {
1657+
self.push_str(&s)
1658+
}
1659+
}
1660+
}
1661+
16441662
/// A convenience impl that delegates to the impl for `&str`
16451663
#[unstable(feature = "pattern",
16461664
reason = "API not fully fleshed out and ready to be stabilized",

src/libcore/benches/num/flt2dec/mod.rs

+24
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ mod strategy {
1313
mod grisu;
1414
}
1515

16+
use std::f64;
17+
use std::io::Write;
18+
use std::vec::Vec;
19+
use test::Bencher;
1620
use core::num::flt2dec::{decode, DecodableFloat, FullDecoded, Decoded};
1721
use core::num::flt2dec::MAX_SIG_DIGITS;
1822

@@ -22,3 +26,23 @@ pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
2226
full_decoded => panic!("expected finite, got {:?} instead", full_decoded)
2327
}
2428
}
29+
30+
#[bench]
31+
fn bench_small_shortest(b: &mut Bencher) {
32+
let mut buf = Vec::with_capacity(20);
33+
34+
b.iter(|| {
35+
buf.clear();
36+
write!(&mut buf, "{}", 3.1415926f64).unwrap()
37+
});
38+
}
39+
40+
#[bench]
41+
fn bench_big_shortest(b: &mut Bencher) {
42+
let mut buf = Vec::with_capacity(300);
43+
44+
b.iter(|| {
45+
buf.clear();
46+
write!(&mut buf, "{}", f64::MAX).unwrap()
47+
});
48+
}

src/libcore/fmt/float.rs

+80-18
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,43 @@
99
// except according to those terms.
1010

1111
use fmt::{Formatter, Result, LowerExp, UpperExp, Display, Debug};
12+
use mem;
1213
use num::flt2dec;
1314

15+
// Don't inline this so callers don't use the stack space this function
16+
// requires unless they have to.
17+
#[inline(never)]
18+
fn float_to_decimal_common_exact<T>(fmt: &mut Formatter, num: &T,
19+
sign: flt2dec::Sign, precision: usize) -> Result
20+
where T: flt2dec::DecodableFloat
21+
{
22+
unsafe {
23+
let mut buf: [u8; 1024] = mem::uninitialized(); // enough for f32 and f64
24+
let mut parts: [flt2dec::Part; 5] = mem::uninitialized();
25+
let formatted = flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact,
26+
*num, sign, precision,
27+
false, &mut buf, &mut parts);
28+
fmt.pad_formatted_parts(&formatted)
29+
}
30+
}
31+
32+
// Don't inline this so callers that call both this and the above won't wind
33+
// up using the combined stack space of both functions in some cases.
34+
#[inline(never)]
35+
fn float_to_decimal_common_shortest<T>(fmt: &mut Formatter,
36+
num: &T, sign: flt2dec::Sign) -> Result
37+
where T: flt2dec::DecodableFloat
38+
{
39+
unsafe {
40+
// enough for f32 and f64
41+
let mut buf: [u8; flt2dec::MAX_SIG_DIGITS] = mem::uninitialized();
42+
let mut parts: [flt2dec::Part; 5] = mem::uninitialized();
43+
let formatted = flt2dec::to_shortest_str(flt2dec::strategy::grisu::format_shortest,
44+
*num, sign, 0, false, &mut buf, &mut parts);
45+
fmt.pad_formatted_parts(&formatted)
46+
}
47+
}
48+
1449
// Common code of floating point Debug and Display.
1550
fn float_to_decimal_common<T>(fmt: &mut Formatter, num: &T, negative_zero: bool) -> Result
1651
where T: flt2dec::DecodableFloat
@@ -23,16 +58,48 @@ fn float_to_decimal_common<T>(fmt: &mut Formatter, num: &T, negative_zero: bool)
2358
(true, true) => flt2dec::Sign::MinusPlusRaw,
2459
};
2560

26-
let mut buf = [0; 1024]; // enough for f32 and f64
27-
let mut parts = [flt2dec::Part::Zero(0); 16];
28-
let formatted = if let Some(precision) = fmt.precision {
29-
flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact, *num, sign,
30-
precision, false, &mut buf, &mut parts)
61+
if let Some(precision) = fmt.precision {
62+
float_to_decimal_common_exact(fmt, num, sign, precision)
3163
} else {
32-
flt2dec::to_shortest_str(flt2dec::strategy::grisu::format_shortest, *num, sign,
33-
0, false, &mut buf, &mut parts)
34-
};
35-
fmt.pad_formatted_parts(&formatted)
64+
float_to_decimal_common_shortest(fmt, num, sign)
65+
}
66+
}
67+
68+
// Don't inline this so callers don't use the stack space this function
69+
// requires unless they have to.
70+
#[inline(never)]
71+
fn float_to_exponential_common_exact<T>(fmt: &mut Formatter, num: &T,
72+
sign: flt2dec::Sign, precision: usize,
73+
upper: bool) -> Result
74+
where T: flt2dec::DecodableFloat
75+
{
76+
unsafe {
77+
let mut buf: [u8; 1024] = mem::uninitialized(); // enough for f32 and f64
78+
let mut parts: [flt2dec::Part; 7] = mem::uninitialized();
79+
let formatted = flt2dec::to_exact_exp_str(flt2dec::strategy::grisu::format_exact,
80+
*num, sign, precision,
81+
upper, &mut buf, &mut parts);
82+
fmt.pad_formatted_parts(&formatted)
83+
}
84+
}
85+
86+
// Don't inline this so callers that call both this and the above won't wind
87+
// up using the combined stack space of both functions in some cases.
88+
#[inline(never)]
89+
fn float_to_exponential_common_shortest<T>(fmt: &mut Formatter,
90+
num: &T, sign: flt2dec::Sign,
91+
upper: bool) -> Result
92+
where T: flt2dec::DecodableFloat
93+
{
94+
unsafe {
95+
// enough for f32 and f64
96+
let mut buf: [u8; flt2dec::MAX_SIG_DIGITS] = mem::uninitialized();
97+
let mut parts: [flt2dec::Part; 7] = mem::uninitialized();
98+
let formatted = flt2dec::to_shortest_exp_str(flt2dec::strategy::grisu::format_shortest,
99+
*num, sign, (0, 0), upper,
100+
&mut buf, &mut parts);
101+
fmt.pad_formatted_parts(&formatted)
102+
}
36103
}
37104

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

48-
let mut buf = [0; 1024]; // enough for f32 and f64
49-
let mut parts = [flt2dec::Part::Zero(0); 16];
50-
let formatted = if let Some(precision) = fmt.precision {
115+
if let Some(precision) = fmt.precision {
51116
// 1 integral digit + `precision` fractional digits = `precision + 1` total digits
52-
flt2dec::to_exact_exp_str(flt2dec::strategy::grisu::format_exact, *num, sign,
53-
precision + 1, upper, &mut buf, &mut parts)
117+
float_to_exponential_common_exact(fmt, num, sign, precision + 1, upper)
54118
} else {
55-
flt2dec::to_shortest_exp_str(flt2dec::strategy::grisu::format_shortest, *num, sign,
56-
(0, 0), upper, &mut buf, &mut parts)
57-
};
58-
fmt.pad_formatted_parts(&formatted)
119+
float_to_exponential_common_shortest(fmt, num, sign, upper)
120+
}
59121
}
60122

61123
macro_rules! floating {

src/libcore/mem.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub use intrinsics::transmute;
4040
/// `forget` is not marked as `unsafe`, because Rust's safety guarantees
4141
/// do not include a guarantee that destructors will always run. For example,
4242
/// a program can create a reference cycle using [`Rc`][rc], or call
43-
/// [`process:exit`][exit] to exit without running destructors. Thus, allowing
43+
/// [`process::exit`][exit] to exit without running destructors. Thus, allowing
4444
/// `mem::forget` from safe code does not fundamentally change Rust's safety
4545
/// guarantees.
4646
///

src/librustc/middle/dead.rs

+6
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,12 @@ fn has_allow_dead_code_or_lang_attr(attrs: &[ast::Attribute]) -> bool {
283283
return true;
284284
}
285285

286+
// #[used] also keeps the item alive forcefully,
287+
// e.g. for placing it in a specific section.
288+
if attr::contains_name(attrs, "used") {
289+
return true;
290+
}
291+
286292
let dead_code = lint::builtin::DEAD_CODE.name_lower();
287293
for attr in lint::gather_attrs(attrs) {
288294
match attr {

src/test/run-pass/issue-41628.rs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![deny(dead_code)]
12+
#![feature(used)]
13+
14+
#[used]
15+
static FOO: u32 = 0;
16+
17+
fn main() {}

0 commit comments

Comments
 (0)