Skip to content

Commit 75af15e

Browse files
committed
Auto merge of #49190 - kennytm:rollup, r=kennytm
Rollup of 17 pull requests - Successful merges: #46518, #48810, #48834, #48902, #49004, #49092, #49096, #49099, #49104, #49125, #49139, #49152, #49157, #49161, #49166, #49176, #49184 - Failed merges:
2 parents b991723 + 57b8211 commit 75af15e

Some content is hidden

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

48 files changed

+1029
-649
lines changed

config.toml.example

-5
Original file line numberDiff line numberDiff line change
@@ -243,11 +243,6 @@
243243
# compiler.
244244
#codegen-units = 1
245245

246-
# Whether to enable ThinLTO (and increase the codegen units to either a default
247-
# or the configured value). On by default. If we want the fastest possible
248-
# compiler, we should disable this.
249-
#thinlto = true
250-
251246
# Whether or not debug assertions are enabled for the compiler and standard
252247
# library. Also enables compilation of debug! and trace! logging macros.
253248
#debug-assertions = false

src/Cargo.lock

+47-92
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/bootstrap/dist.rs

+1
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ fn make_win_dist(
221221
"libsecur32.a",
222222
"libsetupapi.a",
223223
"libshell32.a",
224+
"libsynchronization.a",
224225
"libuser32.a",
225226
"libuserenv.a",
226227
"libuuid.a",

src/liballoc/fmt.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@
114114
//! * *nothing* ⇒ [`Display`]
115115
//! * `?` ⇒ [`Debug`]
116116
//! * `x?` ⇒ [`Debug`] with lower-case hexadecimal integers
117-
//! * `X?` ⇒ [`Debug`] with lower-case hexadecimal integers
117+
//! * `X?` ⇒ [`Debug`] with upper-case hexadecimal integers
118118
//! * `o` ⇒ [`Octal`](trait.Octal.html)
119119
//! * `x` ⇒ [`LowerHex`](trait.LowerHex.html)
120120
//! * `X` ⇒ [`UpperHex`](trait.UpperHex.html)

src/libcore/borrow.rs

+149-15
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,154 @@
1414

1515
/// A trait for borrowing data.
1616
///
17-
/// In general, there may be several ways to "borrow" a piece of data. The
18-
/// typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T`
19-
/// (a mutable borrow). But types like `Vec<T>` provide additional kinds of
20-
/// borrows: the borrowed slices `&[T]` and `&mut [T]`.
17+
/// In Rust, it is common to provide different representations of a type for
18+
/// different use cases. For instance, storage location and management for a
19+
/// value can be specifically chosen as appropriate for a particular use via
20+
/// pointer types such as [`Box<T>`] or [`Rc<T>`]. Beyond these generic
21+
/// wrappers that can be used with any type, some types provide optional
22+
/// facets providing potentially costly functionality. An example for such a
23+
/// type is [`String`] which adds the ability to extend a string to the basic
24+
/// [`str`]. This requires keeping additional information unnecessary for a
25+
/// simple, immutable string.
2126
///
22-
/// When writing generic code, it is often desirable to abstract over all ways
23-
/// of borrowing data from a given type. That is the role of the `Borrow`
24-
/// trait: if `T: Borrow<U>`, then `&U` can be borrowed from `&T`. A given
25-
/// type can be borrowed as multiple different types. In particular, `Vec<T>:
26-
/// Borrow<Vec<T>>` and `Vec<T>: Borrow<[T]>`.
27+
/// These types provide access to the underlying data through references
28+
/// to the type of that data. They are said to be ‘borrowed as’ that type.
29+
/// For instance, a [`Box<T>`] can be borrowed as `T` while a [`String`]
30+
/// can be borrowed as `str`.
2731
///
28-
/// If you are implementing `Borrow` and both `Self` and `Borrowed` implement
29-
/// `Hash`, `Eq`, and/or `Ord`, they must produce the same result.
32+
/// Types express that they can be borrowed as some type `T` by implementing
33+
/// `Borrow<T>`, providing a reference to a `T` in the trait’s
34+
/// [`borrow`] method. A type is free to borrow as several different types.
35+
/// If it wishes to mutably borrow as the type – allowing the underlying data
36+
/// to be modified, it can additionally implement [`BorrowMut<T>`].
3037
///
31-
/// `Borrow` is very similar to, but different than, `AsRef`. See
32-
/// [the book][book] for more.
38+
/// Further, when providing implementations for additional traits, it needs
39+
/// to be considered whether they should behave identical to those of the
40+
/// underlying type as a consequence of acting as a representation of that
41+
/// underlying type. Generic code typically uses `Borrow<T>` when it relies
42+
/// on the identical behavior of these additional trait implementations.
43+
/// These traits will likely appear as additional trait bounds.
3344
///
34-
/// [book]: ../../book/first-edition/borrow-and-asref.html
45+
/// If generic code merely needs to work for all types that can
46+
/// provide a reference to related type `T`, it is often better to use
47+
/// [`AsRef<T>`] as more types can safely implement it.
48+
///
49+
/// [`AsRef<T>`]: ../../std/convert/trait.AsRef.html
50+
/// [`BorrowMut<T>`]: trait.BorrowMut.html
51+
/// [`Box<T>`]: ../../std/boxed/struct.Box.html
52+
/// [`Mutex<T>`]: ../../std/sync/struct.Mutex.html
53+
/// [`Rc<T>`]: ../../std/rc/struct.Rc.html
54+
/// [`str`]: ../../std/primitive.str.html
55+
/// [`String`]: ../../std/string/struct.String.html
56+
/// [`borrow`]: #tymethod.borrow
57+
///
58+
/// # Examples
59+
///
60+
/// As a data collection, [`HashMap<K, V>`] owns both keys and values. If
61+
/// the key’s actual data is wrapped in a managing type of some kind, it
62+
/// should, however, still be possible to search for a value using a
63+
/// reference to the key’s data. For instance, if the key is a string, then
64+
/// it is likely stored with the hash map as a [`String`], while it should
65+
/// be possible to search using a [`&str`][`str`]. Thus, `insert` needs to
66+
/// operate on a `String` while `get` needs to be able to use a `&str`.
67+
///
68+
/// Slightly simplified, the relevant parts of `HashMap<K, V>` look like
69+
/// this:
70+
///
71+
/// ```
72+
/// use std::borrow::Borrow;
73+
/// use std::hash::Hash;
74+
///
75+
/// pub struct HashMap<K, V> {
76+
/// # marker: ::std::marker::PhantomData<(K, V)>,
77+
/// // fields omitted
78+
/// }
79+
///
80+
/// impl<K, V> HashMap<K, V> {
81+
/// pub fn insert(&self, key: K, value: V) -> Option<V>
82+
/// where K: Hash + Eq
83+
/// {
84+
/// # unimplemented!()
85+
/// // ...
86+
/// }
87+
///
88+
/// pub fn get<Q>(&self, k: &Q) -> Option<&V>
89+
/// where
90+
/// K: Borrow<Q>,
91+
/// Q: Hash + Eq + ?Sized
92+
/// {
93+
/// # unimplemented!()
94+
/// // ...
95+
/// }
96+
/// }
97+
/// ```
98+
///
99+
/// The entire hash map is generic over a key type `K`. Because these keys
100+
/// are stored with the hash map, this type has to own the key’s data.
101+
/// When inserting a key-value pair, the map is given such a `K` and needs
102+
/// to find the correct hash bucket and check if the key is already present
103+
/// based on that `K`. It therefore requires `K: Hash + Eq`.
104+
///
105+
/// When searching for a value in the map, however, having to provide a
106+
/// reference to a `K` as the key to search for would require to always
107+
/// create such an owned value. For string keys, this would mean a `String`
108+
/// value needs to be created just for the search for cases where only a
109+
/// `str` is available.
110+
///
111+
/// Instead, the `get` method is generic over the type of the underlying key
112+
/// data, called `Q` in the method signature above. It states that `K`
113+
/// borrows as a `Q` by requiring that `K: Borrow<Q>`. By additionally
114+
/// requiring `Q: Hash + Eq`, it signals the requirement that `K` and `Q`
115+
/// have implementations of the `Hash` and `Eq` traits that produce identical
116+
/// results.
117+
///
118+
/// The implementation of `get` relies in particular on identical
119+
/// implementations of `Hash` by determining the key’s hash bucket by calling
120+
/// `Hash::hash` on the `Q` value even though it inserted the key based on
121+
/// the hash value calculated from the `K` value.
122+
///
123+
/// As a consequence, the hash map breaks if a `K` wrapping a `Q` value
124+
/// produces a different hash than `Q`. For instance, imagine you have a
125+
/// type that wraps a string but compares ASCII letters ignoring their case:
126+
///
127+
/// ```
128+
/// pub struct CaseInsensitiveString(String);
129+
///
130+
/// impl PartialEq for CaseInsensitiveString {
131+
/// fn eq(&self, other: &Self) -> bool {
132+
/// self.0.eq_ignore_ascii_case(&other.0)
133+
/// }
134+
/// }
135+
///
136+
/// impl Eq for CaseInsensitiveString { }
137+
/// ```
138+
///
139+
/// Because two equal values need to produce the same hash value, the
140+
/// implementation of `Hash` needs to ignore ASCII case, too:
141+
///
142+
/// ```
143+
/// # use std::hash::{Hash, Hasher};
144+
/// # pub struct CaseInsensitiveString(String);
145+
/// impl Hash for CaseInsensitiveString {
146+
/// fn hash<H: Hasher>(&self, state: &mut H) {
147+
/// for c in self.0.as_bytes() {
148+
/// c.to_ascii_lowercase().hash(state)
149+
/// }
150+
/// }
151+
/// }
152+
/// ```
153+
///
154+
/// Can `CaseInsensitiveString` implement `Borrow<str>`? It certainly can
155+
/// provide a reference to a string slice via its contained owned string.
156+
/// But because its `Hash` implementation differs, it behaves differently
157+
/// from `str` and therefore must not, in fact, implement `Borrow<str>`.
158+
/// If it wants to allow others access to the underlying `str`, it can do
159+
/// that via `AsRef<str>` which doesn’t carry any extra requirements.
160+
///
161+
/// [`Hash`]: ../../std/hash/trait.Hash.html
162+
/// [`HashMap<K, V>`]: ../../std/collections/struct.HashMap.html
163+
/// [`String`]: ../../std/string/struct.String.html
164+
/// [`str`]: ../../std/primitive.str.html
35165
#[stable(feature = "rust1", since = "1.0.0")]
36166
pub trait Borrow<Borrowed: ?Sized> {
37167
/// Immutably borrows from an owned value.
@@ -59,7 +189,11 @@ pub trait Borrow<Borrowed: ?Sized> {
59189

60190
/// A trait for mutably borrowing data.
61191
///
62-
/// Similar to `Borrow`, but for mutable borrows.
192+
/// As a companion to [`Borrow<T>`] this trait allows a type to borrow as
193+
/// an underlying type by providing a mutable reference. See [`Borrow<T>`]
194+
/// for more information on borrowing as another type.
195+
///
196+
/// [`Borrow<T>`]: trait.Borrow.html
63197
#[stable(feature = "rust1", since = "1.0.0")]
64198
pub trait BorrowMut<Borrowed: ?Sized> : Borrow<Borrowed> {
65199
/// Mutably borrows from an owned value.

src/libcore/fmt/num.rs

+15-17
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,13 @@ doit! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize }
4949
#[doc(hidden)]
5050
trait GenericRadix {
5151
/// The number of digits.
52-
fn base(&self) -> u8;
52+
const BASE: u8;
5353

5454
/// A radix-specific prefix string.
55-
fn prefix(&self) -> &'static str {
56-
""
57-
}
55+
const PREFIX: &'static str;
5856

5957
/// Converts an integer to corresponding radix digit.
60-
fn digit(&self, x: u8) -> u8;
58+
fn digit(x: u8) -> u8;
6159

6260
/// Format an integer using the radix using a formatter.
6361
fn fmt_int<T: Int>(&self, mut x: T, f: &mut fmt::Formatter) -> fmt::Result {
@@ -67,14 +65,14 @@ trait GenericRadix {
6765
let is_nonnegative = x >= zero;
6866
let mut buf = [0; 128];
6967
let mut curr = buf.len();
70-
let base = T::from_u8(self.base());
68+
let base = T::from_u8(Self::BASE);
7169
if is_nonnegative {
7270
// Accumulate each digit of the number from the least significant
7371
// to the most significant figure.
7472
for byte in buf.iter_mut().rev() {
75-
let n = x % base; // Get the current place value.
76-
x = x / base; // Deaccumulate the number.
77-
*byte = self.digit(n.to_u8()); // Store the digit in the buffer.
73+
let n = x % base; // Get the current place value.
74+
x = x / base; // Deaccumulate the number.
75+
*byte = Self::digit(n.to_u8()); // Store the digit in the buffer.
7876
curr -= 1;
7977
if x == zero {
8078
// No more digits left to accumulate.
@@ -84,9 +82,9 @@ trait GenericRadix {
8482
} else {
8583
// Do the same as above, but accounting for two's complement.
8684
for byte in buf.iter_mut().rev() {
87-
let n = zero - (x % base); // Get the current place value.
88-
x = x / base; // Deaccumulate the number.
89-
*byte = self.digit(n.to_u8()); // Store the digit in the buffer.
85+
let n = zero - (x % base); // Get the current place value.
86+
x = x / base; // Deaccumulate the number.
87+
*byte = Self::digit(n.to_u8()); // Store the digit in the buffer.
9088
curr -= 1;
9189
if x == zero {
9290
// No more digits left to accumulate.
@@ -95,7 +93,7 @@ trait GenericRadix {
9593
}
9694
}
9795
let buf = unsafe { str::from_utf8_unchecked(&buf[curr..]) };
98-
f.pad_integral(is_nonnegative, self.prefix(), buf)
96+
f.pad_integral(is_nonnegative, Self::PREFIX, buf)
9997
}
10098
}
10199

@@ -122,12 +120,12 @@ struct UpperHex;
122120
macro_rules! radix {
123121
($T:ident, $base:expr, $prefix:expr, $($x:pat => $conv:expr),+) => {
124122
impl GenericRadix for $T {
125-
fn base(&self) -> u8 { $base }
126-
fn prefix(&self) -> &'static str { $prefix }
127-
fn digit(&self, x: u8) -> u8 {
123+
const BASE: u8 = $base;
124+
const PREFIX: &'static str = $prefix;
125+
fn digit(x: u8) -> u8 {
128126
match x {
129127
$($x => $conv,)+
130-
x => panic!("number not in the range 0..{}: {}", self.base() - 1, x),
128+
x => panic!("number not in the range 0..{}: {}", Self::BASE - 1, x),
131129
}
132130
}
133131
}

0 commit comments

Comments
 (0)