Skip to content

Commit

Permalink
Merge pull request #18074 from ChayimFriedman2/typeref-source-map
Browse files Browse the repository at this point in the history
internal: Build source map for `hir_def::TypeRef`s
  • Loading branch information
Veykril authored Oct 28, 2024
2 parents 5346e84 + 3f63848 commit 25b0846
Show file tree
Hide file tree
Showing 46 changed files with 2,510 additions and 928 deletions.
17 changes: 17 additions & 0 deletions src/tools/rust-analyzer/crates/hir-def/src/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use crate::{
nameres::DefMap,
path::{ModPath, Path},
src::HasSource,
type_ref::{TypeRef, TypeRefId, TypesMap, TypesSourceMap},
BlockId, DefWithBodyId, HasModule, Lookup,
};

Expand Down Expand Up @@ -69,6 +70,7 @@ pub struct Body {
pub self_param: Option<BindingId>,
/// The `ExprId` of the actual body expression.
pub body_expr: ExprId,
pub types: TypesMap,
/// Block expressions in this body that may contain inner items.
block_scopes: Vec<BlockId>,

Expand Down Expand Up @@ -139,6 +141,8 @@ pub struct BodySourceMap {
field_map_back: FxHashMap<ExprId, FieldSource>,
pat_field_map_back: FxHashMap<PatId, PatFieldSource>,

types: TypesSourceMap,

// FIXME: Make this a sane struct.
template_map: Option<
Box<(
Expand Down Expand Up @@ -304,6 +308,7 @@ impl Body {
binding_hygiene,
expr_hygiene,
pat_hygiene,
types,
} = self;
block_scopes.shrink_to_fit();
exprs.shrink_to_fit();
Expand All @@ -314,6 +319,7 @@ impl Body {
binding_hygiene.shrink_to_fit();
expr_hygiene.shrink_to_fit();
pat_hygiene.shrink_to_fit();
types.shrink_to_fit();
}

pub fn walk_bindings_in_pat(&self, pat_id: PatId, mut f: impl FnMut(BindingId)) {
Expand Down Expand Up @@ -542,6 +548,7 @@ impl Default for Body {
binding_hygiene: Default::default(),
expr_hygiene: Default::default(),
pat_hygiene: Default::default(),
types: Default::default(),
}
}
}
Expand Down Expand Up @@ -578,6 +585,14 @@ impl Index<BindingId> for Body {
}
}

impl Index<TypeRefId> for Body {
type Output = TypeRef;

fn index(&self, b: TypeRefId) -> &TypeRef {
&self.types[b]
}
}

// FIXME: Change `node_` prefix to something more reasonable.
// Perhaps `expr_syntax` and `expr_id`?
impl BodySourceMap {
Expand Down Expand Up @@ -691,6 +706,7 @@ impl BodySourceMap {
template_map,
diagnostics,
binding_definitions,
types,
} = self;
if let Some(template_map) = template_map {
template_map.0.shrink_to_fit();
Expand All @@ -707,5 +723,6 @@ impl BodySourceMap {
expansions.shrink_to_fit();
diagnostics.shrink_to_fit();
binding_definitions.shrink_to_fit();
types.shrink_to_fit();
}
}
64 changes: 26 additions & 38 deletions src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use hir_expand::{
span_map::{ExpansionSpanMap, SpanMap},
InFile, MacroDefId,
};
use intern::{sym, Interned, Symbol};
use intern::{sym, Symbol};
use rustc_hash::FxHashMap;
use span::AstIdMap;
use stdx::never;
Expand Down Expand Up @@ -274,8 +274,8 @@ impl ExprCollector<'_> {
(self.body, self.source_map)
}

fn ctx(&self) -> LowerCtx<'_> {
self.expander.ctx(self.db)
fn ctx(&mut self) -> LowerCtx<'_> {
self.expander.ctx(self.db, &mut self.body.types, &mut self.source_map.types)
}

