Skip to content

Commit 7932349

Browse files
committed
Auto merge of #40072 - GuillaumeGomez:rollup, r=GuillaumeGomez
Rollup of 11 pull requests - Successful merges: #39777, #39815, #39845, #39886, #39940, #40010, #40030, #40048, #40050, #40052, #40071 - Failed merges:
2 parents 0823077 + f26bbb3 commit 7932349

File tree

13 files changed

+223
-40
lines changed

13 files changed

+223
-40
lines changed

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+
```

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:

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:

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
//!

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]

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]

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> {

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]

src/librustc/ty/inhabitedness/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
187187
// which contains a Foo<((T, T), (T, T))>
188188
// which contains a Foo<(((T, T), (T, T)), ((T, T), (T, T)))>
189189
// etc.
190-
let error = format!("reached recursion limit while checking
190+
let error = format!("reached recursion limit while checking \
191191
inhabitedness of `{}`", self);
192192
tcx.sess.fatal(&error);
193193
}

src/libstd/sync/barrier.rs

+69-7
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ use sync::{Mutex, Condvar};
1414
/// A barrier enables multiple threads to synchronize the beginning
1515
/// of some computation.
1616
///
17+
/// # Examples
18+
///
1719
/// ```
1820
/// use std::sync::{Arc, Barrier};
1921
/// use std::thread;
@@ -50,8 +52,19 @@ struct BarrierState {
5052

5153
/// A result returned from wait.
5254
///
53-
/// Currently this opaque structure only has one method, `.is_leader()`. Only
55+
/// Currently this opaque structure only has one method, [`.is_leader()`]. Only
5456
/// one thread will receive a result that will return `true` from this function.
57+
///
58+
/// [`.is_leader()`]: #method.is_leader
59+
///
60+
/// # Examples
61+
///
62+
/// ```
63+
/// use std::sync::Barrier;
64+
///
65+
/// let barrier = Barrier::new(1);
66+
/// let barrier_wait_result = barrier.wait();
67+
/// ```
5568
#[stable(feature = "rust1", since = "1.0.0")]
5669
pub struct BarrierWaitResult(bool);
5770

@@ -65,8 +78,18 @@ impl fmt::Debug for Barrier {
6578
impl Barrier {
6679
/// Creates a new barrier that can block a given number of threads.
6780
///
68-
/// A barrier will block `n`-1 threads which call `wait` and then wake up
69-
/// all threads at once when the `n`th thread calls `wait`.
81+
/// A barrier will block `n`-1 threads which call [`wait`] and then wake up
82+
/// all threads at once when the `n`th thread calls [`wait`].
83+
///
84+
/// [`wait`]: #method.wait
85+
///
86+
/// # Examples
87+
///
88+
/// ```
89+
/// use std::sync::Barrier;
90+
///
91+
/// let barrier = Barrier::new(10);
92+
/// ```
7093
#[stable(feature = "rust1", since = "1.0.0")]
7194
pub fn new(n: usize) -> Barrier {
7295
Barrier {
@@ -84,10 +107,37 @@ impl Barrier {
84107
/// Barriers are re-usable after all threads have rendezvoused once, and can
85108
/// be used continuously.
86109
///
87-
/// A single (arbitrary) thread will receive a `BarrierWaitResult` that
88-
/// returns `true` from `is_leader` when returning from this function, and
110+
/// A single (arbitrary) thread will receive a [`BarrierWaitResult`] that
111+
/// returns `true` from [`is_leader`] when returning from this function, and
89112
/// all other threads will receive a result that will return `false` from
90-
/// `is_leader`
113+
/// [`is_leader`].
114+
///
115+
/// [`BarrierWaitResult`]: struct.BarrierWaitResult.html
116+
/// [`is_leader`]: struct.BarrierWaitResult.html#method.is_leader
117+
///
118+
/// # Examples
119+
///
120+
/// ```
121+
/// use std::sync::{Arc, Barrier};
122+
/// use std::thread;
123+
///
124+
/// let mut handles = Vec::with_capacity(10);
125+
/// let barrier = Arc::new(Barrier::new(10));
126+
/// for _ in 0..10 {
127+
/// let c = barrier.clone();
128+
/// // The same messages will be printed together.
129+
/// // You will NOT see any interleaving.
130+
/// handles.push(thread::spawn(move|| {
131+
/// println!("before wait");
132+
/// c.wait();
133+
/// println!("after wait");
134+
/// }));
135+
/// }
136+
/// // Wait for other threads to finish.
137+
/// for handle in handles {
138+
/// handle.join().unwrap();
139+
/// }
140+
/// ```
91141
#[stable(feature = "rust1", since = "1.0.0")]
92142
pub fn wait(&self) -> BarrierWaitResult {
93143
let mut lock = self.lock.lock().unwrap();
@@ -120,10 +170,22 @@ impl fmt::Debug for BarrierWaitResult {
120170
}
121171

122172
impl BarrierWaitResult {
123-
/// Returns whether this thread from `wait` is the "leader thread".
173+
/// Returns whether this thread from [`wait`] is the "leader thread".
124174
///
125175
/// Only one thread will have `true` returned from their result, all other
126176
/// threads will have `false` returned.
177+
///
178+
/// [`wait`]: struct.Barrier.html#method.wait
179+
///
180+
/// # Examples
181+
///
182+
/// ```
183+
/// use std::sync::Barrier;
184+
///
185+
/// let barrier = Barrier::new(1);
186+
/// let barrier_wait_result = barrier.wait();
187+
/// println!("{:?}", barrier_wait_result.is_leader());
188+
/// ```
127189
#[stable(feature = "rust1", since = "1.0.0")]
128190
pub fn is_leader(&self) -> bool { self.0 }
129191
}

0 commit comments

Comments
 (0)