aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/body
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/body')
-rw-r--r--crates/ra_hir_def/src/body/lower.rs80
1 files changed, 35 insertions, 45 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index 9d6ee095e..79abe55ce 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -2,9 +2,7 @@
2//! representation. 2//! representation.
3 3
4use either::Either; 4use either::Either;
5
6use hir_expand::{ 5use hir_expand::{
7 hygiene::Hygiene,
8 name::{name, AsName, Name}, 6 name::{name, AsName, Name},
9 MacroDefId, MacroDefKind, 7 MacroDefId, MacroDefKind,
10}; 8};
@@ -18,10 +16,8 @@ use ra_syntax::{
18}; 16};
19use test_utils::tested_by; 17use test_utils::tested_by;
20 18
21use super::{ExprSource, PatSource};
22use crate::{ 19use crate::{
23 adt::StructKind, 20 adt::StructKind,
24 attr::Attrs,
25 body::{Body, BodySourceMap, Expander, PatPtr, SyntheticSyntax}, 21 body::{Body, BodySourceMap, Expander, PatPtr, SyntheticSyntax},
26 builtin_type::{BuiltinFloat, BuiltinInt}, 22 builtin_type::{BuiltinFloat, BuiltinInt},
27 db::DefDatabase, 23 db::DefDatabase,
@@ -31,12 +27,14 @@ use crate::{
31 }, 27 },
32 item_scope::BuiltinShadowMode, 28 item_scope::BuiltinShadowMode,
33 path::GenericArgs, 29 path::GenericArgs,
34 path::Path,
35 type_ref::{Mutability, TypeRef}, 30 type_ref::{Mutability, TypeRef},
36 AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, HasModule, Intern, 31 AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId,
37 ModuleDefId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, 32 StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc,
38}; 33};
39 34
35use super::{ExprSource, PatSource};
36use ast::AstChildren;
37
40pub(super) fn lower( 38pub(super) fn lower(
41 db: &dyn DefDatabase, 39 db: &dyn DefDatabase,
42 def: DefWithBodyId, 40 def: DefWithBodyId,
@@ -104,7 +102,6 @@ impl ExprCollector<'_> {
104 } 102 }
105 103
106 fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId { 104 fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId {
107 let ptr = Either::Left(ptr);
108 let src = self.expander.to_source(ptr); 105 let src = self.expander.to_source(ptr);
109 let id = self.make_expr(expr, Ok(src.clone())); 106 let id = self.make_expr(expr, Ok(src.clone()));
110 self.source_map.expr_map.insert(src, id); 107 self.source_map.expr_map.insert(src, id);
@@ -115,13 +112,6 @@ impl ExprCollector<'_> {
115 fn alloc_expr_desugared(&mut self, expr: Expr) -> ExprId { 112 fn alloc_expr_desugared(&mut self, expr: Expr) -> ExprId {
116 self.make_expr(expr, Err(SyntheticSyntax)) 113 self.make_expr(expr, Err(SyntheticSyntax))
117 } 114 }
118 fn alloc_expr_field_shorthand(&mut self, expr: Expr, ptr: AstPtr<ast::RecordField>) -> ExprId {
119 let ptr = Either::Right(ptr);
120 let src = self.expander.to_source(ptr);
121 let id = self.make_expr(expr, Ok(src.clone()));
122 self.source_map.expr_map.insert(src, id);
123 id
124 }
125 fn empty_block(&mut self) -> ExprId { 115 fn empty_block(&mut self) -> ExprId {
126 self.alloc_expr_desugared(Expr::Block { statements: Vec::new(), tail: None }) 116 self.alloc_expr_desugared(Expr::Block { statements: Vec::new(), tail: None })
127 } 117 }
@@ -291,7 +281,7 @@ impl ExprCollector<'_> {
291 ast::Expr::ParenExpr(e) => { 281 ast::Expr::ParenExpr(e) => {
292 let inner = self.collect_expr_opt(e.expr()); 282 let inner = self.collect_expr_opt(e.expr());
293 // make the paren expr point to the inner expression as well 283 // make the paren expr point to the inner expression as well
294 let src = self.expander.to_source(Either::Left(syntax_ptr)); 284 let src = self.expander.to_source(syntax_ptr);
295 self.source_map.expr_map.insert(src, inner); 285 self.source_map.expr_map.insert(src, inner);
296 inner 286 inner
297 } 287 }
@@ -300,7 +290,6 @@ impl ExprCollector<'_> {
300 self.alloc_expr(Expr::Return { expr }, syntax_ptr) 290 self.alloc_expr(Expr::Return { expr }, syntax_ptr)
301 } 291 }
302 ast::Expr::RecordLit(e) => { 292 ast::Expr::RecordLit(e) => {
303 let crate_graph = self.db.crate_graph();
304 let path = e.path().and_then(|path| self.expander.parse_path(path)); 293 let path = e.path().and_then(|path| self.expander.parse_path(path));
305 let mut field_ptrs = Vec::new(); 294 let mut field_ptrs = Vec::new();
306 let record_lit = if let Some(nfl) = e.record_field_list() { 295 let record_lit = if let Some(nfl) = e.record_field_list() {
@@ -308,31 +297,17 @@ impl ExprCollector<'_> {
308 .fields() 297 .fields()
309 .inspect(|field| field_ptrs.push(AstPtr::new(field))) 298 .inspect(|field| field_ptrs.push(AstPtr::new(field)))
310 .filter_map(|field| { 299 .filter_map(|field| {
311 let module_id = ContainerId::DefWithBodyId(self.def).module(self.db); 300 let attrs = self.expander.parse_attrs(&field);
312 let attrs = Attrs::new( 301 if !self.expander.is_cfg_enabled(&attrs) {
313 &field,
314 &Hygiene::new(self.db.upcast(), self.expander.current_file_id),
315 );
316
317 if !attrs.is_cfg_enabled(&crate_graph[module_id.krate].cfg_options) {
318 return None; 302 return None;
319 } 303 }
304 let name = field.field_name()?.as_name();
320 305
321 Some(RecordLitField { 306 Some(RecordLitField {
322 name: field 307 name,
323 .name_ref() 308 expr: match field.expr() {
324 .map(|nr| nr.as_name()) 309 Some(e) => self.collect_expr(e),
325 .unwrap_or_else(Name::missing), 310 None => self.missing_expr(),
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 }, 311 },
337 }) 312 })
338 }) 313 })
@@ -624,8 +599,8 @@ impl ExprCollector<'_> {
624 } 599 }
625 ast::Pat::TupleStructPat(p) => { 600 ast::Pat::TupleStructPat(p) => {
626 let path = p.path().and_then(|path| self.expander.parse_path(path)); 601 let path = p.path().and_then(|path| self.expander.parse_path(path));
627 let args = p.args().map(|p| self.collect_pat(p)).collect(); 602 let (args, ellipsis) = self.collect_tuple_pat(p.args());
628 Pat::TupleStruct { path, args } 603 Pat::TupleStruct { path, args, ellipsis }
629 } 604 }
630 ast::Pat::RefPat(p) => { 605 ast::Pat::RefPat(p) => {
631 let pat = self.collect_pat_opt(p.pat()); 606 let pat = self.collect_pat_opt(p.pat());
@@ -642,10 +617,10 @@ impl ExprCollector<'_> {
642 } 617 }
643 ast::Pat::ParenPat(p) => return self.collect_pat_opt(p.pat()), 618 ast::Pat::ParenPat(p) => return self.collect_pat_opt(p.pat()),
644 ast::Pat::TuplePat(p) => { 619 ast::Pat::TuplePat(p) => {
645 let args = p.args().map(|p| self.collect_pat(p)).collect(); 620 let (args, ellipsis) = self.collect_tuple_pat(p.args());
646 Pat::Tuple(args) 621 Pat::Tuple { args, ellipsis }
647 } 622 }
648 ast::Pat::PlaceholderPat(_) | ast::Pat::DotDotPat(_) => Pat::Wild, 623 ast::Pat::PlaceholderPat(_) => Pat::Wild,
649 ast::Pat::RecordPat(p) => { 624 ast::Pat::RecordPat(p) => {
650 let path = p.path().and_then(|path| self.expander.parse_path(path)); 625 let path = p.path().and_then(|path| self.expander.parse_path(path));
651 let record_field_pat_list = 626 let record_field_pat_list =
@@ -663,7 +638,7 @@ impl ExprCollector<'_> {
663 let iter = record_field_pat_list.record_field_pats().filter_map(|f| { 638 let iter = record_field_pat_list.record_field_pats().filter_map(|f| {
664 let ast_pat = f.pat()?; 639 let ast_pat = f.pat()?;
665 let pat = self.collect_pat(ast_pat); 640 let pat = self.collect_pat(ast_pat);
666 let name = f.name()?.as_name(); 641 let name = f.field_name()?.as_name();
667 Some(RecordFieldPat { name, pat }) 642 Some(RecordFieldPat { name, pat })
668 }); 643 });
669 fields.extend(iter); 644 fields.extend(iter);
@@ -691,7 +666,9 @@ impl ExprCollector<'_> {
691 Pat::Missing 666 Pat::Missing
692 } 667 }
693 } 668 }
694 669 ast::Pat::DotDotPat(_) => unreachable!(
670 "`DotDotPat` requires special handling and should not be mapped to a Pat."
671 ),
695 // FIXME: implement 672 // FIXME: implement
696 ast::Pat::BoxPat(_) | ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing, 673 ast::Pat::BoxPat(_) | ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing,
697 }; 674 };
@@ -706,6 +683,19 @@ impl ExprCollector<'_> {
706 self.missing_pat() 683 self.missing_pat()
707 } 684 }
708 } 685 }
686
687 fn collect_tuple_pat(&mut self, args: AstChildren<ast::Pat>) -> (Vec<PatId>, Option<usize>) {
688 // Find the location of the `..`, if there is one. Note that we do not
689 // consider the possiblity of there being multiple `..` here.
690 let ellipsis = args.clone().position(|p| matches!(p, ast::Pat::DotDotPat(_)));
691 // We want to skip the `..` pattern here, since we account for it above.
692 let args = args
693 .filter(|p| !matches!(p, ast::Pat::DotDotPat(_)))
694 .map(|p| self.collect_pat(p))
695 .collect();
696
697 (args, ellipsis)
698 }
709} 699}
710 700
711impl From<ast::BinOp> for BinaryOp { 701impl From<ast::BinOp> for BinaryOp {