Skip to content

Commit 0d46cfe

Browse files
committed
Have only one presentation for binding consistency errors
1 parent 738b0f3 commit 0d46cfe

File tree

2 files changed

+68
-73
lines changed

2 files changed

+68
-73
lines changed

src/librustc_resolve/lib.rs

Lines changed: 27 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,8 @@ enum ResolutionError<'a> {
109109
TypeNotMemberOfTrait(Name, &'a str),
110110
/// error E0438: const is not a member of trait
111111
ConstNotMemberOfTrait(Name, &'a str),
112-
/// error E0408: variable `{}` from pattern #{} is not bound in pattern #1
112+
/// error E0408: variable `{}` from pattern #{} is not bound in pattern #{}
113113
VariableNotBoundInPattern(Name, Span, Vec<(Span, usize)>),
114-
/// error E0408: variable `{}` from pattern #1 is not bound in pattern #{}
115-
VariableNotBoundInFirstPattern(Span, Vec<(Name, usize, Span)>),
116114
/// error E0409: variable is bound with different mode in pattern #{} than in pattern #1
117115
VariableBoundWithDifferentMode(Name, usize, Span),
118116
/// error E0415: identifier is bound more than once in this parameter list
@@ -228,33 +226,6 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver,
228226
err.span_label(sp, &"variable not in all patterns");
229227
err
230228
}
231-
ResolutionError::VariableNotBoundInFirstPattern(sp, extra_vars) => {
232-
let spans: Vec<_> = extra_vars.iter().map(|x| x.2).collect();
233-
let msp = MultiSpan::from_spans(spans.clone());
234-
// "variable `b` from pattern #2, variable `c` from pattern #3 aren't bound in pattern
235-
// #1"
236-
let msg = format!("{} {}n't bound in pattern #1",
237-
extra_vars.iter()
238-
.map(|x| format!("variable `{}` from pattern #{}", x.0, x.1))
239-
.collect::<Vec<_>>()
240-
.join(", "),
241-
if spans.len() > 1 {
242-
"are"
243-
} else {
244-
"is"
245-
});
246-
let mut err = resolver.session.struct_span_err_with_code(msp, &msg, "E0408");
247-
for sp in spans {
248-
err.span_label(sp, &"variable not in all patterns");
249-
}
250-
err.span_label(sp,
251-
&format!("pattern doesn't bind {}",
252-
extra_vars.iter()
253-
.map(|x| format!("`{}`", x.0))
254-
.collect::<Vec<_>>()
255-
.join(", ")));
256-
err
257-
}
258229
ResolutionError::VariableBoundWithDifferentMode(variable_name,
259230
pattern_number,
260231
first_binding_span) => {
@@ -1906,51 +1877,46 @@ impl<'a> Resolver<'a> {
19061877
if arm.pats.is_empty() {
19071878
return;
19081879
}
1909-
let map_0 = self.binding_mode_map(&arm.pats[0]);
19101880

19111881
let mut missing_vars = FxHashMap();
1912-
let mut extra_vars = vec![];
1913-
19141882
for (i, p) in arm.pats.iter().enumerate() {
19151883
let map_i = self.binding_mode_map(&p);
19161884

1917-
for (&key, &binding_0) in &map_0 {
1918-
match map_i.get(&key) {
1919-
None => {
1920-
let spans = missing_vars
1921-
.entry((key.name, binding_0.span))
1922-
.or_insert(vec![]);
1923-
spans.push((p.span, i + 1));
1924-
}
1925-
Some(binding_i) => {
1926-
if binding_0.binding_mode != binding_i.binding_mode {
1927-
resolve_error(self,
1928-
binding_i.span,
1929-
ResolutionError::VariableBoundWithDifferentMode(
1930-
key.name,
1931-
i + 1,
1932-
binding_0.span));
1933-
}
1934-
}
1885+
for (j, q) in arm.pats.iter().enumerate() {
1886+
if i == j {
1887+
continue;
19351888
}
1936-
}
19371889

1938-
for (&key, &binding) in &map_i {
1939-
if !map_0.contains_key(&key) {
1940-
extra_vars.push((key.name, i + 1, binding.span));
1890+
let map_j = self.binding_mode_map(&q);
1891+
for (&key, &binding_i) in &map_i {
1892+
for (&key_j, &binding_j) in &map_j {
1893+
match map_i.get(&key_j) {
1894+
None => { // missing binding
1895+
let spans = missing_vars
1896+
.entry((key_j.name, binding_j.span))
1897+
.or_insert(FxHashMap());
1898+
spans.entry((p.span, i + 1)).or_insert(Some(()));
1899+
}
1900+
Some(binding_j) => { // check consistent binding
1901+
if binding_i.binding_mode != binding_j.binding_mode {
1902+
resolve_error(self,
1903+
binding_i.span,
1904+
ResolutionError::VariableBoundWithDifferentMode(
1905+
key.name,
1906+
i + 1,
1907+
binding_i.span));
1908+
}
1909+
}
1910+
}
1911+
}
19411912
}
19421913
}
19431914
}
19441915
for (k, v) in missing_vars {
19451916
let (name, sp) = k;
1917+
let v = v.iter().map(|x| *x.0).collect::<Vec<_>>();
19461918
resolve_error(self, sp, ResolutionError::VariableNotBoundInPattern(name, sp, v));
19471919
}
1948-
if extra_vars.len() > 0 {
1949-
resolve_error(self,
1950-
arm.pats[0].span,
1951-
ResolutionError::VariableNotBoundInFirstPattern(arm.pats[0].span,
1952-
extra_vars));
1953-
}
19541920
}
19551921

19561922
fn resolve_arm(&mut self, arm: &Arm) {

src/test/ui/span/issue-39698.stderr

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
error[E0408]: variable `d` from pattern #1 isn't bound in patterns #3, #4
2-
--> $DIR/issue-39698.rs:20:37
1+
error[E0408]: variable `a` from pattern #1 isn't bound in patterns #2, #3
2+
--> $DIR/issue-39698.rs:20:23
33
|
44
20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
5-
| - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `d`
6-
| | |
7-
| | pattern doesn't bind `d`
8-
| variable not in all patterns
5+
| ^^^^^^^^^^^ ^^^^^^^^ - variable not in all patterns
6+
| | |
7+
| | pattern doesn't bind `a`
8+
| pattern doesn't bind `a`
99

1010
error[E0408]: variable `a` from pattern #1 isn't bound in patterns #2, #3
1111
--> $DIR/issue-39698.rs:20:23
@@ -16,14 +16,43 @@ error[E0408]: variable `a` from pattern #1 isn't bound in patterns #2, #3
1616
| | pattern doesn't bind `a`
1717
| variable not in all patterns
1818

19-
error[E0408]: variable `b` from pattern #2, variable `c` from pattern #3 aren't bound in pattern #1
20-
--> $DIR/issue-39698.rs:20:32
19+
error[E0408]: variable `c` from pattern #1 isn't bound in patterns #2, #4, #1
20+
--> $DIR/issue-39698.rs:20:23
21+
|
22+
20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
23+
| ^^^^^^^^^^^ ^^^^^^^^^^^ - ^^^^^^^^ pattern doesn't bind `c`
24+
| | | |
25+
| | | variable not in all patterns
26+
| | pattern doesn't bind `c`
27+
| pattern doesn't bind `c`
28+
29+
error[E0408]: variable `d` from pattern #1 isn't bound in patterns #4, #3
30+
--> $DIR/issue-39698.rs:20:48
2131
|
2232
20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
23-
| ----------- ^ ^ variable not in all patterns
24-
| | |
33+
| - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `d`
34+
| | |
35+
| | pattern doesn't bind `d`
36+
| variable not in all patterns
37+
38+
error[E0408]: variable `b` from pattern #1 isn't bound in patterns #4, #3, #1
39+
--> $DIR/issue-39698.rs:20:48
40+
|
41+
20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
42+
| ^^^^^^^^^^^ - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `b`
43+
| | | |
44+
| | | pattern doesn't bind `b`
2545
| | variable not in all patterns
26-
| pattern doesn't bind `b`, `c`
46+
| pattern doesn't bind `b`
47+
48+
error[E0408]: variable `d` from pattern #1 isn't bound in patterns #4, #3
49+
--> $DIR/issue-39698.rs:20:48
50+
|
51+
20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
52+
| - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `d`
53+
| | |
54+
| | pattern doesn't bind `d`
55+
| variable not in all patterns
2756

28-
error: aborting due to 3 previous errors
57+
error: aborting due to 6 previous errors
2958

0 commit comments

Comments
 (0)