Skip to content

Commit bdfc212

Browse files
Build source map for hir_def::TypeRefs
So that given a `TypeRef` we will be able to trace it back to source code. This is necessary to be able to provide diagnostics for lowering to chalk tys, since the input to that is `TypeRef`. This means that `TypeRef`s now have an identity, which means storing them in arena and not interning them, which is an unfortunate (but necessary) loss but also a pretty massive change. Luckily, because of the separation layer we have for IDE and HIR, this change never crosses the IDE boundary.
1 parent c286786 commit bdfc212

40 files changed

+1710
-779
lines changed

crates/hir-def/src/body.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use crate::{
3030
nameres::DefMap,
3131
path::{ModPath, Path},
3232
src::HasSource,
33+
type_ref::{TypeRef, TypeRefId, TypesMap, TypesSourceMap},
3334
BlockId, DefWithBodyId, HasModule, Lookup,
3435
};
3536

@@ -53,6 +54,7 @@ pub struct Body {
5354
pub self_param: Option<BindingId>,
5455
/// The `ExprId` of the actual body expression.
5556
pub body_expr: ExprId,
57+
pub types: TypesMap,
5658
/// Block expressions in this body that may contain inner items.
5759
block_scopes: Vec<BlockId>,
5860
}
@@ -107,6 +109,8 @@ pub struct BodySourceMap {
107109
field_map_back: FxHashMap<ExprId, FieldSource>,
108110
pat_field_map_back: FxHashMap<PatId, PatFieldSource>,
109111

112+
types: TypesSourceMap,
113+
110114
template_map: Option<
111115
Box<(
112116
// format_args!
@@ -268,13 +272,15 @@ impl Body {
268272
pats,
269273
bindings,
270274
binding_owners,
275+
types,
271276
} = self;
272277
block_scopes.shrink_to_fit();
273278
exprs.shrink_to_fit();
274279
labels.shrink_to_fit();
275280
pats.shrink_to_fit();
276281
bindings.shrink_to_fit();
277282
binding_owners.shrink_to_fit();
283+
types.shrink_to_fit();
278284
}
279285

280286
pub fn walk_bindings_in_pat(&self, pat_id: PatId, mut f: impl FnMut(BindingId)) {
@@ -481,6 +487,7 @@ impl Default for Body {
481487
block_scopes: Default::default(),
482488
binding_owners: Default::default(),
483489
self_param: Default::default(),
490+
types: Default::default(),
484491
}
485492
}
486493
}
@@ -517,6 +524,14 @@ impl Index<BindingId> for Body {
517524
}
518525
}
519526

