Skip to content

Commit c9d3749

Browse files
committed
Auto merge of #40080 - frewsxcv:rollup, r=frewsxcv
Rollup of 17 pull requests - Successful merges: #39777, #39815, #39845, #39886, #39892, #39903, #39905, #39914, #39927, #39940, #40010, #40030, #40048, #40050, #40052, #40060, #40071 - Failed merges:
2 parents 0823077 + c7a78c7 commit c9d3749

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+573
-384
lines changed

Diff for: src/bootstrap/bootstrap.py

+19-4
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,33 @@ def delete_if_present(path, verbose):
5959

6060

6161
def download(path, url, probably_big, verbose):
62+
for x in range(0, 4):
63+
try:
64+
_download(path, url, probably_big, verbose, True)
65+
return
66+
except RuntimeError:
67+
print("\nspurious failure, trying again")
68+
_download(path, url, probably_big, verbose, False)
69+
70+
71+
def _download(path, url, probably_big, verbose, exception):
6272
if probably_big or verbose:
6373
print("downloading {}".format(url))
6474
# see http://serverfault.com/questions/301128/how-to-download
6575
if sys.platform == 'win32':
6676
run(["PowerShell.exe", "/nologo", "-Command",
6777
"(New-Object System.Net.WebClient)"
6878
".DownloadFile('{}', '{}')".format(url, path)],
69-
verbose=verbose)
79+
verbose=verbose,
80+
exception=exception)
7081
else:
7182
if probably_big or verbose:
7283
option = "-#"
7384
else:
7485
option = "-s"
75-
run(["curl", option, "--retry", "3", "-Sf", "-o", path, url], verbose=verbose)
86+
run(["curl", option, "--retry", "3", "-Sf", "-o", path, url],
87+
verbose=verbose,
88+
exception=exception)
7689

7790

7891
def verify(path, sha_path, verbose):
@@ -112,7 +125,7 @@ def unpack(tarball, dst, verbose=False, match=None):
112125
shutil.move(tp, fp)
113126
shutil.rmtree(os.path.join(dst, fname))
114127

115-
def run(args, verbose=False):
128+
def run(args, verbose=False, exception=False):
116129
if verbose:
117130
print("running: " + ' '.join(args))
118131
sys.stdout.flush()
@@ -122,7 +135,7 @@ def run(args, verbose=False):
122135
code = ret.wait()
123136
if code != 0:
124137
err = "failed to run: " + ' '.join(args)
125-
if verbose:
138+
if verbose or exception:
126139
raise RuntimeError(err)
127140
sys.exit(err)
128141

@@ -472,6 +485,8 @@ def build_triple(self):
472485
ostype += 'abi64'
473486
elif cputype in {'powerpc', 'ppc', 'ppc64'}:
474487
cputype = 'powerpc'
488+
elif cputype == 'sparcv9':
489+
pass
475490
elif cputype in {'amd64', 'x86_64', 'x86-64', 'x64'}:
476491
cputype = 'x86_64'
477492
else:

Diff for: src/doc/book/src/procedural-macros.md

