diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-06-21 15:24:51 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-06-21 15:24:51 +0100 |
commit | f9dffade9d2afdf8f92a32d4d09502485af6282d (patch) | |
tree | 63867917eb7f84172a7ac84ce606f943a329cb45 /crates/ra_hir_def/src/body/scope.rs | |
parent | 6d0a765d34a1f94645310f36d39c5125fea563f2 (diff) | |
parent | 500d8b2f6047660eeb6fc883b1aa60c297aa073b (diff) |
Merge #4969
4969: Handle bindings after @ in patterns r=flodiebold a=jonas-schievink
This is unstable, behind the `bindings_after_at` feature gate, but the semantics are fairly clear, and this is used at lot in rustc.
Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/ra_hir_def/src/body/scope.rs')
-rw-r--r-- | crates/ra_hir_def/src/body/scope.rs | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs index e48ff38f9..661f00407 100644 --- a/crates/ra_hir_def/src/body/scope.rs +++ b/crates/ra_hir_def/src/body/scope.rs | |||
@@ -87,15 +87,13 @@ impl ExprScopes { | |||
87 | } | 87 | } |
88 | 88 | ||
89 | fn add_bindings(&mut self, body: &Body, scope: ScopeId, pat: PatId) { | 89 | fn add_bindings(&mut self, body: &Body, scope: ScopeId, pat: PatId) { |
90 | match &body[pat] { | 90 | let pattern = &body[pat]; |
91 | Pat::Bind { name, .. } => { | 91 | if let Pat::Bind { name, .. } = pattern { |
92 | // bind can have a sub pattern, but it's actually not allowed | 92 | let entry = ScopeEntry { name: name.clone(), pat }; |
93 | // to bind to things in there | 93 | self.scopes[scope].entries.push(entry); |
94 | let entry = ScopeEntry { name: name.clone(), pat }; | ||
95 | self.scopes[scope].entries.push(entry) | ||
96 | } | ||
97 | p => p.walk_child_pats(|pat| self.add_bindings(body, scope, pat)), | ||
98 | } | 94 | } |
95 | |||
96 | pattern.walk_child_pats(|pat| self.add_bindings(body, scope, pat)); | ||
99 | } | 97 | } |
100 | 98 | ||
101 | fn add_params_bindings(&mut self, body: &Body, scope: ScopeId, params: &[PatId]) { | 99 | fn add_params_bindings(&mut self, body: &Body, scope: ScopeId, params: &[PatId]) { |
@@ -190,8 +188,8 @@ mod tests { | |||
190 | } | 188 | } |
191 | } | 189 | } |
192 | 190 | ||
193 | fn do_check(code: &str, expected: &[&str]) { | 191 | fn do_check(ra_fixture: &str, expected: &[&str]) { |
194 | let (off, code) = extract_offset(code); | 192 | let (off, code) = extract_offset(ra_fixture); |
195 | let code = { | 193 | let code = { |
196 | let mut buf = String::new(); | 194 | let mut buf = String::new(); |
197 | let off: usize = off.into(); | 195 | let off: usize = off.into(); |
@@ -300,6 +298,22 @@ mod tests { | |||
300 | ); | 298 | ); |
301 | } | 299 | } |
302 | 300 | ||
301 | #[test] | ||
302 | fn test_bindings_after_at() { | ||
303 | do_check( | ||
304 | r" | ||
305 | fn foo() { | ||
306 | match Some(()) { | ||
307 | opt @ Some(unit) => { | ||
308 | <|> | ||
309 | } | ||
310 | _ => {} | ||
311 | } | ||
312 | }", | ||
313 | &["opt", "unit"], | ||
314 | ); | ||
315 | } | ||
316 | |||
303 | fn do_check_local_name(code: &str, expected_offset: u32) { | 317 | fn do_check_local_name(code: &str, expected_offset: u32) { |
304 | let (off, code) = extract_offset(code); | 318 | let (off, code) = extract_offset(code); |
305 | 319 | ||