Skip to content

Commit 485c5fb

Browse files
committed
Auto merge of #70931 - Dylan-DPC:rollup-f8orcao, r=Dylan-DPC
Rollup of 9 pull requests Successful merges: - #70789 (remove false positives of unused_braces) - #70847 (ci: move /var/lib/docker to /mnt on GHA) - #70850 (BTreeMap first last proposal tweaks) - #70876 (Use a `SmallVec` for `Cache::predecessors`.) - #70883 (Clean up E0507 explanation) - #70892 (wf: refactor `compute_trait_ref`) - #70914 (Corrects a typo in rustdoc documentation.) - #70915 (Remove unnecessary TypeFlags::NOMINAL_FLAGS) - #70927 (Clean up E0510 explanation) Failed merges: r? @ghost
2 parents 42abbd8 + 1498da8 commit 485c5fb

File tree

14 files changed

+346
-273
lines changed

14 files changed

+346
-273
lines changed

src/ci/scripts/symlink-build-dir.sh

+6
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,10 @@ elif isLinux && isGitHubActions; then
2424
mv "${current_dir}" /mnt/more-space/workspace
2525
ln -s /mnt/more-space/workspace "${current_dir}"
2626
cd "${current_dir}"
27+
28+
# Move the Docker data directory to /mnt
29+
sudo systemctl stop docker.service
30+
sudo mv /var/lib/docker /mnt/docker
31+
sudo ln -s /mnt/docker /var/lib/docker
32+
sudo systemctl start docker.service
2733
fi

