diff options
Diffstat (limited to 'crates/ra_hir_def/src/body/lower.rs')
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index f467ed3fe..e9dd65b0a 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -3,8 +3,9 @@ | |||
3 | 3 | ||
4 | use either::Either; | 4 | use either::Either; |
5 | use hir_expand::{ | 5 | use hir_expand::{ |
6 | hygiene::Hygiene, | ||
6 | name::{name, AsName, Name}, | 7 | name::{name, AsName, Name}, |
7 | MacroDefId, MacroDefKind, | 8 | HirFileId, MacroDefId, MacroDefKind, |
8 | }; | 9 | }; |
9 | use ra_arena::Arena; | 10 | use ra_arena::Arena; |
10 | use ra_syntax::{ | 11 | use ra_syntax::{ |
@@ -26,7 +27,7 @@ use crate::{ | |||
26 | LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, | 27 | LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, |
27 | }, | 28 | }, |
28 | item_scope::BuiltinShadowMode, | 29 | item_scope::BuiltinShadowMode, |
29 | path::GenericArgs, | 30 | path::{GenericArgs, Path}, |
30 | type_ref::{Mutability, TypeRef}, | 31 | type_ref::{Mutability, TypeRef}, |
31 | AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, | 32 | AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, |
32 | StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, | 33 | StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, |
@@ -35,6 +36,23 @@ use crate::{ | |||
35 | use super::{ExprSource, PatSource}; | 36 | use super::{ExprSource, PatSource}; |
36 | use ast::AstChildren; | 37 | use ast::AstChildren; |
37 | 38 | ||
39 | pub(crate) struct LowerCtx { | ||
40 | hygiene: Hygiene, | ||
41 | } | ||
42 | |||
43 | impl LowerCtx { | ||
44 | pub fn new(db: &dyn DefDatabase, file_id: HirFileId) -> Self { | ||
45 | LowerCtx { hygiene: Hygiene::new(db.upcast(), file_id) } | ||
46 | } | ||
47 | pub fn with_hygiene(hygiene: &Hygiene) -> Self { | ||
48 | LowerCtx { hygiene: hygiene.clone() } | ||
49 | } | ||
50 | |||
51 | pub fn lower_path(&self, ast: ast::Path) -> Option<Path> { | ||
52 | Path::from_src(ast, &self.hygiene) | ||
53 | } | ||
54 | } | ||
55 | |||
38 | pub(super) fn lower( | 56 | pub(super) fn lower( |
39 | db: &dyn DefDatabase, | 57 | db: &dyn DefDatabase, |
40 | def: DefWithBodyId, | 58 | def: DefWithBodyId, |
@@ -42,10 +60,13 @@ pub(super) fn lower( | |||
42 | params: Option<ast::ParamList>, | 60 | params: Option<ast::ParamList>, |
43 | body: Option<ast::Expr>, | 61 | body: Option<ast::Expr>, |
44 | ) -> (Body, BodySourceMap) { | 62 | ) -> (Body, BodySourceMap) { |
63 | let ctx = LowerCtx::new(db, expander.current_file_id.clone()); | ||
64 | |||
45 | ExprCollector { | 65 | ExprCollector { |
46 | db, | 66 | db, |
47 | def, | 67 | def, |
48 | expander, | 68 | expander, |
69 | ctx, | ||
49 | source_map: BodySourceMap::default(), | 70 | source_map: BodySourceMap::default(), |
50 | body: Body { | 71 | body: Body { |
51 | exprs: Arena::default(), | 72 | exprs: Arena::default(), |
@@ -62,7 +83,7 @@ struct ExprCollector<'a> { | |||
62 | db: &'a dyn DefDatabase, | 83 | db: &'a dyn DefDatabase, |
63 | def: DefWithBodyId, | 84 | def: DefWithBodyId, |
64 | expander: Expander, | 85 | expander: Expander, |
65 | 86 | ctx: LowerCtx, | |
66 | body: Body, | 87 | body: Body, |
67 | source_map: BodySourceMap, | 88 | source_map: BodySourceMap, |
68 | } | 89 | } |
@@ -237,7 +258,8 @@ impl ExprCollector<'_> { | |||
237 | Vec::new() | 258 | Vec::new() |
238 | }; | 259 | }; |
239 | let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); | 260 | let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); |
240 | let generic_args = e.type_arg_list().and_then(GenericArgs::from_ast); | 261 | let generic_args = |
262 | e.type_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx, it)); | ||
241 | self.alloc_expr( | 263 | self.alloc_expr( |
242 | Expr::MethodCall { receiver, method_name, args, generic_args }, | 264 | Expr::MethodCall { receiver, method_name, args, generic_args }, |
243 | syntax_ptr, | 265 | syntax_ptr, |
@@ -343,7 +365,7 @@ impl ExprCollector<'_> { | |||
343 | } | 365 | } |
344 | ast::Expr::CastExpr(e) => { | 366 | ast::Expr::CastExpr(e) => { |
345 | let expr = self.collect_expr_opt(e.expr()); | 367 | let expr = self.collect_expr_opt(e.expr()); |
346 | let type_ref = TypeRef::from_ast_opt(e.type_ref()); | 368 | let type_ref = TypeRef::from_ast_opt(&self.ctx, e.type_ref()); |
347 | self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) | 369 | self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) |
348 | } | 370 | } |
349 | ast::Expr::RefExpr(e) => { | 371 | ast::Expr::RefExpr(e) => { |
@@ -365,12 +387,16 @@ impl ExprCollector<'_> { | |||
365 | if let Some(pl) = e.param_list() { | 387 | if let Some(pl) = e.param_list() { |
366 | for param in pl.params() { | 388 | for param in pl.params() { |
367 | let pat = self.collect_pat_opt(param.pat()); | 389 | let pat = self.collect_pat_opt(param.pat()); |
368 | let type_ref = param.ascribed_type().map(TypeRef::from_ast); | 390 | let type_ref = |
391 | param.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it)); | ||
369 | args.push(pat); | 392 | args.push(pat); |
370 | arg_types.push(type_ref); | 393 | arg_types.push(type_ref); |
371 | } | 394 | } |
372 | } | 395 | } |
373 | let ret_type = e.ret_type().and_then(|r| r.type_ref()).map(TypeRef::from_ast); | 396 | let ret_type = e |
397 | .ret_type() | ||
398 | .and_then(|r| r.type_ref()) | ||
399 | .map(|it| TypeRef::from_ast(&self.ctx, it)); | ||
374 | let body = self.collect_expr_opt(e.body()); | 400 | let body = self.collect_expr_opt(e.body()); |
375 | self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) | 401 | self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) |
376 | } | 402 | } |
@@ -476,7 +502,7 @@ impl ExprCollector<'_> { | |||
476 | .map(|s| match s { | 502 | .map(|s| match s { |
477 | ast::Stmt::LetStmt(stmt) => { | 503 | ast::Stmt::LetStmt(stmt) => { |
478 | let pat = self.collect_pat_opt(stmt.pat()); | 504 | let pat = self.collect_pat_opt(stmt.pat()); |
479 | let type_ref = stmt.ascribed_type().map(TypeRef::from_ast); | 505 | let type_ref = stmt.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it)); |
480 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); | 506 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); |
481 | Statement::Let { pat, type_ref, initializer } | 507 | Statement::Let { pat, type_ref, initializer } |
482 | } | 508 | } |