aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/expr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/expr.rs')
-rw-r--r--crates/ra_hir/src/expr.rs49
1 files changed, 48 insertions, 1 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index e7235c1a1..4d372c97b 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -329,6 +329,43 @@ impl Expr {
329pub struct PatId(RawId); 329pub struct PatId(RawId);
330impl_arena_id!(PatId); 330impl_arena_id!(PatId);
331 331
332// copied verbatim from librustc::hir
333
334/// Explicit binding annotations given in the HIR for a binding. Note
335/// that this is not the final binding *mode* that we infer after type
336/// inference.
337#[derive(Clone, PartialEq, Eq, Debug, Copy)]
338pub enum BindingAnnotation {
339 /// No binding annotation given: this means that the final binding mode
340 /// will depend on whether we have skipped through a `&` reference
341 /// when matching. For example, the `x` in `Some(x)` will have binding
342 /// mode `None`; if you do `let Some(x) = &Some(22)`, it will
343 /// ultimately be inferred to be by-reference.
344 ///
345 /// Note that implicit reference skipping is not implemented yet (#42640).
346 Unannotated,
347
348 /// Annotated with `mut x` -- could be either ref or not, similar to `None`.
349 Mutable,
350
351 /// Annotated as `ref`, like `ref x`
352 Ref,
353
354 /// Annotated as `ref mut x`.
355 RefMut,
356}
357
358impl BindingAnnotation {
359 fn new(is_mutable: bool, is_ref: bool) -> Self {
360 match (is_mutable, is_ref) {
361 (true, true) => BindingAnnotation::RefMut,
362 (false, true) => BindingAnnotation::Ref,
363 (true, false) => BindingAnnotation::Mutable,
364 (false, false) => BindingAnnotation::Unannotated,
365 }
366 }
367}
368
332#[derive(Debug, Clone, Eq, PartialEq)] 369#[derive(Debug, Clone, Eq, PartialEq)]
333pub struct FieldPat { 370pub struct FieldPat {
334 pub(crate) name: Name, 371 pub(crate) name: Name,
@@ -359,7 +396,9 @@ pub enum Pat {
359 Path(Path), 396 Path(Path),
360 Lit(ExprId), 397 Lit(ExprId),
361 Bind { 398 Bind {
399 mode: BindingAnnotation,
362 name: Name, 400 name: Name,
401 sub_pat: Option<PatId>,
363 }, 402 },
364 TupleStruct { 403 TupleStruct {
365 path: Option<Path>, 404 path: Option<Path>,
@@ -793,7 +832,13 @@ impl ExprCollector {
793 .name() 832 .name()
794 .map(|nr| nr.as_name()) 833 .map(|nr| nr.as_name())
795 .unwrap_or_else(Name::missing); 834 .unwrap_or_else(Name::missing);
796 Pat::Bind { name } 835 let annotation = BindingAnnotation::new(bp.is_mutable(), bp.is_ref());
836 let sub_pat = bp.pat().map(|subpat| self.collect_pat(subpat));
837 Pat::Bind {
838 name,
839 mode: annotation,
840 sub_pat,
841 }
797 } 842 }
798 ast::PatKind::TupleStructPat(p) => { 843 ast::PatKind::TupleStructPat(p) => {
799 let path = p.path().and_then(Path::from_ast); 844 let path = p.path().and_then(Path::from_ast);
@@ -882,6 +927,8 @@ pub(crate) fn collect_fn_body_syntax(node: &ast::FnDef) -> BodySyntaxMapping {
882 let param = collector.alloc_pat( 927 let param = collector.alloc_pat(
883 Pat::Bind { 928 Pat::Bind {
884 name: Name::self_param(), 929 name: Name::self_param(),
930 mode: BindingAnnotation::Unannotated,
931 sub_pat: None,
885 }, 932 },
886 self_param, 933 self_param,
887 ); 934 );