527+
impl Index<TypeRefId> for Body {
528+
type Output = TypeRef;
529+
530+
fn index(&self, b: TypeRefId) -> &TypeRef {
531+
&self.types[b]
532+
}
533+
}
534+
520535
// FIXME: Change `node_` prefix to something more reasonable.
521536
// Perhaps `expr_syntax` and `expr_id`?
522537
impl BodySourceMap {
@@ -632,6 +647,7 @@ impl BodySourceMap {
632647
template_map,
633648
diagnostics,
634649
binding_definitions,
650+
types,
635651
} = self;
636652
if let Some(template_map) = template_map {
637653
template_map.0.shrink_to_fit();
@@ -648,6 +664,7 @@ impl BodySourceMap {
648664
expansions.shrink_to_fit();
649665
diagnostics.shrink_to_fit();
650666
binding_definitions.shrink_to_fit();
667+
types.shrink_to_fit();
651668
}
652669

653670
pub fn template_map(

crates/hir-def/src/body/lower.rs

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use hir_expand::{
1111
name::{AsName, Name},
1212
InFile,
1313
};
14-
use intern::{sym, Interned, Symbol};
14+
use intern::{sym, Symbol};
1515
use rustc_hash::FxHashMap;
1616
use span::AstIdMap;
1717
use stdx::never;
@@ -243,8 +243,8 @@ impl ExprCollector<'_> {
243243
(self.body, self.source_map)
244244
}
245245

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

250250
fn collect_expr(&mut self, expr: ast::Expr) -> ExprId {
@@ -400,7 +400,7 @@ impl ExprCollector<'_> {
400400
ast::Expr::PathExpr(e) => {
401401
let path = e
402402
.path()
403-
.and_then(|path| self.expander.parse_path(self.db, path))
403+
.and_then(|path| self.parse_path(path))
404404
.map(Expr::Path)
405405
.unwrap_or(Expr::Missing);
406406
self.alloc_expr(path, syntax_ptr)
@@ -446,8 +446,7 @@ impl ExprCollector<'_> {
446446
self.alloc_expr(Expr::Yeet { expr }, syntax_ptr)
447447
}
448448
ast::Expr::RecordExpr(e) => {
449-
let path =
450-
e.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
449+
let path = e.path().and_then(|path| self.parse_path(path)).map(Box::new);
451450
let record_lit = if let Some(nfl) = e.record_expr_field_list() {
452451
let fields = nfl
453452
.fields()
@@ -494,7 +493,7 @@ impl ExprCollector<'_> {
494493
ast::Expr::TryExpr(e) => self.collect_try_operator(syntax_ptr, e),
495494
ast::Expr::CastExpr(e) => {
496495
let expr = self.collect_expr_opt(e.expr());
497-
let type_ref = Interned::new(TypeRef::from_ast_opt(&self.ctx(), e.ty()));
496+
let type_ref = TypeRef::from_ast_opt(&self.ctx(), e.ty());
498497
self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr)
499498
}
500499
ast::Expr::RefExpr(e) => {
@@ -533,16 +532,13 @@ impl ExprCollector<'_> {
533532
arg_types.reserve_exact(num_params);
534533
for param in pl.params() {
535534
let pat = this.collect_pat_top(param.pat());
536-
let type_ref =
537-
param.ty().map(|it| Interned::new(TypeRef::from_ast(&this.ctx(), it)));
535+
let type_ref = param.ty().map(|it| TypeRef::from_ast(&this.ctx(), it));
538536
args.push(pat);
539537
arg_types.push(type_ref);
540538
}
541539
}
542-
let ret_type = e
543-
.ret_type()
544-
.and_then(|r| r.ty())
545-
.map(|it| Interned::new(TypeRef::from_ast(&this.ctx(), it)));
540+
let ret_type =
541+
e.ret_type().and_then(|r| r.ty()).map(|it| TypeRef::from_ast(&this.ctx(), it));
546542

547543
let prev_is_lowering_coroutine = mem::take(&mut this.is_lowering_coroutine);
548544
let prev_try_block_label = this.current_try_block_label.take();
@@ -669,14 +665,18 @@ impl ExprCollector<'_> {
669665
ast::Expr::UnderscoreExpr(_) => self.alloc_expr(Expr::Underscore, syntax_ptr),
670666
ast::Expr::AsmExpr(e) => self.lower_inline_asm(e, syntax_ptr),
671667
ast::Expr::OffsetOfExpr(e) => {
672-
let container = Interned::new(TypeRef::from_ast_opt(&self.ctx(), e.ty()));
668+
let container = TypeRef::from_ast_opt(&self.ctx(), e.ty());
673669
let fields = e.fields().map(|it| it.as_name()).collect();
674670
self.alloc_expr(Expr::OffsetOf(OffsetOf { container, fields }), syntax_ptr)
675671
}
676672
ast::Expr::FormatArgsExpr(f) => self.collect_format_args(f, syntax_ptr),
677673
})
678674
}
679675

676+
fn parse_path(&mut self, path: ast::Path) -> Option<Path> {
677+
self.expander.parse_path(self.db, path, &mut self.body.types, &mut self.source_map.types)
678+
}
679+
680680
fn collect_expr_as_pat_opt(&mut self, expr: Option<ast::Expr>) -> PatId {
681681
match expr {
682682
Some(expr) => self.collect_expr_as_pat(expr),
@@ -732,15 +732,12 @@ impl ExprCollector<'_> {
732732
}
733733
ast::Expr::CallExpr(e) => {
734734
let path = collect_path(self, e.expr()?)?;
735-
let path = path
736-
.path()
737-
.and_then(|path| self.expander.parse_path(self.db, path))
738-
.map(Box::new);
735+
let path = path.path().and_then(|path| self.parse_path(path)).map(Box::new);
739736
let (ellipsis, args) = collect_tuple(self, e.arg_list()?.args());
740737
self.alloc_pat_from_expr(Pat::TupleStruct { path, args, ellipsis }, syntax_ptr)
741738
}
742739
ast::Expr::PathExpr(e) => {
743-
let path = Box::new(self.expander.parse_path(self.db, e.path()?)?);
740+
let path = Box::new(self.parse_path(e.path()?)?);
744741
self.alloc_pat_from_expr(Pat::Path(path), syntax_ptr)
745742
}
746743
ast::Expr::MacroExpr(e) => {
@@ -754,8 +751,7 @@ impl ExprCollector<'_> {
754751
id
755752
}
756753
ast::Expr::RecordExpr(e) => {
757-
let path =
758-
e.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
754+
let path = e.path().and_then(|path| self.parse_path(path)).map(Box::new);
759755
let record_field_list = e.record_expr_field_list()?;
760756
let ellipsis = record_field_list.dotdot_token().is_some();
761757
// FIXME: Report an error here if `record_field_list.spread().is_some()`.
@@ -1248,8 +1244,7 @@ impl ExprCollector<'_> {
12481244
return;
12491245
}
12501246
let pat = self.collect_pat_top(stmt.pat());
1251-
let type_ref =
1252-
stmt.ty().map(|it| Interned::new(TypeRef::from_ast(&self.ctx(), it)));
1247+
let type_ref = stmt.ty().map(|it| TypeRef::from_ast(&self.ctx(), it));
12531248
let initializer = stmt.initializer().map(|e| self.collect_expr(e));
12541249
let else_branch = stmt
12551250
.let_else()
@@ -1431,8 +1426,7 @@ impl ExprCollector<'_> {
14311426
return pat;
14321427
}
14331428
ast::Pat::TupleStructPat(p) => {
1434-
let path =
1435-
p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
1429+
let path = p.path().and_then(|path| self.parse_path(path)).map(Box::new);
14361430
let (args, ellipsis) = self.collect_tuple_pat(
14371431
p.fields(),
14381432
comma_follows_token(p.l_paren_token()),
@@ -1446,8 +1440,7 @@ impl ExprCollector<'_> {
14461440
Pat::Ref { pat, mutability }
14471441
}
14481442
ast::Pat::PathPat(p) => {
1449-
let path =
1450-
p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
1443+
let path = p.path().and_then(|path| self.parse_path(path)).map(Box::new);
14511444
path.map(Pat::Path).unwrap_or(Pat::Missing)
14521445
}
14531446
ast::Pat::OrPat(p) => 'b: {
@@ -1490,8 +1483,7 @@ impl ExprCollector<'_> {
14901483
}
14911484
ast::Pat::WildcardPat(_) => Pat::Wild,
14921485
ast::Pat::RecordPat(p) => {
1493-
let path =
1494-
p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
1486+
let path = p.path().and_then(|path| self.parse_path(path)).map(Box::new);
14951487
let record_pat_field_list =
14961488
&p.record_pat_field_list().expect("every struct should have a field list");
14971489
let args = record_pat_field_list

crates/hir-def/src/body/lower/asm.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,7 @@ impl ExprCollector<'_> {
158158
AsmOperand::Const(self.collect_expr_opt(c.expr()))
159159
}
160160
ast::AsmOperand::AsmSym(s) => {
161-
let Some(path) =
162-
s.path().and_then(|p| self.expander.parse_path(self.db, p))
163-
else {
161+
let Some(path) = s.path().and_then(|p| self.parse_path(p)) else {
164162
continue;
165163
};
166164
AsmOperand::Sym(path)

crates/hir-def/src/body/pretty.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use crate::{
1111
Statement,
1212
},
1313
pretty::{print_generic_args, print_path, print_type_ref},
14-
type_ref::TypeRef,
1514
};
1615

1716
use super::*;
@@ -69,20 +68,20 @@ pub(super) fn print_body_hir(
6968
};
7069
if let DefWithBodyId::FunctionId(it) = owner {
7170
p.buf.push('(');
72-
let function_data = &db.function_data(it);
71+
let function_data = db.function_data(it);
7372
let (mut params, ret_type) = (function_data.params.iter(), &function_data.ret_type);
7473
if let Some(self_param) = body.self_param {
7574
p.print_binding(self_param);
7675
p.buf.push_str(": ");
7776
if let Some(ty) = params.next() {
78-
p.print_type_ref(ty);
77+
p.print_type_ref(*ty, &function_data.types_map);
7978
p.buf.push_str(", ");
8079
}
8180
}
8281
body.params.iter().zip(params).for_each(|(&param, ty)| {
8382
p.print_pat(param);
8483
p.buf.push_str(": ");
85-
p.print_type_ref(ty);
84+
p.print_type_ref(*ty, &function_data.types_map);
8685
p.buf.push_str(", ");
8786
});
8887
// remove the last ", " in param list
@@ -92,7 +91,7 @@ pub(super) fn print_body_hir(
9291
p.buf.push(')');
9392
// return type
9493
p.buf.push_str(" -> ");
95-
p.print_type_ref(ret_type);
94+
p.print_type_ref(*ret_type, &function_data.types_map);
9695
p.buf.push(' ');
9796
}
9897
p.print_expr(body.body_expr);
@@ -242,7 +241,7 @@ impl Printer<'_> {
242241
Expr::InlineAsm(_) => w!(self, "builtin#asm(_)"),
243242
Expr::OffsetOf(offset_of) => {
244243
w!(self, "builtin#offset_of(");
245-
self.print_type_ref(&offset_of.container);
244+
self.print_type_ref(offset_of.container, &self.body.types);
246245
let edition = self.edition;
247246
w!(
248247
self,
@@ -296,7 +295,7 @@ impl Printer<'_> {
296295
if let Some(args) = generic_args {
297296
w!(self, "::<");
298297
let edition = self.edition;
299-
print_generic_args(self.db, args, self, edition).unwrap();
298+
print_generic_args(self.db, args, &self.body.types, self, edition).unwrap();
300299
w!(self, ">");
301300
}
302301
w!(self, "(");
@@ -405,7 +404,7 @@ impl Printer<'_> {
405404
Expr::Cast { expr, type_ref } => {
406405
self.print_expr(*expr);
407406
w!(self, " as ");
408-
self.print_type_ref(type_ref);
407+
self.print_type_ref(*type_ref, &self.body.types);
409408
}
410409
Expr::Ref { expr, rawness, mutability } => {
411410
w!(self, "&");
@@ -493,13 +492,13 @@ impl Printer<'_> {
493492
self.print_pat(*pat);
494493
if let Some(ty) = ty {
495494
w!(self, ": ");
496-
self.print_type_ref(ty);
495+
self.print_type_ref(*ty, &self.body.types);
497496
}
498497
}
499498
w!(self, "|");
500499
if let Some(ret_ty) = ret_type {
501500
w!(self, " -> ");
502-
self.print_type_ref(ret_ty);
501+
self.print_type_ref(*ret_ty, &self.body.types);
503502
}
504503
self.whitespace();
505504
self.print_expr(*body);
@@ -734,7 +733,7 @@ impl Printer<'_> {
734733
self.print_pat(*pat);
735734
if let Some(ty) = type_ref {
736735
w!(self, ": ");
737-
self.print_type_ref(ty);
736+
self.print_type_ref(*ty, &self.body.types);
738737
}
739738
if let Some(init) = initializer {
740739
w!(self, " = ");
@@ -792,14 +791,14 @@ impl Printer<'_> {
792791
}
793792
}
794793

795-
fn print_type_ref(&mut self, ty: &TypeRef) {
794+
fn print_type_ref(&mut self, ty: TypeRefId, map: &TypesMap) {
796795
let edition = self.edition;
797-
print_type_ref(self.db, ty, self, edition).unwrap();
796+
print_type_ref(self.db, ty, map, self, edition).unwrap();
798797
}
799798

800799
fn print_path(&mut self, path: &Path) {
801800
let edition = self.edition;
802-
print_path(self.db, path, self, edition).unwrap();
801+
print_path(self.db, path, &self.body.types, self, edition).unwrap();
803802
}
804803

805804
fn print_binding(&mut self, id: BindingId) {

0 commit comments

Comments
 (0)