fn collect_expr(&mut self, expr: ast::Expr) -> ExprId {
Expand Down Expand Up @@ -436,7 +436,7 @@ impl ExprCollector<'_> {
}
ast::Expr::PathExpr(e) => {
let (path, hygiene) = self
.collect_expr_path(&e)
.collect_expr_path(e)
.map(|(path, hygiene)| (Expr::Path(path), hygiene))
.unwrap_or((Expr::Missing, HygieneId::ROOT));
let expr_id = self.alloc_expr(path, syntax_ptr);
Expand Down Expand Up @@ -486,8 +486,7 @@ impl ExprCollector<'_> {
self.alloc_expr(Expr::Yeet { expr }, syntax_ptr)
}
ast::Expr::RecordExpr(e) => {
let path =
e.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
let path = e.path().and_then(|path| self.parse_path(path)).map(Box::new);
let record_lit = if let Some(nfl) = e.record_expr_field_list() {
let fields = nfl
.fields()
Expand Down Expand Up @@ -534,7 +533,7 @@ impl ExprCollector<'_> {
ast::Expr::TryExpr(e) => self.collect_try_operator(syntax_ptr, e),
ast::Expr::CastExpr(e) => {
let expr = self.collect_expr_opt(e.expr());
let type_ref = Interned::new(TypeRef::from_ast_opt(&self.ctx(), e.ty()));
let type_ref = TypeRef::from_ast_opt(&self.ctx(), e.ty());
self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr)
}
ast::Expr::RefExpr(e) => {
Expand Down Expand Up @@ -573,16 +572,13 @@ impl ExprCollector<'_> {
arg_types.reserve_exact(num_params);
for param in pl.params() {
let pat = this.collect_pat_top(param.pat());
let type_ref =
param.ty().map(|it| Interned::new(TypeRef::from_ast(&this.ctx(), it)));
let type_ref = param.ty().map(|it| TypeRef::from_ast(&this.ctx(), it));
args.push(pat);
arg_types.push(type_ref);
}
}
let ret_type = e
.ret_type()
.and_then(|r| r.ty())
.map(|it| Interned::new(TypeRef::from_ast(&this.ctx(), it)));
let ret_type =
e.ret_type().and_then(|r| r.ty()).map(|it| TypeRef::from_ast(&this.ctx(), it));

let prev_is_lowering_coroutine = mem::take(&mut this.is_lowering_coroutine);
let prev_try_block_label = this.current_try_block_label.take();
Expand Down Expand Up @@ -709,23 +705,23 @@ impl ExprCollector<'_> {
ast::Expr::UnderscoreExpr(_) => self.alloc_expr(Expr::Underscore, syntax_ptr),
ast::Expr::AsmExpr(e) => self.lower_inline_asm(e, syntax_ptr),
ast::Expr::OffsetOfExpr(e) => {
let container = Interned::new(TypeRef::from_ast_opt(&self.ctx(), e.ty()));
let container = TypeRef::from_ast_opt(&self.ctx(), e.ty());
let fields = e.fields().map(|it| it.as_name()).collect();
self.alloc_expr(Expr::OffsetOf(OffsetOf { container, fields }), syntax_ptr)
}
ast::Expr::FormatArgsExpr(f) => self.collect_format_args(f, syntax_ptr),
})
}

