diff options
Diffstat (limited to 'crates/ra_hir_def/src/body')
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 63 | ||||
-rw-r--r-- | crates/ra_hir_def/src/body/scope.rs | 4 |
2 files changed, 40 insertions, 27 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index e9dd65b0a..e08d62dd6 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -15,7 +15,7 @@ use ra_syntax::{ | |||
15 | }, | 15 | }, |
16 | AstNode, AstPtr, | 16 | AstNode, AstPtr, |
17 | }; | 17 | }; |
18 | use test_utils::tested_by; | 18 | use test_utils::mark; |
19 | 19 | ||
20 | use crate::{ | 20 | use crate::{ |
21 | adt::StructKind, | 21 | adt::StructKind, |
@@ -60,13 +60,10 @@ pub(super) fn lower( | |||
60 | params: Option<ast::ParamList>, | 60 | params: Option<ast::ParamList>, |
61 | body: Option<ast::Expr>, | 61 | body: Option<ast::Expr>, |
62 | ) -> (Body, BodySourceMap) { | 62 | ) -> (Body, BodySourceMap) { |
63 | let ctx = LowerCtx::new(db, expander.current_file_id.clone()); | ||
64 | |||
65 | ExprCollector { | 63 | ExprCollector { |
66 | db, | 64 | db, |
67 | def, | 65 | def, |
68 | expander, | 66 | expander, |
69 | ctx, | ||
70 | source_map: BodySourceMap::default(), | 67 | source_map: BodySourceMap::default(), |
71 | body: Body { | 68 | body: Body { |
72 | exprs: Arena::default(), | 69 | exprs: Arena::default(), |
@@ -83,7 +80,6 @@ struct ExprCollector<'a> { | |||
83 | db: &'a dyn DefDatabase, | 80 | db: &'a dyn DefDatabase, |
84 | def: DefWithBodyId, | 81 | def: DefWithBodyId, |
85 | expander: Expander, | 82 | expander: Expander, |
86 | ctx: LowerCtx, | ||
87 | body: Body, | 83 | body: Body, |
88 | source_map: BodySourceMap, | 84 | source_map: BodySourceMap, |
89 | } | 85 | } |
@@ -122,6 +118,10 @@ impl ExprCollector<'_> { | |||
122 | (self.body, self.source_map) | 118 | (self.body, self.source_map) |
123 | } | 119 | } |
124 | 120 | ||
121 | fn ctx(&self) -> LowerCtx { | ||
122 | LowerCtx::new(self.db, self.expander.current_file_id) | ||
123 | } | ||
124 | |||
125 | fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId { | 125 | fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId { |
126 | let src = self.expander.to_source(ptr); | 126 | let src = self.expander.to_source(ptr); |
127 | let id = self.make_expr(expr, Ok(src.clone())); | 127 | let id = self.make_expr(expr, Ok(src.clone())); |
@@ -162,8 +162,7 @@ impl ExprCollector<'_> { | |||
162 | 162 | ||
163 | fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { | 163 | fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { |
164 | let syntax_ptr = AstPtr::new(&expr); | 164 | let syntax_ptr = AstPtr::new(&expr); |
165 | let attrs = self.expander.parse_attrs(&expr); | 165 | if !self.expander.is_cfg_enabled(&expr) { |
166 | if !self.expander.is_cfg_enabled(&attrs) { | ||
167 | return self.missing_expr(); | 166 | return self.missing_expr(); |
168 | } | 167 | } |
169 | match expr { | 168 | match expr { |
@@ -203,6 +202,16 @@ impl ExprCollector<'_> { | |||
203 | 202 | ||
204 | self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr) | 203 | self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr) |
205 | } | 204 | } |
205 | ast::Expr::EffectExpr(e) => match e.effect() { | ||
206 | ast::Effect::Try(_) => { | ||
207 | let body = self.collect_block_opt(e.block_expr()); | ||
208 | self.alloc_expr(Expr::TryBlock { body }, syntax_ptr) | ||
209 | } | ||
210 | // FIXME: we need to record these effects somewhere... | ||
211 | ast::Effect::Async(_) | ast::Effect::Label(_) | ast::Effect::Unsafe(_) => { | ||
212 | self.collect_block_opt(e.block_expr()) | ||
213 | } | ||
214 | }, | ||
206 | ast::Expr::BlockExpr(e) => self.collect_block(e), | 215 | ast::Expr::BlockExpr(e) => self.collect_block(e), |
207 | ast::Expr::LoopExpr(e) => { | 216 | ast::Expr::LoopExpr(e) => { |
208 | let body = self.collect_block_opt(e.loop_body()); | 217 | let body = self.collect_block_opt(e.loop_body()); |
@@ -217,7 +226,7 @@ impl ExprCollector<'_> { | |||
217 | None => self.collect_expr_opt(condition.expr()), | 226 | None => self.collect_expr_opt(condition.expr()), |
218 | // if let -- desugar to match | 227 | // if let -- desugar to match |
219 | Some(pat) => { | 228 | Some(pat) => { |
220 | tested_by!(infer_resolve_while_let); | 229 | mark::hit!(infer_resolve_while_let); |
221 | let pat = self.collect_pat(pat); | 230 | let pat = self.collect_pat(pat); |
222 | let match_expr = self.collect_expr_opt(condition.expr()); | 231 | let match_expr = self.collect_expr_opt(condition.expr()); |
223 | let placeholder_pat = self.missing_pat(); | 232 | let placeholder_pat = self.missing_pat(); |
@@ -259,7 +268,7 @@ impl ExprCollector<'_> { | |||
259 | }; | 268 | }; |
260 | let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); | 269 | let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); |
261 | let generic_args = | 270 | let generic_args = |
262 | e.type_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx, it)); | 271 | e.type_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx(), it)); |
263 | self.alloc_expr( | 272 | self.alloc_expr( |
264 | Expr::MethodCall { receiver, method_name, args, generic_args }, | 273 | Expr::MethodCall { receiver, method_name, args, generic_args }, |
265 | syntax_ptr, | 274 | syntax_ptr, |
@@ -319,8 +328,7 @@ impl ExprCollector<'_> { | |||
319 | .fields() | 328 | .fields() |
320 | .inspect(|field| field_ptrs.push(AstPtr::new(field))) | 329 | .inspect(|field| field_ptrs.push(AstPtr::new(field))) |
321 | .filter_map(|field| { | 330 | .filter_map(|field| { |
322 | let attrs = self.expander.parse_attrs(&field); | 331 | if !self.expander.is_cfg_enabled(&field) { |
323 | if !self.expander.is_cfg_enabled(&attrs) { | ||
324 | return None; | 332 | return None; |
325 | } | 333 | } |
326 | let name = field.field_name()?.as_name(); | 334 | let name = field.field_name()?.as_name(); |
@@ -365,7 +373,7 @@ impl ExprCollector<'_> { | |||
365 | } | 373 | } |
366 | ast::Expr::CastExpr(e) => { | 374 | ast::Expr::CastExpr(e) => { |
367 | let expr = self.collect_expr_opt(e.expr()); | 375 | let expr = self.collect_expr_opt(e.expr()); |
368 | let type_ref = TypeRef::from_ast_opt(&self.ctx, e.type_ref()); | 376 | let type_ref = TypeRef::from_ast_opt(&self.ctx(), e.type_ref()); |
369 | self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) | 377 | self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) |
370 | } | 378 | } |
371 | ast::Expr::RefExpr(e) => { | 379 | ast::Expr::RefExpr(e) => { |
@@ -388,7 +396,7 @@ impl ExprCollector<'_> { | |||
388 | for param in pl.params() { | 396 | for param in pl.params() { |
389 | let pat = self.collect_pat_opt(param.pat()); | 397 | let pat = self.collect_pat_opt(param.pat()); |
390 | let type_ref = | 398 | let type_ref = |
391 | param.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it)); | 399 | param.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx(), it)); |
392 | args.push(pat); | 400 | args.push(pat); |
393 | arg_types.push(type_ref); | 401 | arg_types.push(type_ref); |
394 | } | 402 | } |
@@ -396,7 +404,7 @@ impl ExprCollector<'_> { | |||
396 | let ret_type = e | 404 | let ret_type = e |
397 | .ret_type() | 405 | .ret_type() |
398 | .and_then(|r| r.type_ref()) | 406 | .and_then(|r| r.type_ref()) |
399 | .map(|it| TypeRef::from_ast(&self.ctx, it)); | 407 | .map(|it| TypeRef::from_ast(&self.ctx(), it)); |
400 | let body = self.collect_expr_opt(e.body()); | 408 | let body = self.collect_expr_opt(e.body()); |
401 | self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) | 409 | self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) |
402 | } | 410 | } |
@@ -456,6 +464,7 @@ impl ExprCollector<'_> { | |||
456 | krate: Some(self.expander.module.krate), | 464 | krate: Some(self.expander.module.krate), |
457 | ast_id: Some(self.expander.ast_id(&e)), | 465 | ast_id: Some(self.expander.ast_id(&e)), |
458 | kind: MacroDefKind::Declarative, | 466 | kind: MacroDefKind::Declarative, |
467 | local_inner: false, | ||
459 | }; | 468 | }; |
460 | self.body.item_scope.define_legacy_macro(name, mac); | 469 | self.body.item_scope.define_legacy_macro(name, mac); |
461 | 470 | ||
@@ -490,19 +499,16 @@ impl ExprCollector<'_> { | |||
490 | } | 499 | } |
491 | } | 500 | } |
492 | 501 | ||
493 | fn collect_block(&mut self, expr: ast::BlockExpr) -> ExprId { | 502 | fn collect_block(&mut self, block: ast::BlockExpr) -> ExprId { |
494 | let syntax_node_ptr = AstPtr::new(&expr.clone().into()); | 503 | let syntax_node_ptr = AstPtr::new(&block.clone().into()); |
495 | let block = match expr.block() { | ||
496 | Some(block) => block, | ||
497 | None => return self.alloc_expr(Expr::Missing, syntax_node_ptr), | ||
498 | }; | ||
499 | self.collect_block_items(&block); | 504 | self.collect_block_items(&block); |
500 | let statements = block | 505 | let statements = block |
501 | .statements() | 506 | .statements() |
502 | .map(|s| match s { | 507 | .map(|s| match s { |
503 | ast::Stmt::LetStmt(stmt) => { | 508 | ast::Stmt::LetStmt(stmt) => { |
504 | let pat = self.collect_pat_opt(stmt.pat()); | 509 | let pat = self.collect_pat_opt(stmt.pat()); |
505 | let type_ref = stmt.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it)); | 510 | let type_ref = |
511 | stmt.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx(), it)); | ||
506 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); | 512 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); |
507 | Statement::Let { pat, type_ref, initializer } | 513 | Statement::Let { pat, type_ref, initializer } |
508 | } | 514 | } |
@@ -513,7 +519,7 @@ impl ExprCollector<'_> { | |||
513 | self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) | 519 | self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) |
514 | } | 520 | } |
515 | 521 | ||
516 | fn collect_block_items(&mut self, block: &ast::Block) { | 522 | fn collect_block_items(&mut self, block: &ast::BlockExpr) { |
517 | let container = ContainerId::DefWithBodyId(self.def); | 523 | let container = ContainerId::DefWithBodyId(self.def); |
518 | for item in block.items() { | 524 | for item in block.items() { |
519 | let (def, name): (ModuleDefId, Option<ast::Name>) = match item { | 525 | let (def, name): (ModuleDefId, Option<ast::Name>) = match item { |
@@ -568,9 +574,16 @@ impl ExprCollector<'_> { | |||
568 | self.body.item_scope.define_def(def); | 574 | self.body.item_scope.define_def(def); |
569 | if let Some(name) = name { | 575 | if let Some(name) = name { |
570 | let vis = crate::visibility::Visibility::Public; // FIXME determine correctly | 576 | let vis = crate::visibility::Visibility::Public; // FIXME determine correctly |
571 | self.body | 577 | let has_constructor = match def { |
572 | .item_scope | 578 | ModuleDefId::AdtId(AdtId::StructId(s)) => { |
573 | .push_res(name.as_name(), crate::per_ns::PerNs::from_def(def, vis)); | 579 | self.db.struct_data(s).variant_data.kind() != StructKind::Record |
580 | } | ||
581 | _ => true, | ||
582 | }; | ||
583 | self.body.item_scope.push_res( | ||
584 | name.as_name(), | ||
585 | crate::per_ns::PerNs::from_def(def, vis, has_constructor), | ||
586 | ); | ||
574 | } | 587 | } |
575 | } | 588 | } |
576 | } | 589 | } |
diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs index 86f953c80..09e92b74e 100644 --- a/crates/ra_hir_def/src/body/scope.rs +++ b/crates/ra_hir_def/src/body/scope.rs | |||
@@ -174,7 +174,7 @@ mod tests { | |||
174 | use hir_expand::{name::AsName, InFile}; | 174 | use hir_expand::{name::AsName, InFile}; |
175 | use ra_db::{fixture::WithFixture, FileId, SourceDatabase}; | 175 | use ra_db::{fixture::WithFixture, FileId, SourceDatabase}; |
176 | use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; | 176 | use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; |
177 | use test_utils::{assert_eq_text, covers, extract_offset}; | 177 | use test_utils::{assert_eq_text, extract_offset, mark}; |
178 | 178 | ||
179 | use crate::{db::DefDatabase, test_db::TestDB, FunctionId, ModuleDefId}; | 179 | use crate::{db::DefDatabase, test_db::TestDB, FunctionId, ModuleDefId}; |
180 | 180 | ||
@@ -388,7 +388,7 @@ mod tests { | |||
388 | 388 | ||
389 | #[test] | 389 | #[test] |
390 | fn while_let_desugaring() { | 390 | fn while_let_desugaring() { |
391 | covers!(infer_resolve_while_let); | 391 | mark::check!(infer_resolve_while_let); |
392 | do_check_local_name( | 392 | do_check_local_name( |
393 | r#" | 393 | r#" |
394 | fn test() { | 394 | fn test() { |