+74-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ a representation of our type (which can be either a `struct` or an `enum`).
170170
Check out the [docs](https://docs.rs/syn/0.10.5/syn/struct.MacroInput.html),
171171
there is some useful information there. We are able to get the name of the
172172
type using `ast.ident`. The `quote!` macro lets us write up the Rust code
173-
that we wish to return and convert it into `Tokens`. `quote!` let's us use some
173+
that we wish to return and convert it into `Tokens`. `quote!` lets us use some
174174
really cool templating mechanics; we simply write `#name` and `quote!` will
175175
replace it with the variable named `name`. You can even do some repetition
176176
similar to regular macros work. You should check out the
@@ -211,3 +211,76 @@ Hello, World! My name is Waffles
211211
```
212212

213213
We've done it!
214+
215+
## Custom Attributes
216+
217+
In some cases it might make sense to allow users some kind of configuration.
218+
For example, the user might want to overwrite the name that is printed in the `hello_world()` method.
219+
220+
This can be achieved with custom attributes:
221+
222+
```rust,ignore
223+
#[derive(HelloWorld)]
224+
#[HelloWorldName = "the best Pancakes"]
225+
struct Pancakes;
226+
227+
fn main() {
228+
Pancakes::hello_world();
229+
}
230+
```
231+
232+
If we try to compile this though, the compiler will respond with an error:
233+
234+
```bash
235+
error: The attribute `HelloWorldName` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
236+
```
237+
238+
The compiler needs to know that we're handling this attribute and to not respond with an error.
239+
This is done in the `hello-world-derive` crate by adding `attributes` to the `proc_macro_derive` attribute:
240+
241+
```rust,ignore
242+
#[proc_macro_derive(HelloWorld, attributes(HelloWorldName))]
243+
pub fn hello_world(input: TokenStream) -> TokenStream
244+
```
245+
246+
Multiple attributes can be specified that way.
247+
248+
## Raising Errors
249+
250+
Let's assume that we do not want to accept enums as input to our custom derive method.
251+
252+
This condition can be easily checked with the help of `syn`.
253+
But how do we tell the user, that we do not accept enums?
254+
The idiomatic way to report errors in procedural macros is to panic:
255+
256+
```rust,ignore
257+
fn impl_hello_world(ast: &syn::MacroInput) -> quote::Tokens {
258+
let name = &ast.ident;
259+
// Check if derive(HelloWorld) was specified for a struct
260+
if let syn::Body::Struct(_) = ast.body {
261+
// Yes, this is a struct
262+
quote! {
263+
impl HelloWorld for #name {
264+
fn hello_world() {
265+
println!("Hello, World! My name is {}", stringify!(#name));
266+
}
267+
}
268+
}
269+
} else {
270+
//Nope. This is an Enum. We cannot handle these!
271+
panic!("#[derive(HelloWorld)] is only defined for structs, not for enums!");
272+
}
273+
}
274+
```
275+
276+
If a user now tries to derive `HelloWorld` from an enum they will be greeted with following, hopefully helpful, error:
277+
278+
```bash
279+
error: custom derive attribute panicked
280+
--> src/main.rs
281+
|
282+
| #[derive(HelloWorld)]
283+
| ^^^^^^^^^^
284+
|
285+
= help: message: #[derive(HelloWorld)] is only defined for structs, not for enums!
286+
```

Diff for: src/doc/book/src/the-stack-and-the-heap.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ to a large number, representing how much RAM your computer has. For example, if
8686
you have a gigabyte of RAM, your addresses go from `0` to `1,073,741,823`. That
8787
number comes from 2<sup>30</sup>, the number of bytes in a gigabyte. [^gigabyte]
8888

89-
[^gigabyte]: ‘Gigabyte’ can mean two things: 10^9, or 2^30. The SI standard resolved this by stating that ‘gigabyte’ is 10^9, and ‘gibibyte’ is 2^30. However, very few people use this terminology, and rely on context to differentiate. We follow in that tradition here.
89+
[^gigabyte]: ‘Gigabyte’ can mean two things: 10<sup>9</sup>, or 2<sup>30</sup>. The IEC standard resolved this by stating that ‘gigabyte’ is 10<sup>9</sup>, and ‘gibibyte’ is 2<sup>30</sup>. However, very few people use this terminology, and rely on context to differentiate. We follow in that tradition here.
9090

9191
This memory is kind of like a giant array: addresses start at zero and go
9292
up to the final number. So here’s a diagram of our first stack frame:

Diff for: src/doc/nomicon/src/exception-safety.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ uselessly. We would rather have the following:
9393
```text
9494
bubble_up(heap, index):
9595
let elem = heap[index]
96-
while index != 0 && element < heap[parent(index)]:
96+
while index != 0 && elem < heap[parent(index)]:
9797
heap[index] = heap[parent(index)]
9898
index = parent(index)
9999
heap[index] = elem
@@ -137,7 +137,7 @@ If Rust had `try` and `finally` like in Java, we could do the following:
137137
bubble_up(heap, index):
138138
let elem = heap[index]
139139
try:
140-
while index != 0 && element < heap[parent(index)]:
140+
       while index != 0 && elem < heap[parent(index)]:
141141
heap[index] = heap[parent(index)]
142142
index = parent(index)
143143
finally:

Diff for: src/libcollections/fmt.rs

+4-21
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
//!
6363
//! A format string is required to use all of its arguments, otherwise it is a
6464
//! compile-time error. You may refer to the same argument more than once in the
65-
//! format string, although it must always be referred to with the same type.
65+
//! format string.
6666
//!
6767
//! ## Named parameters
6868
//!
@@ -89,19 +89,8 @@
8989
//!
9090
//! ## Argument types
9191
//!
92-
//! Each argument's type is dictated by the format string. It is a requirement
93-
//! that every argument is only ever referred to by one type. For example, this
94-
//! is an invalid format string:
95-
//!
96-
//! ```text
97-
//! {0:x} {0:o}
98-
//! ```
99-
//!
100-
//! This is invalid because the first argument is both referred to as a
101-
//! hexadecimal as well as an
102-
//! octal.
103-
//!
104-
//! There are various parameters which do require a particular type, however.
92+
//! Each argument's type is dictated by the format string.
93+
//! There are various parameters which require a particular type, however.
10594
//! An example is the `{:.*}` syntax, which sets the number of decimal places
10695
//! in floating-point types:
10796
//!
@@ -113,13 +102,7 @@
113102
//!
114103
//! If this syntax is used, then the number of characters to print precedes the
115104
//! actual object being formatted, and the number of characters must have the
116-
//! type `usize`. Although a `usize` can be printed with `{}`, it is invalid to
117-
//! reference an argument as such. For example this is another invalid format
118-
//! string:
119-
//!
120-
//! ```text
121-
//! {:.*} {0}
122-
//! ```
105+
//! type `usize`.
123106
//!
124107
//! ## Formatting traits
125108
//!

Diff for: src/libcollections/string.rs

+42
Original file line numberDiff line numberDiff line change
@@ -1629,6 +1629,43 @@ impl hash::Hash for String {
16291629
}
16301630
}
16311631

1632+
/// Implements the `+` operator for concatenating two strings.
1633+
///
1634+
/// This consumes the `String` on the left-hand side and re-uses its buffer (growing it if
1635+
/// necessary). This is done to avoid allocating a new `String` and copying the entire contents on
1636+
/// every operation, which would lead to `O(n^2)` running time when building an `n`-byte string by
1637+
/// repeated concatenation.
1638+
///
1639+
/// The string on the right-hand side is only borrowed; its contents are copied into the returned
1640+
/// `String`.
1641+
///
1642+
/// # Examples
1643+
///
1644+
/// Concatenating two `String`s takes the first by value and borrows the second:
1645+
///
1646+
/// ```
1647+
/// let a = String::from("hello");
1648+
/// let b = String::from(" world");
1649+
/// let c = a + &b;
1650+
/// // `a` is moved and can no longer be used here.
1651+
/// ```
1652+
///
1653+
/// If you want to keep using the first `String`, you can clone it and append to the clone instead:
1654+
///
1655+
/// ```
1656+
/// let a = String::from("hello");
1657+
/// let b = String::from(" world");
1658+
/// let c = a.clone() + &b;
1659+
/// // `a` is still valid here.
1660+
/// ```
1661+
///
1662+
/// Concatenating `&str` slices can be done by converting the first to a `String`:
1663+
///
1664+
/// ```
1665+
/// let a = "hello";
1666+
/// let b = " world";
1667+
/// let c = a.to_string() + b;
1668+
/// ```
16321669
#[stable(feature = "rust1", since = "1.0.0")]
16331670
impl<'a> Add<&'a str> for String {
16341671
type Output = String;
@@ -1640,6 +1677,11 @@ impl<'a> Add<&'a str> for String {
16401677
}
16411678
}
16421679

1680+
/// Implements the `+=` operator for appending to a `String`.
1681+
///
1682+
/// This has the same behavior as the [`push_str()`] method.
1683+
///
1684+
/// [`push_str()`]: struct.String.html#method.push_str
16431685
#[stable(feature = "stringaddassign", since = "1.12.0")]
16441686
impl<'a> AddAssign<&'a str> for String {
16451687
#[inline]

Diff for: src/libcollections/vec.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1776,6 +1776,7 @@ array_impls! {
17761776
30 31 32
17771777
}
17781778

1779+
/// Implements comparison of vectors, lexicographically.
17791780
#[stable(feature = "rust1", since = "1.0.0")]
17801781
impl<T: PartialOrd> PartialOrd for Vec<T> {
17811782
#[inline]
@@ -1787,6 +1788,7 @@ impl<T: PartialOrd> PartialOrd for Vec<T> {
17871788
#[stable(feature = "rust1", since = "1.0.0")]
17881789
impl<T: Eq> Eq for Vec<T> {}
17891790

1791+
/// Implements ordering of vectors, lexicographically.
17901792
#[stable(feature = "rust1", since = "1.0.0")]
17911793
impl<T: Ord> Ord for Vec<T> {
17921794
#[inline]

Diff for: src/libcompiler_builtins/build.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,15 @@ fn main() {
9292
// compiler-rt's build system already
9393
cfg.flag("-fno-builtin");
9494
cfg.flag("-fvisibility=hidden");
95-
cfg.flag("-fomit-frame-pointer");
95+
// Accepted practice on Solaris is to never omit frame pointer so that
96+
// system observability tools work as expected. In addition, at least
97+
// on Solaris, -fomit-frame-pointer on sparcv9 appears to generate
98+
// references to data outside of the current stack frame. A search of
99+
// the gcc bug database provides a variety of issues surrounding
100+
// -fomit-frame-pointer on non-x86 platforms.
101+
if !target.contains("solaris") && !target.contains("sparc") {
102+
cfg.flag("-fomit-frame-pointer");
103+
}
96104
cfg.flag("-ffreestanding");
97105
cfg.define("VISIBILITY_HIDDEN", None);
98106
}

Diff for: src/libcore/slice.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2202,13 +2202,15 @@ impl<A, B> PartialEq<[B]> for [A] where A: PartialEq<B> {
22022202
#[stable(feature = "rust1", since = "1.0.0")]
22032203
impl<T: Eq> Eq for [T] {}
22042204

2205+
/// Implements comparison of vectors lexicographically.
22052206
#[stable(feature = "rust1", since = "1.0.0")]
22062207
impl<T: Ord> Ord for [T] {
22072208
fn cmp(&self, other: &[T]) -> Ordering {
22082209
SliceOrd::compare(self, other)
22092210
}
22102211
}
22112212

2213+
/// Implements comparison of vectors lexicographically.
22122214
#[stable(feature = "rust1", since = "1.0.0")]
22132215
impl<T: PartialOrd> PartialOrd for [T] {
22142216
fn partial_cmp(&self, other: &[T]) -> Option<Ordering> {

Diff for: src/libcore/str/mod.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1366,6 +1366,13 @@ mod traits {
13661366
use ops;
13671367
use str::eq_slice;
13681368

1369+
/// Implements ordering of strings.
1370+
///
1371+
/// Strings are ordered lexicographically by their byte values. This orders Unicode code
1372+
/// points based on their positions in the code charts. This is not necessarily the same as
1373+
/// "alphabetical" order, which varies by language and locale. Sorting strings according to
1374+
/// culturally-accepted standards requires locale-specific data that is outside the scope of
1375+
/// the `str` type.
13691376
#[stable(feature = "rust1", since = "1.0.0")]
13701377
impl Ord for str {
13711378
#[inline]
@@ -1387,6 +1394,13 @@ mod traits {
13871394
#[stable(feature = "rust1", since = "1.0.0")]
13881395
impl Eq for str {}
13891396

1397+
/// Implements comparison operations on strings.
1398+
///
1399+
/// Strings are compared lexicographically by their byte values. This compares Unicode code
1400+
/// points based on their positions in the code charts. This is not necessarily the same as
1401+
/// "alphabetical" order, which varies by language and locale. Comparing strings according to
1402+
/// culturally-accepted standards requires locale-specific data that is outside the scope of
1403+
/// the `str` type.
13901404
#[stable(feature = "rust1", since = "1.0.0")]
13911405
impl PartialOrd for str {
13921406
#[inline]

Diff for: src/librustc/cfg/construct.rs

+6-14
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ struct LoopScope {
3232
}
3333

3434
pub fn construct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
35-
body: &hir::Expr) -> CFG {
35+
body: &hir::Body) -> CFG {
3636
let mut graph = graph::Graph::new();
3737
let entry = graph.add_node(CFGNodeData::Entry);
3838

@@ -43,26 +43,18 @@ pub fn construct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
4343
let fn_exit = graph.add_node(CFGNodeData::Exit);
4444
let body_exit;
4545

46-
// Find the function this expression is from.
47-
let mut node_id = body.id;
48-
loop {
49-
let node = tcx.hir.get(node_id);
50-
if hir::map::blocks::FnLikeNode::from_node(node).is_some() {
51-
break;
52-
}
53-
let parent = tcx.hir.get_parent_node(node_id);
54-
assert!(node_id != parent);
55-
node_id = parent;
56-
}
46+
// Find the tables for this body.
47+
let owner_def_id = tcx.hir.local_def_id(tcx.hir.body_owner(body.id()));
48+
let tables = tcx.item_tables(owner_def_id);
5749

5850
let mut cfg_builder = CFGBuilder {
5951
tcx: tcx,
60-
tables: tcx.item_tables(tcx.hir.local_def_id(node_id)),
52+
tables: tables,
6153
graph: graph,
6254
fn_exit: fn_exit,
6355
loop_scopes: Vec::new()
6456
};
65-
body_exit = cfg_builder.expr(body, entry);
57+
body_exit = cfg_builder.expr(&body.value, entry);
6658
cfg_builder.add_contained_edge(body_exit, fn_exit);
6759
let CFGBuilder {graph, ..} = cfg_builder;
6860
CFG {graph: graph,

0 commit comments

Comments
 (0)