From 9c3b25177e3c8d609dd24d2c2e01cbb82cab665f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 3 Sep 2019 11:04:38 +0300 Subject: Correctly build BodySourceMap for macro-expanded expressions --- crates/ra_hir/src/expr/lower.rs | 16 ++++++------ crates/ra_hir/src/expr/validation.rs | 47 +++++++++++++++++------------------- 2 files changed, 31 insertions(+), 32 deletions(-) (limited to 'crates/ra_hir/src/expr') diff --git a/crates/ra_hir/src/expr/lower.rs b/crates/ra_hir/src/expr/lower.rs index 7b3e55b7e..6afd80989 100644 --- a/crates/ra_hir/src/expr/lower.rs +++ b/crates/ra_hir/src/expr/lower.rs @@ -14,7 +14,7 @@ use crate::{ ty::primitive::{FloatTy, IntTy, UncertainFloatTy, UncertainIntTy}, type_ref::TypeRef, DefWithBody, Either, HirDatabase, HirFileId, MacroCallLoc, MacroFileKind, Mutability, Path, - Resolver, + Resolver, Source, }; use super::{ @@ -103,11 +103,13 @@ where let id = self.body.exprs.alloc(expr); if self.current_file_id == self.original_file_id { self.source_map.expr_map.insert(ptr, id); - self.source_map.expr_map_back.insert(id, ptr); } + self.source_map + .expr_map_back + .insert(id, Source { file_id: self.current_file_id, ast: ptr }); id } - // deshugared exprs don't have ptr, that's wrong and should be fixed + // desugared exprs don't have ptr, that's wrong and should be fixed // somehow. fn alloc_expr_desugared(&mut self, expr: Expr) -> ExprId { self.body.exprs.alloc(expr) @@ -117,18 +119,18 @@ where let id = self.body.exprs.alloc(expr); if self.current_file_id == self.original_file_id { self.source_map.expr_map.insert(ptr, id); - self.source_map.expr_map_back.insert(id, ptr); } + self.source_map + .expr_map_back + .insert(id, Source { file_id: self.current_file_id, ast: ptr }); id } fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId { let id = self.body.pats.alloc(pat); - if self.current_file_id == self.original_file_id { self.source_map.pat_map.insert(ptr, id); - self.source_map.pat_map_back.insert(id, ptr); } - + self.source_map.pat_map_back.insert(id, Source { file_id: self.current_file_id, ast: ptr }); id } diff --git a/crates/ra_hir/src/expr/validation.rs b/crates/ra_hir/src/expr/validation.rs index 6fdaf1fce..1202913e2 100644 --- a/crates/ra_hir/src/expr/validation.rs +++ b/crates/ra_hir/src/expr/validation.rs @@ -1,9 +1,8 @@ use std::sync::Arc; -use ra_syntax::ast::{self, AstNode}; +use ra_syntax::ast; use rustc_hash::FxHashSet; -use super::{Expr, ExprId, RecordLitField}; use crate::{ adt::AdtDef, diagnostics::{DiagnosticSink, MissingFields, MissingOkInTailExpr}, @@ -11,9 +10,11 @@ use crate::{ name, path::{PathKind, PathSegment}, ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, - Function, HasSource, HirDatabase, ModuleDef, Name, Path, PerNs, Resolution, + Function, HirDatabase, ModuleDef, Name, Path, PerNs, Resolution, }; +use super::{Expr, ExprId, RecordLitField}; + pub(crate) struct ExprValidator<'a, 'b: 'a> { func: Function, infer: Arc, @@ -78,25 +79,20 @@ impl<'a, 'b> ExprValidator<'a, 'b> { return; } let source_map = self.func.body_source_map(db); - let file_id = self.func.source(db).file_id; - let parse = db.parse(file_id.original_file(db)); - let source_file = parse.tree(); - if let Some(field_list_node) = source_map - .expr_syntax(id) - .and_then(|ptr| ptr.a()) - .map(|ptr| ptr.to_node(source_file.syntax())) - .and_then(|expr| match expr { - ast::Expr::RecordLit(it) => Some(it), - _ => None, - }) - .and_then(|lit| lit.record_field_list()) - { - let field_list_ptr = AstPtr::new(&field_list_node); - self.sink.push(MissingFields { - file: file_id, - field_list: field_list_ptr, - missed_fields, - }) + + if let Some(source_ptr) = source_map.expr_syntax(id) { + if let Some(expr) = source_ptr.ast.a() { + let root = source_ptr.file_syntax(db); + if let ast::Expr::RecordLit(record_lit) = expr.to_node(&root) { + if let Some(field_list) = record_lit.record_field_list() { + self.sink.push(MissingFields { + file: source_ptr.file_id, + field_list: AstPtr::new(&field_list), + missed_fields, + }) + } + } + } } } @@ -136,10 +132,11 @@ impl<'a, 'b> ExprValidator<'a, 'b> { if params.len() == 2 && ¶ms[0] == &mismatch.actual { let source_map = self.func.body_source_map(db); - let file_id = self.func.source(db).file_id; - if let Some(expr) = source_map.expr_syntax(id).and_then(|n| n.a()) { - self.sink.push(MissingOkInTailExpr { file: file_id, expr }); + if let Some(source_ptr) = source_map.expr_syntax(id) { + if let Some(expr) = source_ptr.ast.a() { + self.sink.push(MissingOkInTailExpr { file: source_ptr.file_id, expr }); + } } } } -- cgit v1.2.3