Correctly build BodySourceMap for macro-expanded expressions

This commit is contained in:
Aleksey Kladov 2019-09-03 11:04:38 +03:00
parent 4b51c92fee
commit 9c3b25177e
8 changed files with 129 additions and 72 deletions

View file

@ -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
}

View file

@ -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<InferenceResult>,
@ -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 && &params[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 });
}
}
}
}