Skip to content

Rollup of 5 pull requests #116356

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Oct 2, 2023
Merged
38 changes: 18 additions & 20 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
@@ -41,9 +41,6 @@ type Res = def::Res<NodeId>;

type IdentMap<T> = FxHashMap<Ident, T>;

/// Map from the name in a pattern to its binding mode.
type BindingMap = IdentMap<BindingInfo>;

use diagnostics::{
ElisionFnParameter, LifetimeElisionCandidate, MissingLifetime, MissingLifetimeKind,
};
@@ -3164,8 +3161,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
/// this is done hygienically. This could arise for a macro
/// that expands into an or-pattern where one 'x' was from the
/// user and one 'x' came from the macro.
fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
let mut binding_map = FxHashMap::default();
fn binding_mode_map(&mut self, pat: &Pat) -> FxIndexMap<Ident, BindingInfo> {
let mut binding_map = FxIndexMap::default();

pat.walk(&mut |pat| {
match pat.kind {
@@ -3200,22 +3197,28 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {

/// Checks that all of the arms in an or-pattern have exactly the
/// same set of bindings, with the same binding modes for each.
fn check_consistent_bindings(&mut self, pats: &[P<Pat>]) -> Vec<BindingMap> {
let mut missing_vars = FxHashMap::default();
let mut inconsistent_vars = FxHashMap::default();
fn check_consistent_bindings(
&mut self,
pats: &[P<Pat>],
) -> Vec<FxIndexMap<Ident, BindingInfo>> {
// pats is consistent.
let mut missing_vars = FxIndexMap::default();
let mut inconsistent_vars = FxIndexMap::default();

// 1) Compute the binding maps of all arms.
let maps = pats.iter().map(|pat| self.binding_mode_map(pat)).collect::<Vec<_>>();

// 2) Record any missing bindings or binding mode inconsistencies.
for (map_outer, pat_outer) in pats.iter().enumerate().map(|(idx, pat)| (&maps[idx], pat)) {
for (map_outer, pat_outer) in maps.iter().zip(pats.iter()) {
// Check against all arms except for the same pattern which is always self-consistent.
let inners = pats
let inners = maps
.iter()
.enumerate()
.zip(pats.iter())
.filter(|(_, pat)| pat.id != pat_outer.id)
.flat_map(|(idx, _)| maps[idx].iter())
.map(|(key, binding)| (key.name, map_outer.get(&key), binding));
.flat_map(|(map, _)| map)
.map(|(key, binding)| (key.name, map_outer.get(key), binding));

let inners = inners.collect::<Vec<_>>();

for (name, info, &binding_inner) in inners {
match info {
@@ -3244,10 +3247,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
}

// 3) Report all missing variables we found.
let mut missing_vars = missing_vars.into_iter().collect::<Vec<_>>();
missing_vars.sort_by_key(|&(sym, ref _err)| sym);

for (name, mut v) in missing_vars.into_iter() {
for (name, mut v) in missing_vars {
if inconsistent_vars.contains_key(&name) {
v.could_be_path = false;
}
@@ -3258,10 +3258,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
}

// 4) Report all inconsistencies in binding modes we found.
let mut inconsistent_vars = inconsistent_vars.iter().collect::<Vec<_>>();
inconsistent_vars.sort();
for (name, v) in inconsistent_vars {
self.report_error(v.0, ResolutionError::VariableBoundWithDifferentMode(*name, v.1));
self.report_error(v.0, ResolutionError::VariableBoundWithDifferentMode(name, v.1));
}

// 5) Finally bubble up all the binding maps.
2 changes: 1 addition & 1 deletion library/core/src/hint.rs
Original file line number Diff line number Diff line change
@@ -277,7 +277,7 @@ pub fn spin_loop() {
/// - Treats the call to `contains` and its result as volatile: the body of `benchmark` cannot
/// optimize this away
///
/// This makes our benchmark much more realistic to how the function would be used in situ, where
/// This makes our benchmark much more realistic to how the function would actually be used, where
/// arguments are usually not known at compile time and the result is used in some way.
#[inline]
#[stable(feature = "bench_black_box", since = "1.66.0")]
1 change: 1 addition & 0 deletions library/std/src/sys/unix/fs.rs
Original file line number Diff line number Diff line change
@@ -1391,6 +1391,7 @@ impl FromInner<FileDesc> for File {
}

impl AsFd for File {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.0.as_fd()
}
6 changes: 3 additions & 3 deletions src/bootstrap/install.rs
Original file line number Diff line number Diff line change
@@ -46,10 +46,10 @@ fn sanitize_sh(path: &Path) -> String {
}

fn is_dir_writable_for_user(dir: &PathBuf) -> bool {
let tmp_file = dir.join(".tmp");
match fs::File::create(&tmp_file) {
let tmp = dir.join(".tmp");
match fs::create_dir_all(&tmp) {
Ok(_) => {
fs::remove_file(tmp_file).unwrap();
fs::remove_dir_all(tmp).unwrap();
true
}
Err(e) => {
6 changes: 3 additions & 3 deletions src/tools/build_helper/src/ci.rs
Original file line number Diff line number Diff line change
@@ -82,15 +82,15 @@ pub mod gha {

fn start_group(name: impl std::fmt::Display) {
if is_in_gha() {
eprintln!("::group::{name}");
println!("::group::{name}");
} else {
eprintln!("{name}")
println!("{name}")
}
}

fn end_group() {
if is_in_gha() {
eprintln!("::endgroup::");
println!("::endgroup::");
}
}

84 changes: 42 additions & 42 deletions tests/ui/or-patterns/missing-bindings.stderr
Original file line number Diff line number Diff line change
@@ -103,22 +103,6 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
| |
| variable not in all patterns

error[E0408]: variable `c` is not bound in all patterns
--> $DIR/missing-bindings.rs:45:33
|
LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
| - ^^^^ pattern doesn't bind `c`
| |
| variable not in all patterns

error[E0408]: variable `d` is not bound in all patterns
--> $DIR/missing-bindings.rs:45:33
|
LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
| - ^^^^ pattern doesn't bind `d`
| |
| variable not in all patterns

error[E0408]: variable `e` is not bound in all patterns
--> $DIR/missing-bindings.rs:45:10
|
@@ -143,6 +127,22 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
| |
| variable not in all patterns

error[E0408]: variable `c` is not bound in all patterns
--> $DIR/missing-bindings.rs:45:33
|
LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
| - ^^^^ pattern doesn't bind `c`
| |
| variable not in all patterns

error[E0408]: variable `d` is not bound in all patterns
--> $DIR/missing-bindings.rs:45:33
|
LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
| - ^^^^ pattern doesn't bind `d`
| |
| variable not in all patterns

error[E0408]: variable `a` is not bound in all patterns
--> $DIR/missing-bindings.rs:61:29
|
@@ -151,14 +151,6 @@ LL | Ok(a) | Err(_),
| |
| variable not in all patterns

error[E0408]: variable `a` is not bound in all patterns
--> $DIR/missing-bindings.rs:69:21
|
LL | A(_, a) |
| - variable not in all patterns
LL | B(b),
| ^^^^ pattern doesn't bind `a`

error[E0408]: variable `b` is not bound in all patterns
--> $DIR/missing-bindings.rs:68:21
|
@@ -167,6 +159,14 @@ LL | A(_, a) |
LL | B(b),
| - variable not in all patterns

error[E0408]: variable `a` is not bound in all patterns
--> $DIR/missing-bindings.rs:69:21
|
LL | A(_, a) |
| - variable not in all patterns
LL | B(b),
| ^^^^ pattern doesn't bind `a`

error[E0408]: variable `a` is not bound in all patterns
--> $DIR/missing-bindings.rs:72:17
|
@@ -185,6 +185,24 @@ LL | B(b),
LL | B(_)
| ^^^^ pattern doesn't bind `b`

error[E0408]: variable `b` is not bound in all patterns
--> $DIR/missing-bindings.rs:57:13
|
LL | / V1(
LL | |
LL | |
LL | | A(
... |
LL | | B(Ok(a) | Err(a))
LL | | ) |
| |_____________^ pattern doesn't bind `b`
...
LL | B(b),
| - variable not in all patterns
...
LL | V3(c),
| ^^^^^ pattern doesn't bind `b`

error[E0408]: variable `c` is not bound in all patterns
--> $DIR/missing-bindings.rs:57:13
|
@@ -219,24 +237,6 @@ LL | A(_, a) |
LL | V3(c),
| ^^^^^ pattern doesn't bind `a`

error[E0408]: variable `b` is not bound in all patterns
--> $DIR/missing-bindings.rs:57:13
|
LL | / V1(
LL | |
LL | |
LL | | A(
... |
LL | | B(Ok(a) | Err(a))
LL | | ) |
| |_____________^ pattern doesn't bind `b`
...
LL | B(b),
| - variable not in all patterns
...
LL | V3(c),
| ^^^^^ pattern doesn't bind `b`

error: aborting due to 26 previous errors

For more information about this error, try `rustc --explain E0408`.
42 changes: 21 additions & 21 deletions tests/ui/resolve/resolve-inconsistent-names.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
error[E0408]: variable `a` is not bound in all patterns
--> $DIR/resolve-inconsistent-names.rs:13:12
|
LL | a | b => {}
| - ^ pattern doesn't bind `a`
| |
| variable not in all patterns

error[E0408]: variable `b` is not bound in all patterns
--> $DIR/resolve-inconsistent-names.rs:13:8
|
@@ -14,6 +6,14 @@ LL | a | b => {}
| |
| pattern doesn't bind `b`

error[E0408]: variable `a` is not bound in all patterns
--> $DIR/resolve-inconsistent-names.rs:13:12
|
LL | a | b => {}
| - ^ pattern doesn't bind `a`
| |
| variable not in all patterns

error[E0408]: variable `c` is not bound in all patterns
--> $DIR/resolve-inconsistent-names.rs:19:9
|
@@ -54,6 +54,19 @@ LL | (A, B) | (ref B, c) | (c, A) => ()
| |
| first binding

error[E0408]: variable `Const2` is not bound in all patterns
--> $DIR/resolve-inconsistent-names.rs:31:9
|
LL | (CONST1, _) | (_, Const2) => ()
| ^^^^^^^^^^^ ------ variable not in all patterns
| |
| pattern doesn't bind `Const2`
|
help: if you meant to match on constant `m::Const2`, use the full path in the pattern
|
LL | (CONST1, _) | (_, m::Const2) => ()
| ~~~~~~~~~

error[E0408]: variable `CONST1` is not bound in all patterns
--> $DIR/resolve-inconsistent-names.rs:31:23
|
@@ -68,19 +81,6 @@ note: you might have meant to match on constant `m::CONST1`, which exists but is
LL | const CONST1: usize = 10;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not accessible

error[E0408]: variable `Const2` is not bound in all patterns
--> $DIR/resolve-inconsistent-names.rs:31:9
|
LL | (CONST1, _) | (_, Const2) => ()
| ^^^^^^^^^^^ ------ variable not in all patterns
| |
| pattern doesn't bind `Const2`
|
help: if you meant to match on constant `m::Const2`, use the full path in the pattern
|
LL | (CONST1, _) | (_, m::Const2) => ()
| ~~~~~~~~~

error[E0308]: mismatched types
--> $DIR/resolve-inconsistent-names.rs:19:19
|
34 changes: 17 additions & 17 deletions tests/ui/span/issue-39698.stderr
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
error[E0408]: variable `b` is not bound in all patterns
--> $DIR/issue-39698.rs:10:9
|
LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
| ^^^^^^^^^^^ - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `b`
| | | |
| | | pattern doesn't bind `b`
| | variable not in all patterns
| pattern doesn't bind `b`

error[E0408]: variable `c` is not bound in all patterns
--> $DIR/issue-39698.rs:10:9
|
@@ -8,16 +18,6 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}
| | pattern doesn't bind `c`
| pattern doesn't bind `c`

error[E0408]: variable `d` is not bound in all patterns
--> $DIR/issue-39698.rs:10:37
|
LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
| - - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `d`
| | | |
| | | pattern doesn't bind `d`
| | variable not in all patterns
| variable not in all patterns

error[E0408]: variable `a` is not bound in all patterns
--> $DIR/issue-39698.rs:10:23
|
@@ -28,15 +28,15 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}
| | pattern doesn't bind `a`
| variable not in all patterns

error[E0408]: variable `b` is not bound in all patterns
--> $DIR/issue-39698.rs:10:9
error[E0408]: variable `d` is not bound in all patterns
--> $DIR/issue-39698.rs:10:37
|
LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
| ^^^^^^^^^^^ - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `b`
| | | |
| | | pattern doesn't bind `b`
| | variable not in all patterns
| pattern doesn't bind `b`
| - - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `d`
| | | |
| | | pattern doesn't bind `d`
| | variable not in all patterns
| variable not in all patterns

error: aborting due to 4 previous errors