Simplify source maps for fields

This commit is contained in:
Aleksey Kladov 2021-03-15 15:38:50 +03:00
parent af2366acdf
commit f7156cb0ae
5 changed files with 33 additions and 45 deletions

View file

@ -253,11 +253,18 @@ pub type LabelSource = InFile<LabelPtr>;
pub struct BodySourceMap {
expr_map: FxHashMap<ExprSource, ExprId>,
expr_map_back: ArenaMap<ExprId, Result<ExprSource, SyntheticSyntax>>,
pat_map: FxHashMap<PatSource, PatId>,
pat_map_back: ArenaMap<PatId, Result<PatSource, SyntheticSyntax>>,
label_map: FxHashMap<LabelSource, LabelId>,
label_map_back: ArenaMap<LabelId, LabelSource>,
field_map: FxHashMap<(ExprId, usize), InFile<AstPtr<ast::RecordExprField>>>,
/// We don't create explicit nodes for record fields (`S { record_field: 92 }`).
/// Instead, we use id of expression (`92`) to identify the field.
field_map: FxHashMap<InFile<AstPtr<ast::RecordExprField>>, ExprId>,
field_map_back: FxHashMap<ExprId, InFile<AstPtr<ast::RecordExprField>>>,
expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, HirFileId>,
/// Diagnostics accumulated during body lowering. These contain `AstPtr`s and so are stored in
@ -337,6 +344,8 @@ impl Index<LabelId> for Body {
}
}
// FIXME: Change `node_` prefix to something more reasonable.
// Perhaps `expr_syntax` and `expr_id`?
impl BodySourceMap {
pub fn expr_syntax(&self, expr: ExprId) -> Result<ExprSource, SyntheticSyntax> {
self.expr_map_back[expr].clone()
@ -375,8 +384,12 @@ impl BodySourceMap {
self.label_map.get(&src).cloned()
}
pub fn field_syntax(&self, expr: ExprId, field: usize) -> InFile<AstPtr<ast::RecordExprField>> {
self.field_map[&(expr, field)].clone()
pub fn field_syntax(&self, expr: ExprId) -> InFile<AstPtr<ast::RecordExprField>> {
self.field_map_back[&expr].clone()
}
pub fn node_field(&self, node: InFile<&ast::RecordExprField>) -> Option<ExprId> {
let src = node.map(|it| AstPtr::new(it));
self.field_map.get(&src).cloned()
}
pub(crate) fn add_diagnostics(&self, _db: &dyn DefDatabase, sink: &mut DiagnosticSink<'_>) {

View file

@ -379,23 +379,22 @@ impl ExprCollector<'_> {
}
ast::Expr::RecordExpr(e) => {
let path = e.path().and_then(|path| self.expander.parse_path(path));
let mut field_ptrs = Vec::new();
let record_lit = if let Some(nfl) = e.record_expr_field_list() {
let fields = nfl
.fields()
.inspect(|field| field_ptrs.push(AstPtr::new(field)))
.filter_map(|field| {
self.check_cfg(&field)?;
let name = field.field_name()?.as_name();
Some(RecordLitField {
name,
expr: match field.expr() {
Some(e) => self.collect_expr(e),
None => self.missing_expr(),
},
})
let expr = match field.expr() {
Some(e) => self.collect_expr(e),
None => self.missing_expr(),
};
let src = self.expander.to_source(AstPtr::new(&field));
self.source_map.field_map.insert(src.clone(), expr);
self.source_map.field_map_back.insert(expr, src);
Some(RecordLitField { name, expr })
})
.collect();
let spread = nfl.spread().map(|s| self.collect_expr(s));
@ -404,12 +403,7 @@ impl ExprCollector<'_> {
Expr::RecordLit { path, fields: Vec::new(), spread: None }
};
let res = self.alloc_expr(record_lit, syntax_ptr);
for (i, ptr) in field_ptrs.into_iter().enumerate() {
let src = self.expander.to_source(ptr);
self.source_map.field_map.insert((res, i), src);
}
res
self.alloc_expr(record_lit, syntax_ptr)
}
ast::Expr::FieldExpr(e) => {
let expr = self.collect_expr_opt(e.expr());