aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def')
-rw-r--r--crates/hir_def/src/body.rs19
-rw-r--r--crates/hir_def/src/body/lower.rs24
2 files changed, 25 insertions, 18 deletions
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs
index 19c4eb521..8bcc350ce 100644
--- a/crates/hir_def/src/body.rs
+++ b/crates/hir_def/src/body.rs
@@ -253,11 +253,18 @@ pub type LabelSource = InFile<LabelPtr>;
253pub struct BodySourceMap { 253pub struct BodySourceMap {
254 expr_map: FxHashMap<ExprSource, ExprId>, 254 expr_map: FxHashMap<ExprSource, ExprId>,
255 expr_map_back: ArenaMap<ExprId, Result<ExprSource, SyntheticSyntax>>, 255 expr_map_back: ArenaMap<ExprId, Result<ExprSource, SyntheticSyntax>>,
256
256 pat_map: FxHashMap<PatSource, PatId>, 257 pat_map: FxHashMap<PatSource, PatId>,
257 pat_map_back: ArenaMap<PatId, Result<PatSource, SyntheticSyntax>>, 258 pat_map_back: ArenaMap<PatId, Result<PatSource, SyntheticSyntax>>,
259
258 label_map: FxHashMap<LabelSource, LabelId>, 260 label_map: FxHashMap<LabelSource, LabelId>,
259 label_map_back: ArenaMap<LabelId, LabelSource>, 261 label_map_back: ArenaMap<LabelId, LabelSource>,
260 field_map: FxHashMap<(ExprId, usize), InFile<AstPtr<ast::RecordExprField>>>, 262
263 /// We don't create explicit nodes for record fields (`S { record_field: 92 }`).
264 /// Instead, we use id of expression (`92`) to identify the field.
265 field_map: FxHashMap<InFile<AstPtr<ast::RecordExprField>>, ExprId>,
266 field_map_back: FxHashMap<ExprId, InFile<AstPtr<ast::RecordExprField>>>,
267
261 expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, HirFileId>, 268 expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, HirFileId>,
262 269
263 /// Diagnostics accumulated during body lowering. These contain `AstPtr`s and so are stored in 270 /// Diagnostics accumulated during body lowering. These contain `AstPtr`s and so are stored in
@@ -337,6 +344,8 @@ impl Index<LabelId> for Body {
337 } 344 }
338} 345}
339 346
347// FIXME: Change `node_` prefix to something more reasonable.
348// Perhaps `expr_syntax` and `expr_id`?
340impl BodySourceMap { 349impl BodySourceMap {
341 pub fn expr_syntax(&self, expr: ExprId) -> Result<ExprSource, SyntheticSyntax> { 350 pub fn expr_syntax(&self, expr: ExprId) -> Result<ExprSource, SyntheticSyntax> {
342 self.expr_map_back[expr].clone() 351 self.expr_map_back[expr].clone()
@@ -375,8 +384,12 @@ impl BodySourceMap {
375 self.label_map.get(&src).cloned() 384 self.label_map.get(&src).cloned()
376 } 385 }
377 386
378 pub fn field_syntax(&self, expr: ExprId, field: usize) -> InFile<AstPtr<ast::RecordExprField>> { 387 pub fn field_syntax(&self, expr: ExprId) -> InFile<AstPtr<ast::RecordExprField>> {
379 self.field_map[&(expr, field)].clone() 388 self.field_map_back[&expr].clone()
389 }
390 pub fn node_field(&self, node: InFile<&ast::RecordExprField>) -> Option<ExprId> {
391 let src = node.map(|it| AstPtr::new(it));
392 self.field_map.get(&src).cloned()
380 } 393 }
381 394
382 pub(crate) fn add_diagnostics(&self, _db: &dyn DefDatabase, sink: &mut DiagnosticSink<'_>) { 395 pub(crate) fn add_diagnostics(&self, _db: &dyn DefDatabase, sink: &mut DiagnosticSink<'_>) {
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index 8c8eb8007..8934ae6c9 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -379,23 +379,22 @@ impl ExprCollector<'_> {
379 } 379 }
380 ast::Expr::RecordExpr(e) => { 380 ast::Expr::RecordExpr(e) => {
381 let path = e.path().and_then(|path| self.expander.parse_path(path)); 381 let path = e.path().and_then(|path| self.expander.parse_path(path));
382 let mut field_ptrs = Vec::new();
383 let record_lit = if let Some(nfl) = e.record_expr_field_list() { 382 let record_lit = if let Some(nfl) = e.record_expr_field_list() {
384 let fields = nfl 383 let fields = nfl
385 .fields() 384 .fields()
386 .inspect(|field| field_ptrs.push(AstPtr::new(field)))
387 .filter_map(|field| { 385 .filter_map(|field| {
388 self.check_cfg(&field)?; 386 self.check_cfg(&field)?;
389 387
390 let name = field.field_name()?.as_name(); 388 let name = field.field_name()?.as_name();
391 389
392 Some(RecordLitField { 390 let expr = match field.expr() {
393 name, 391 Some(e) => self.collect_expr(e),
394 expr: match field.expr() { 392 None => self.missing_expr(),
395 Some(e) => self.collect_expr(e), 393 };
396 None => self.missing_expr(), 394 let src = self.expander.to_source(AstPtr::new(&field));
397 }, 395 self.source_map.field_map.insert(src.clone(), expr);
398 }) 396 self.source_map.field_map_back.insert(expr, src);
397 Some(RecordLitField { name, expr })
399 }) 398 })
400 .collect(); 399 .collect();
401 let spread = nfl.spread().map(|s| self.collect_expr(s)); 400 let spread = nfl.spread().map(|s| self.collect_expr(s));
@@ -404,12 +403,7 @@ impl ExprCollector<'_> {
404 Expr::RecordLit { path, fields: Vec::new(), spread: None } 403 Expr::RecordLit { path, fields: Vec::new(), spread: None }
405 }; 404 };
406 405
407 let res = self.alloc_expr(record_lit, syntax_ptr); 406 self.alloc_expr(record_lit, syntax_ptr)
408 for (i, ptr) in field_ptrs.into_iter().enumerate() {
409 let src = self.expander.to_source(ptr);
410 self.source_map.field_map.insert((res, i), src);
411 }
412 res
413 } 407 }
414 ast::Expr::FieldExpr(e) => { 408 ast::Expr::FieldExpr(e) => {
415 let expr = self.collect_expr_opt(e.expr()); 409 let expr = self.collect_expr_opt(e.expr());