fn collect_expr_path(&mut self, e: &ast::PathExpr) -> Option<(Path, HygieneId)> {
fn parse_path(&mut self, path: ast::Path) -> Option<Path> {
self.expander.parse_path(self.db, path, &mut self.body.types, &mut self.source_map.types)
}

fn collect_expr_path(&mut self, e: ast::PathExpr) -> Option<(Path, HygieneId)> {
e.path().and_then(|path| {
let path = self.expander.parse_path(self.db, path)?;
let Path::Normal { type_anchor, mod_path, generic_args } = &path else {
panic!("path parsing produced a non-normal path");
};
let path = self.parse_path(path)?;
// Need to enable `mod_path.len() < 1` for `self`.
let may_be_variable =
type_anchor.is_none() && mod_path.len() <= 1 && generic_args.is_none();
let may_be_variable = matches!(&path, Path::BarePath(mod_path) if mod_path.len() <= 1);
let hygiene = if may_be_variable {
self.hygiene_id_for(e.syntax().text_range().start())
} else {
Expand Down Expand Up @@ -790,17 +786,14 @@ impl ExprCollector<'_> {
}
ast::Expr::CallExpr(e) => {
let path = collect_path(self, e.expr()?)?;
let path = path
.path()
.and_then(|path| self.expander.parse_path(self.db, path))
.map(Box::new);
let path = path.path().and_then(|path| self.parse_path(path)).map(Box::new);
let (ellipsis, args) = collect_tuple(self, e.arg_list()?.args());
self.alloc_pat_from_expr(Pat::TupleStruct { path, args, ellipsis }, syntax_ptr)
}
ast::Expr::PathExpr(e) => {
let (path, hygiene) = self
.collect_expr_path(e)
.map(|(path, hygiene)| (Pat::Path(Box::new(path)), hygiene))
.collect_expr_path(e.clone())
.map(|(path, hygiene)| (Pat::Path(path), hygiene))
.unwrap_or((Pat::Missing, HygieneId::ROOT));
let pat_id = self.alloc_pat_from_expr(path, syntax_ptr);
if !hygiene.is_root() {
Expand All @@ -819,8 +812,7 @@ impl ExprCollector<'_> {
id
}
ast::Expr::RecordExpr(e) => {
let path =
e.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
let path = e.path().and_then(|path| self.parse_path(path)).map(Box::new);
let record_field_list = e.record_expr_field_list()?;
let ellipsis = record_field_list.dotdot_token().is_some();
// FIXME: Report an error here if `record_field_list.spread().is_some()`.
Expand Down Expand Up @@ -1063,7 +1055,7 @@ impl ExprCollector<'_> {
syntax_ptr,
);
let none_arm = MatchArm {
pat: self.alloc_pat_desugared(Pat::Path(Box::new(option_none))),
pat: self.alloc_pat_desugared(Pat::Path(option_none)),
guard: None,
expr: self.alloc_expr(Expr::Break { expr: None, label: None }, syntax_ptr),
};
Expand Down Expand Up @@ -1325,8 +1317,7 @@ impl ExprCollector<'_> {
return;
}
let pat = self.collect_pat_top(stmt.pat());
let type_ref =
stmt.ty().map(|it| Interned::new(TypeRef::from_ast(&self.ctx(), it)));
let type_ref = stmt.ty().map(|it| TypeRef::from_ast(&self.ctx(), it));
let initializer = stmt.initializer().map(|e| self.collect_expr(e));
let else_branch = stmt
.let_else()
Expand Down Expand Up @@ -1552,8 +1543,7 @@ impl ExprCollector<'_> {
return pat;
}
ast::Pat::TupleStructPat(p) => {
let path =
p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
let path = p.path().and_then(|path| self.parse_path(path)).map(Box::new);
let (args, ellipsis) = self.collect_tuple_pat(
p.fields(),
comma_follows_token(p.l_paren_token()),
Expand All @@ -1567,8 +1557,7 @@ impl ExprCollector<'_> {
Pat::Ref { pat, mutability }
}
ast::Pat::PathPat(p) => {
let path =
p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
let path = p.path().and_then(|path| self.parse_path(path));
path.map(Pat::Path).unwrap_or(Pat::Missing)
}
ast::Pat::OrPat(p) => 'b: {
Expand Down Expand Up @@ -1615,8 +1604,7 @@ impl ExprCollector<'_> {
}
ast::Pat::WildcardPat(_) => Pat::Wild,
ast::Pat::RecordPat(p) => {
let path =
p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
let path = p.path().and_then(|path| self.parse_path(path)).map(Box::new);
let record_pat_field_list =
&p.record_pat_field_list().expect("every struct should have a field list");
let args = record_pat_field_list
Expand Down
4 changes: 1 addition & 3 deletions src/tools/rust-analyzer/crates/hir-def/src/body/lower/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,7 @@ impl ExprCollector<'_> {
AsmOperand::Const(self.collect_expr_opt(c.expr()))
}
ast::AsmOperand::AsmSym(s) => {
let Some(path) =
s.path().and_then(|p| self.expander.parse_path(self.db, p))
else {
let Some(path) = s.path().and_then(|p| self.parse_path(p)) else {
continue;
};
AsmOperand::Sym(path)
Expand Down
27 changes: 13 additions & 14 deletions src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use crate::{
Statement,
},
pretty::{print_generic_args, print_path, print_type_ref},
type_ref::TypeRef,
};

use super::*;
Expand Down Expand Up @@ -69,20 +68,20 @@ pub(super) fn print_body_hir(
};
if let DefWithBodyId::FunctionId(it) = owner {
p.buf.push('(');
let function_data = &db.function_data(it);
let function_data = db.function_data(it);
let (mut params, ret_type) = (function_data.params.iter(), &function_data.ret_type);
if let Some(self_param) = body.self_param {
p.print_binding(self_param);
p.buf.push_str(": ");
if let Some(ty) = params.next() {
p.print_type_ref(ty);
p.print_type_ref(*ty, &function_data.types_map);
p.buf.push_str(", ");
}
}
body.params.iter().zip(params).for_each(|(&param, ty)| {
p.print_pat(param);
p.buf.push_str(": ");
p.print_type_ref(ty);
p.print_type_ref(*ty, &function_data.types_map);
p.buf.push_str(", ");
});
// remove the last ", " in param list
Expand All @@ -92,7 +91,7 @@ pub(super) fn print_body_hir(
p.buf.push(')');
// return type
p.buf.push_str(" -> ");
p.print_type_ref(ret_type);
p.print_type_ref(*ret_type, &function_data.types_map);
p.buf.push(' ');
}
p.print_expr(body.body_expr);
Expand Down Expand Up @@ -242,7 +241,7 @@ impl Printer<'_> {
Expr::InlineAsm(_) => w!(self, "builtin#asm(_)"),
Expr::OffsetOf(offset_of) => {
w!(self, "builtin#offset_of(");
self.print_type_ref(&offset_of.container);
self.print_type_ref(offset_of.container, &self.body.types);
let edition = self.edition;
w!(
self,
Expand Down Expand Up @@ -296,7 +295,7 @@ impl Printer<'_> {
if let Some(args) = generic_args {
w!(self, "::<");
let edition = self.edition;
print_generic_args(self.db, args, self, edition).unwrap();
print_generic_args(self.db, args, &self.body.types, self, edition).unwrap();
w!(self, ">");
}
w!(self, "(");
Expand Down Expand Up @@ -405,7 +404,7 @@ impl Printer<'_> {
Expr::Cast { expr, type_ref } => {
self.print_expr(*expr);
w!(self, " as ");
self.print_type_ref(type_ref);
self.print_type_ref(*type_ref, &self.body.types);
}
Expr::Ref { expr, rawness, mutability } => {
w!(self, "&");
Expand Down Expand Up @@ -493,13 +492,13 @@ impl Printer<'_> {
self.print_pat(*pat);
if let Some(ty) = ty {
w!(self, ": ");
self.print_type_ref(ty);
self.print_type_ref(*ty, &self.body.types);
}
}
w!(self, "|");
if let Some(ret_ty) = ret_type {
w!(self, " -> ");
self.print_type_ref(ret_ty);
self.print_type_ref(*ret_ty, &self.body.types);
}
self.whitespace();
self.print_expr(*body);
Expand Down Expand Up @@ -734,7 +733,7 @@ impl Printer<'_> {
self.print_pat(*pat);
if let Some(ty) = type_ref {
w!(self, ": ");
self.print_type_ref(ty);
self.print_type_ref(*ty, &self.body.types);
}
if let Some(init) = initializer {
w!(self, " = ");
Expand Down Expand Up @@ -792,14 +791,14 @@ impl Printer<'_> {
}
}

fn print_type_ref(&mut self, ty: &TypeRef) {
fn print_type_ref(&mut self, ty: TypeRefId, map: &TypesMap) {
let edition = self.edition;
print_type_ref(self.db, ty, self, edition).unwrap();
print_type_ref(self.db, ty, map, self, edition).unwrap();
}

fn print_path(&mut self, path: &Path) {
let edition = self.edition;
print_path(self.db, path, self, edition).unwrap();
print_path(self.db, path, &self.body.types, self, edition).unwrap();
}

fn print_binding(&mut self, id: BindingId) {
Expand Down
Loading

0 comments on commit 25b0846

Please sign in to comment.