diff options
Diffstat (limited to 'crates/ra_hir_def/src/body/lower.rs')
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 71 |
1 files changed, 43 insertions, 28 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index c4a5ec59c..9d6ee095e 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -4,6 +4,7 @@ | |||
4 | use either::Either; | 4 | use either::Either; |
5 | 5 | ||
6 | use hir_expand::{ | 6 | use hir_expand::{ |
7 | hygiene::Hygiene, | ||
7 | name::{name, AsName, Name}, | 8 | name::{name, AsName, Name}, |
8 | MacroDefId, MacroDefKind, | 9 | MacroDefId, MacroDefKind, |
9 | }; | 10 | }; |
@@ -20,6 +21,7 @@ use test_utils::tested_by; | |||
20 | use super::{ExprSource, PatSource}; | 21 | use super::{ExprSource, PatSource}; |
21 | use crate::{ | 22 | use crate::{ |
22 | adt::StructKind, | 23 | adt::StructKind, |
24 | attr::Attrs, | ||
23 | body::{Body, BodySourceMap, Expander, PatPtr, SyntheticSyntax}, | 25 | body::{Body, BodySourceMap, Expander, PatPtr, SyntheticSyntax}, |
24 | builtin_type::{BuiltinFloat, BuiltinInt}, | 26 | builtin_type::{BuiltinFloat, BuiltinInt}, |
25 | db::DefDatabase, | 27 | db::DefDatabase, |
@@ -31,8 +33,8 @@ use crate::{ | |||
31 | path::GenericArgs, | 33 | path::GenericArgs, |
32 | path::Path, | 34 | path::Path, |
33 | type_ref::{Mutability, TypeRef}, | 35 | type_ref::{Mutability, TypeRef}, |
34 | AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, | 36 | AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, HasModule, Intern, |
35 | StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, | 37 | ModuleDefId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, |
36 | }; | 38 | }; |
37 | 39 | ||
38 | pub(super) fn lower( | 40 | pub(super) fn lower( |
@@ -104,7 +106,7 @@ impl ExprCollector<'_> { | |||
104 | fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId { | 106 | fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId { |
105 | let ptr = Either::Left(ptr); | 107 | let ptr = Either::Left(ptr); |
106 | let src = self.expander.to_source(ptr); | 108 | let src = self.expander.to_source(ptr); |
107 | let id = self.make_expr(expr, Ok(src)); | 109 | let id = self.make_expr(expr, Ok(src.clone())); |
108 | self.source_map.expr_map.insert(src, id); | 110 | self.source_map.expr_map.insert(src, id); |
109 | id | 111 | id |
110 | } | 112 | } |
@@ -116,7 +118,7 @@ impl ExprCollector<'_> { | |||
116 | fn alloc_expr_field_shorthand(&mut self, expr: Expr, ptr: AstPtr<ast::RecordField>) -> ExprId { | 118 | fn alloc_expr_field_shorthand(&mut self, expr: Expr, ptr: AstPtr<ast::RecordField>) -> ExprId { |
117 | let ptr = Either::Right(ptr); | 119 | let ptr = Either::Right(ptr); |
118 | let src = self.expander.to_source(ptr); | 120 | let src = self.expander.to_source(ptr); |
119 | let id = self.make_expr(expr, Ok(src)); | 121 | let id = self.make_expr(expr, Ok(src.clone())); |
120 | self.source_map.expr_map.insert(src, id); | 122 | self.source_map.expr_map.insert(src, id); |
121 | id | 123 | id |
122 | } | 124 | } |
@@ -134,7 +136,7 @@ impl ExprCollector<'_> { | |||
134 | 136 | ||
135 | fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId { | 137 | fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId { |
136 | let src = self.expander.to_source(ptr); | 138 | let src = self.expander.to_source(ptr); |
137 | let id = self.make_pat(pat, Ok(src)); | 139 | let id = self.make_pat(pat, Ok(src.clone())); |
138 | self.source_map.pat_map.insert(src, id); | 140 | self.source_map.pat_map.insert(src, id); |
139 | id | 141 | id |
140 | } | 142 | } |
@@ -298,28 +300,41 @@ impl ExprCollector<'_> { | |||
298 | self.alloc_expr(Expr::Return { expr }, syntax_ptr) | 300 | self.alloc_expr(Expr::Return { expr }, syntax_ptr) |
299 | } | 301 | } |
300 | ast::Expr::RecordLit(e) => { | 302 | ast::Expr::RecordLit(e) => { |
303 | let crate_graph = self.db.crate_graph(); | ||
301 | let path = e.path().and_then(|path| self.expander.parse_path(path)); | 304 | let path = e.path().and_then(|path| self.expander.parse_path(path)); |
302 | let mut field_ptrs = Vec::new(); | 305 | let mut field_ptrs = Vec::new(); |
303 | let record_lit = if let Some(nfl) = e.record_field_list() { | 306 | let record_lit = if let Some(nfl) = e.record_field_list() { |
304 | let fields = nfl | 307 | let fields = nfl |
305 | .fields() | 308 | .fields() |
306 | .inspect(|field| field_ptrs.push(AstPtr::new(field))) | 309 | .inspect(|field| field_ptrs.push(AstPtr::new(field))) |
307 | .map(|field| RecordLitField { | 310 | .filter_map(|field| { |
308 | name: field | 311 | let module_id = ContainerId::DefWithBodyId(self.def).module(self.db); |
309 | .name_ref() | 312 | let attrs = Attrs::new( |
310 | .map(|nr| nr.as_name()) | 313 | &field, |
311 | .unwrap_or_else(Name::missing), | 314 | &Hygiene::new(self.db.upcast(), self.expander.current_file_id), |
312 | expr: if let Some(e) = field.expr() { | 315 | ); |
313 | self.collect_expr(e) | 316 | |
314 | } else if let Some(nr) = field.name_ref() { | 317 | if !attrs.is_cfg_enabled(&crate_graph[module_id.krate].cfg_options) { |
315 | // field shorthand | 318 | return None; |
316 | self.alloc_expr_field_shorthand( | 319 | } |
317 | Expr::Path(Path::from_name_ref(&nr)), | 320 | |
318 | AstPtr::new(&field), | 321 | Some(RecordLitField { |
319 | ) | 322 | name: field |
320 | } else { | 323 | .name_ref() |
321 | self.missing_expr() | 324 | .map(|nr| nr.as_name()) |
322 | }, | 325 | .unwrap_or_else(Name::missing), |
326 | expr: if let Some(e) = field.expr() { | ||
327 | self.collect_expr(e) | ||
328 | } else if let Some(nr) = field.name_ref() { | ||
329 | // field shorthand | ||
330 | self.alloc_expr_field_shorthand( | ||
331 | Expr::Path(Path::from_name_ref(&nr)), | ||
332 | AstPtr::new(&field), | ||
333 | ) | ||
334 | } else { | ||
335 | self.missing_expr() | ||
336 | }, | ||
337 | }) | ||
323 | }) | 338 | }) |
324 | .collect(); | 339 | .collect(); |
325 | let spread = nfl.spread().map(|s| self.collect_expr(s)); | 340 | let spread = nfl.spread().map(|s| self.collect_expr(s)); |
@@ -357,7 +372,7 @@ impl ExprCollector<'_> { | |||
357 | } | 372 | } |
358 | ast::Expr::RefExpr(e) => { | 373 | ast::Expr::RefExpr(e) => { |
359 | let expr = self.collect_expr_opt(e.expr()); | 374 | let expr = self.collect_expr_opt(e.expr()); |
360 | let mutability = Mutability::from_mutable(e.is_mut()); | 375 | let mutability = Mutability::from_mutable(e.mut_token().is_some()); |
361 | self.alloc_expr(Expr::Ref { expr, mutability }, syntax_ptr) | 376 | self.alloc_expr(Expr::Ref { expr, mutability }, syntax_ptr) |
362 | } | 377 | } |
363 | ast::Expr::PrefixExpr(e) => { | 378 | ast::Expr::PrefixExpr(e) => { |
@@ -572,10 +587,8 @@ impl ExprCollector<'_> { | |||
572 | let pattern = match &pat { | 587 | let pattern = match &pat { |
573 | ast::Pat::BindPat(bp) => { | 588 | ast::Pat::BindPat(bp) => { |
574 | let name = bp.name().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); | 589 | let name = bp.name().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); |
575 | let annotation = BindingAnnotation::new( | 590 | let annotation = |
576 | bp.mut_kw_token().is_some(), | 591 | BindingAnnotation::new(bp.mut_token().is_some(), bp.ref_token().is_some()); |
577 | bp.ref_kw_token().is_some(), | ||
578 | ); | ||
579 | let subpat = bp.pat().map(|subpat| self.collect_pat(subpat)); | 592 | let subpat = bp.pat().map(|subpat| self.collect_pat(subpat)); |
580 | if annotation == BindingAnnotation::Unannotated && subpat.is_none() { | 593 | if annotation == BindingAnnotation::Unannotated && subpat.is_none() { |
581 | // This could also be a single-segment path pattern. To | 594 | // This could also be a single-segment path pattern. To |
@@ -616,7 +629,7 @@ impl ExprCollector<'_> { | |||
616 | } | 629 | } |
617 | ast::Pat::RefPat(p) => { | 630 | ast::Pat::RefPat(p) => { |
618 | let pat = self.collect_pat_opt(p.pat()); | 631 | let pat = self.collect_pat_opt(p.pat()); |
619 | let mutability = Mutability::from_mutable(p.mut_kw_token().is_some()); | 632 | let mutability = Mutability::from_mutable(p.mut_token().is_some()); |
620 | Pat::Ref { pat, mutability } | 633 | Pat::Ref { pat, mutability } |
621 | } | 634 | } |
622 | ast::Pat::PathPat(p) => { | 635 | ast::Pat::PathPat(p) => { |
@@ -655,7 +668,9 @@ impl ExprCollector<'_> { | |||
655 | }); | 668 | }); |
656 | fields.extend(iter); | 669 | fields.extend(iter); |
657 | 670 | ||
658 | Pat::Record { path, args: fields } | 671 | let ellipsis = record_field_pat_list.dotdot_token().is_some(); |
672 | |||
673 | Pat::Record { path, args: fields, ellipsis } | ||
659 | } | 674 | } |
660 | ast::Pat::SlicePat(p) => { | 675 | ast::Pat::SlicePat(p) => { |
661 | let SlicePatComponents { prefix, slice, suffix } = p.components(); | 676 | let SlicePatComponents { prefix, slice, suffix } = p.components(); |