aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/body/lower.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/body/lower.rs')
-rw-r--r--crates/ra_hir_def/src/body/lower.rs71
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 @@
4use either::Either; 4use either::Either;
5 5
6use hir_expand::{ 6use 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;
20use super::{ExprSource, PatSource}; 21use super::{ExprSource, PatSource};
21use crate::{ 22use 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
38pub(super) fn lower( 40pub(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();