diff options
Diffstat (limited to 'crates/ra_hir_def/src/body/lower.rs')
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 80 |
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 | ||
4 | use either::Either; | 4 | use either::Either; |
5 | |||
6 | use hir_expand::{ | 5 | use 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 | }; |
19 | use test_utils::tested_by; | 17 | use test_utils::tested_by; |
20 | 18 | ||
21 | use super::{ExprSource, PatSource}; | ||
22 | use crate::{ | 19 | use 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 | ||
35 | use super::{ExprSource, PatSource}; | ||
36 | use ast::AstChildren; | ||
37 | |||
40 | pub(super) fn lower( | 38 | pub(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 | ||
711 | impl From<ast::BinOp> for BinaryOp { | 701 | impl From<ast::BinOp> for BinaryOp { |