src/doc/rustdoc/src/documentation-tests.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -352,9 +352,9 @@ are added.
352352
/// ```
353353
```
354354

355-
`edition2018` tells `rustdoc` that the code sample should be compiled the 2018
356-
edition of Rust. Similarly, you can specify `edition2015` to compile the code
357-
with the 2015 edition.
355+
`edition2018` tells `rustdoc` that the code sample should be compiled using
356+
the 2018 edition of Rust. Similarly, you can specify `edition2015` to compile
357+
the code with the 2015 edition.
358358

359359
## Syntax reference
360360

src/liballoc/collections/btree/map.rs

+76-48
Original file line numberDiff line numberDiff line change
@@ -653,11 +653,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
653653
/// assert_eq!(map.first_key_value(), Some((&1, &"b")));
654654
/// ```
655655
#[unstable(feature = "map_first_last", issue = "62924")]
656-
pub fn first_key_value<T: ?Sized>(&self) -> Option<(&K, &V)>
657-
where
658-
T: Ord,
659-
K: Borrow<T>,
660-
{
656+
pub fn first_key_value(&self) -> Option<(&K, &V)> {
661657
let front = self.root.as_ref()?.as_ref().first_leaf_edge();
662658
front.right_kv().ok().map(Handle::into_kv)
663659
}
@@ -667,36 +663,54 @@ impl<K: Ord, V> BTreeMap<K, V> {
667663
///
668664
/// # Examples
669665
///
670-
/// Contrived way to `clear` a map:
671-
///
672666
/// ```
673667
/// #![feature(map_first_last)]
674668
/// use std::collections::BTreeMap;
675669
///
676670
/// let mut map = BTreeMap::new();
677671
/// map.insert(1, "a");
678672
/// map.insert(2, "b");
679-
/// while let Some(entry) = map.first_entry() {
680-
/// let (key, val) = entry.remove_entry();
681-
/// assert!(!map.contains_key(&key));
673+
/// if let Some(mut entry) = map.first_entry() {
674+
/// if *entry.key() > 0 {
675+
/// entry.insert("first");
676+
/// }
682677
/// }
678+
/// assert_eq!(*map.get(&1).unwrap(), "first");
679+
/// assert_eq!(*map.get(&2).unwrap(), "b");
683680
/// ```
684681
#[unstable(feature = "map_first_last", issue = "62924")]
685-
pub fn first_entry<T: ?Sized>(&mut self) -> Option<OccupiedEntry<'_, K, V>>
686-
where
687-
T: Ord,
688-
K: Borrow<T>,
689-
{
682+
pub fn first_entry(&mut self) -> Option<OccupiedEntry<'_, K, V>> {
690683
let front = self.root.as_mut()?.as_mut().first_leaf_edge();
691-
if let Ok(kv) = front.right_kv() {
692-
Some(OccupiedEntry {
693-
handle: kv.forget_node_type(),
694-
length: &mut self.length,
695-
_marker: PhantomData,
696-
})
697-
} else {
698-
None
699-
}
684+
let kv = front.right_kv().ok()?;
685+
Some(OccupiedEntry {
686+
handle: kv.forget_node_type(),
687+
length: &mut self.length,
688+
_marker: PhantomData,
689+
})
690+
}
691+
692+
/// Removes and returns the first element in the map.
693+
/// The key of this element is the minimum key that was in the map.
694+
///
695+
/// # Examples
696+
///
697+
/// Draining elements in ascending order, while keeping a usable map each iteration.
698+
///
699+
/// ```
700+
/// #![feature(map_first_last)]
701+
/// use std::collections::BTreeMap;
702+
///
703+
/// let mut map = BTreeMap::new();
704+
/// map.insert(1, "a");
705+
/// map.insert(2, "b");
706+
/// while let Some((key, _val)) = map.pop_first() {
707+
/// assert!(map.iter().all(|(k, _v)| *k > key));
708+
/// }
709+
/// assert!(map.is_empty());
710+
/// ```
711+
#[unstable(feature = "map_first_last", issue = "62924")]
712+
pub fn pop_first(&mut self) -> Option<(K, V)> {
713+
self.first_entry().map(|entry| entry.remove_entry())
700714
}
701715

702716
/// Returns the last key-value pair in the map.
@@ -716,11 +730,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
716730
/// assert_eq!(map.last_key_value(), Some((&2, &"a")));
717731
/// ```
718732
#[unstable(feature = "map_first_last", issue = "62924")]
719-
pub fn last_key_value<T: ?Sized>(&self) -> Option<(&K, &V)>
720-
where
721-
T: Ord,
722-
K: Borrow<T>,
723-
{
733+
pub fn last_key_value(&self) -> Option<(&K, &V)> {
724734
let back = self.root.as_ref()?.as_ref().last_leaf_edge();
725735
back.left_kv().ok().map(Handle::into_kv)
726736
}
@@ -730,36 +740,54 @@ impl<K: Ord, V> BTreeMap<K, V> {
730740
///
731741
/// # Examples
732742
///
733-
/// Contrived way to `clear` a map:
734-
///
735743
/// ```
736744
/// #![feature(map_first_last)]
737745
/// use std::collections::BTreeMap;
738746
///
739747
/// let mut map = BTreeMap::new();
740748
/// map.insert(1, "a");
741749
/// map.insert(2, "b");
742-
/// while let Some(entry) = map.last_entry() {
743-
/// let (key, val) = entry.remove_entry();
744-
/// assert!(!map.contains_key(&key));
750+
/// if let Some(mut entry) = map.last_entry() {
751+
/// if *entry.key() > 0 {
752+
/// entry.insert("last");
753+
/// }
745754
/// }
755+
/// assert_eq!(*map.get(&1).unwrap(), "a");
756+
/// assert_eq!(*map.get(&2).unwrap(), "last");
746757
/// ```
747758
#[unstable(feature = "map_first_last", issue = "62924")]
748-
pub fn last_entry<T: ?Sized>(&mut self) -> Option<OccupiedEntry<'_, K, V>>
749-
where
750-
T: Ord,
751-
K: Borrow<T>,
752-
{
759+
pub fn last_entry(&mut self) -> Option<OccupiedEntry<'_, K, V>> {
753760
let back = self.root.as_mut()?.as_mut().last_leaf_edge();
754-
if let Ok(kv) = back.left_kv() {
755-
Some(OccupiedEntry {
756-
handle: kv.forget_node_type(),
757-
length: &mut self.length,
758-
_marker: PhantomData,
759-
})
760-
} else {
761-
None
762-
}
761+
let kv = back.left_kv().ok()?;
762+
Some(OccupiedEntry {
763+
handle: kv.forget_node_type(),
764+
length: &mut self.length,
765+
_marker: PhantomData,
766+
})
767+
}
768+
769+
/// Removes and returns the last element in the map.
770+
/// The key of this element is the maximum key that was in the map.
771+
///
772+
/// # Examples
773+
///
774+
/// Draining elements in descending order, while keeping a usable map each iteration.
775+
///
776+
/// ```
777+
/// #![feature(map_first_last)]
778+
/// use std::collections::BTreeMap;
779+
///
780+
/// let mut map = BTreeMap::new();
781+
/// map.insert(1, "a");
782+
/// map.insert(2, "b");
783+
/// while let Some((key, _val)) = map.pop_last() {
784+
/// assert!(map.iter().all(|(k, _v)| *k < key));
785+
/// }
786+
/// assert!(map.is_empty());
787+
/// ```
788+
#[unstable(feature = "map_first_last", issue = "62924")]
789+
pub fn pop_last(&mut self) -> Option<(K, V)> {
790+
self.last_entry().map(|entry| entry.remove_entry())
763791
}
764792

765793
/// Returns `true` if the map contains a value for the specified key.

src/librustc_error_codes/error_codes/E0507.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
You tried to move out of a value which was borrowed.
2-
3-
This can also happen when using a type implementing `Fn` or `FnMut`, as neither
4-
allows moving out of them (they usually represent closures which can be called
5-
more than once). Much of the text following applies equally well to non-`FnOnce`
6-
closure bodies.
1+
A borrowed value was moved out.
72

83
Erroneous code example:
94

@@ -32,6 +27,11 @@ you have three choices:
3227
* Somehow reclaim the ownership.
3328
* Implement the `Copy` trait on the type.
3429

30+
This can also happen when using a type implementing `Fn` or `FnMut`, as neither
31+
allows moving out of them (they usually represent closures which can be called
32+
more than once). Much of the text following applies equally well to non-`FnOnce`
33+
closure bodies.
34+
3535
Examples:
3636

3737
```
+20-7
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,29 @@
1-
Cannot mutate place in this match guard.
1+
The matched value was assigned in a match guard.
22

3-
When matching on a variable it cannot be mutated in the match guards, as this
4-
could cause the match to be non-exhaustive:
3+
Erroneous code example:
54

65
```compile_fail,E0510
76
let mut x = Some(0);
87
match x {
9-
None => (),
10-
Some(_) if { x = None; false } => (),
11-
Some(v) => (), // No longer matches
8+
None => {}
9+
Some(_) if { x = None; false } => {} // error!
10+
Some(_) => {}
1211
}
1312
```
1413

14+
When matching on a variable it cannot be mutated in the match guards, as this
15+
could cause the match to be non-exhaustive.
16+
1517
Here executing `x = None` would modify the value being matched and require us
16-
to go "back in time" to the `None` arm.
18+
to go "back in time" to the `None` arm. To fix it, change the value in the match
19+
arm:
20+
21+
```
22+
let mut x = Some(0);
23+
match x {
24+
None => {}
25+
Some(_) => {
26+
x = None; // ok!
27+
}
28+
}
29+
```

src/librustc_lint/unused.rs

+23-3
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,19 @@ impl From<UnusedDelimsCtx> for &'static str {
355355
trait UnusedDelimLint {
356356
const DELIM_STR: &'static str;
357357

358+
/// Due to `ref` pattern, there can be a difference between using
359+
/// `{ expr }` and `expr` in pattern-matching contexts. This means
360+
/// that we should only lint `unused_parens` and not `unused_braces`
361+
/// in this case.
362+
///
363+
/// ```rust
364+
/// let mut a = 7;
365+
/// let ref b = { a }; // We actually borrow a copy of `a` here.
366+
/// a += 1; // By mutating `a` we invalidate any borrows of `a`.
367+
/// assert_eq!(b + 1, a); // `b` does not borrow `a`, so we can still use it here.
368+
/// ```
369+
const LINT_EXPR_IN_PATTERN_MATCHING_CTX: bool;
370+
358371
// this cannot be a constant is it refers to a static.
359372
fn lint(&self) -> &'static Lint;
360373

@@ -454,7 +467,10 @@ trait UnusedDelimLint {
454467
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
455468
use rustc_ast::ast::ExprKind::*;
456469
let (value, ctx, followed_by_block, left_pos, right_pos) = match e.kind {
457-
If(ref cond, ref block, ..) => {
470+
// Do not lint `unused_braces` in `if let` expressions.
471+
If(ref cond, ref block, ..)
472+
if !matches!(cond.kind, Let(_, _)) || Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX =>
473+
{
458474
let left = e.span.lo() + rustc_span::BytePos(2);
459475
let right = block.span.lo();
460476
(cond, UnusedDelimsCtx::IfCond, true, Some(left), Some(right))
@@ -470,7 +486,7 @@ trait UnusedDelimLint {
470486
(cond, UnusedDelimsCtx::ForIterExpr, true, None, Some(block.span.lo()))
471487
}
472488

473-
Match(ref head, _) => {
489+
Match(ref head, _) if Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX => {
474490
let left = e.span.lo() + rustc_span::BytePos(5);
475491
(head, UnusedDelimsCtx::MatchScrutineeExpr, true, Some(left), None)
476492
}
@@ -512,7 +528,7 @@ trait UnusedDelimLint {
512528

513529
fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
514530
match s.kind {
515-
StmtKind::Local(ref local) => {
531+
StmtKind::Local(ref local) if Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX => {
516532
if let Some(ref value) = local.init {
517533
self.check_unused_delims_expr(
518534
cx,
@@ -565,6 +581,8 @@ declare_lint_pass!(UnusedParens => [UNUSED_PARENS]);
565581
impl UnusedDelimLint for UnusedParens {
566582
const DELIM_STR: &'static str = "parentheses";
567583

584+
const LINT_EXPR_IN_PATTERN_MATCHING_CTX: bool = true;
585+
568586
fn lint(&self) -> &'static Lint {
569587
UNUSED_PARENS
570588
}
@@ -736,6 +754,8 @@ declare_lint_pass!(UnusedBraces => [UNUSED_BRACES]);
736754
impl UnusedDelimLint for UnusedBraces {
737755
const DELIM_STR: &'static str = "braces";
738756

757+
const LINT_EXPR_IN_PATTERN_MATCHING_CTX: bool = false;
758+
739759
fn lint(&self) -> &'static Lint {
740760
UNUSED_BRACES
741761
}

src/librustc_middle/mir/cache.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ use rustc_data_structures::graph::{self, GraphPredecessors, GraphSuccessors};
55
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
66
use rustc_index::vec::IndexVec;
77
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
8+
use smallvec::SmallVec;
89
use std::iter;
910
use std::ops::{Deref, DerefMut, Index, IndexMut};
1011
use std::vec::IntoIter;
1112

1213
#[derive(Clone, Debug)]
1314
pub struct Cache {
14-
predecessors: Option<IndexVec<BasicBlock, Vec<BasicBlock>>>,
15+
// Typically 95%+ of the inner vectors have 4 or fewer elements.
16+
predecessors: Option<IndexVec<BasicBlock, SmallVec<[BasicBlock; 4]>>>,
1517
}
1618

1719
impl rustc_serialize::Encodable for Cache {
@@ -44,7 +46,7 @@ impl Cache {
4446

4547
pub fn ensure_predecessors(&mut self, body: &Body<'_>) {
4648
if self.predecessors.is_none() {
47-
let mut result = IndexVec::from_elem(vec![], body.basic_blocks());
49+
let mut result = IndexVec::from_elem(smallvec![], body.basic_blocks());
4850
for (bb, data) in body.basic_blocks().iter_enumerated() {
4951
if let Some(ref term) = data.terminator {
5052
for &tgt in term.successors() {
@@ -58,7 +60,11 @@ impl Cache {
5860
}
5961

6062
/// This will recompute the predecessors cache if it is not available
61-
fn predecessors(&mut self, body: &Body<'_>) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
63+
// njn: typedef?
64+
fn predecessors(
65+
&mut self,
66+
body: &Body<'_>,
67+
) -> &IndexVec<BasicBlock, SmallVec<[BasicBlock; 4]>> {
6268
self.ensure_predecessors(body);
6369
self.predecessors.as_ref().unwrap()
6470
}
@@ -137,7 +143,7 @@ impl BodyAndCache<'tcx> {
137143
self.cache.ensure_predecessors(&self.body);
138144
}
139145

140-
pub fn predecessors(&mut self) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
146+
pub fn predecessors(&mut self) -> &IndexVec<BasicBlock, SmallVec<[BasicBlock; 4]>> {
141147
self.cache.predecessors(&self.body)
142148
}
143149

@@ -199,7 +205,7 @@ impl ReadOnlyBodyAndCache<'a, 'tcx> {
199205
Self { body, cache }
200206
}
201207

202-
pub fn predecessors(&self) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
208+
pub fn predecessors(&self) -> &IndexVec<BasicBlock, SmallVec<[BasicBlock; 4]>> {
203209
self.cache.predecessors.as_ref().unwrap()
204210
}
205211

src/librustc_middle/ty/flags.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ impl FlagComputation {
2828
}
2929

3030
fn add_flags(&mut self, flags: TypeFlags) {
31-
self.flags = self.flags | (flags & TypeFlags::NOMINAL_FLAGS);
31+
self.flags = self.flags | flags;
3232
}
3333

3434
/// indicates that `self` refers to something at binding level `binder`

0 commit comments

Comments
 (0)