Skip to content

Commit 3c34665

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 fd243cd commit 3c34665

40 files changed

+1724
-804
lines changed

crates/hir-def/src/body.rs

+17
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use crate::{
2828
nameres::DefMap,
2929
path::{ModPath, Path},
3030
src::HasSource,
31+
type_ref::{TypeRef, TypeRefId, TypesMap, TypesSourceMap},
3132
BlockId, DefWithBodyId, HasModule, Lookup,
3233
};
3334

@@ -51,6 +52,7 @@ pub struct Body {
5152
pub self_param: Option<BindingId>,
5253
/// The `ExprId` of the actual body expression.
5354
pub body_expr: ExprId,
55+
pub types: TypesMap,
5456
/// Block expressions in this body that may contain inner items.
5557
block_scopes: Vec<BlockId>,
5658
}
@@ -100,6 +102,8 @@ pub struct BodySourceMap {
100102
field_map_back: FxHashMap<ExprId, FieldSource>,
101103
pat_field_map_back: FxHashMap<PatId, PatFieldSource>,
102104

105+
types: TypesSourceMap,
106+
103107
template_map: Option<
104108
Box<(
105109
// format_args!
@@ -261,13 +265,15 @@ impl Body {
261265
pats,
262266
bindings,
263267
binding_owners,
268+
types,
264269
} = self;
265270
block_scopes.shrink_to_fit();
266271
exprs.shrink_to_fit();
267272
labels.shrink_to_fit();
268273
pats.shrink_to_fit();
269274
bindings.shrink_to_fit();
270275
binding_owners.shrink_to_fit();
276+
types.shrink_to_fit();
271277
}
272278

273279
pub fn walk_bindings_in_pat(&self, pat_id: PatId, mut f: impl FnMut(BindingId)) {
@@ -336,6 +342,7 @@ impl Default for Body {
336342
block_scopes: Default::default(),
337343
binding_owners: Default::default(),
338344
self_param: Default::default(),
345+
types: Default::default(),
339346
}
340347
}
341348
}
@@ -372,6 +379,14 @@ impl Index<BindingId> for Body {
372379
}
373380
}
374381

382+
impl Index<TypeRefId> for Body {
383+
type Output = TypeRef;
384+
385+
fn index(&self, b: TypeRefId) -> &TypeRef {
386+
&self.types[b]
387+
}
388+
}
389+
375390
// FIXME: Change `node_` prefix to something more reasonable.
376391
// Perhaps `expr_syntax` and `expr_id`?
377392
impl BodySourceMap {
@@ -476,6 +491,7 @@ impl BodySourceMap {
476491
template_map,
477492
diagnostics,
478493
binding_definitions,
494+
types,
479495
} = self;
480496
if let Some(template_map) = template_map {
481497
template_map.0.shrink_to_fit();
@@ -492,6 +508,7 @@ impl BodySourceMap {
492508
expansions.shrink_to_fit();
493509
diagnostics.shrink_to_fit();
494510
binding_definitions.shrink_to_fit();
511+
types.shrink_to_fit();
495512
}
496513

497514
pub fn template_map(

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

+18-22
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;
@@ -245,8 +245,8 @@ impl ExprCollector<'_> {
245245
(self.body, self.source_map)
246246
}
247247

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

252252
fn collect_expr(&mut self, expr: ast::Expr) -> ExprId {
@@ -409,7 +409,7 @@ impl ExprCollector<'_> {
409409
ast::Expr::PathExpr(e) => {
410410
let path = e
411411
.path()
412-
.and_then(|path| self.expander.parse_path(self.db, path))
412+
.and_then(|path| self.parse_path(path))
413413
.map(Expr::Path)
414414
.unwrap_or(Expr::Missing);
415415
self.alloc_expr(path, syntax_ptr)
@@ -455,8 +455,7 @@ impl ExprCollector<'_> {
455455
self.alloc_expr(Expr::Yeet { expr }, syntax_ptr)
456456
}
457457
ast::Expr::RecordExpr(e) => {
458-
let path =
459-
e.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
458+
let path = e.path().and_then(|path| self.parse_path(path)).map(Box::new);
460459
let is_assignee_expr = self.is_lowering_assignee_expr;
461460
let record_lit = if let Some(nfl) = e.record_expr_field_list() {
462461
let fields = nfl
@@ -511,7 +510,7 @@ impl ExprCollector<'_> {
511510
ast::Expr::TryExpr(e) => self.collect_try_operator(syntax_ptr, e),
512511
ast::Expr::CastExpr(e) => {
513512
let expr = self.collect_expr_opt(e.expr());
514-
let type_ref = Interned::new(TypeRef::from_ast_opt(&self.ctx(), e.ty()));
513+
let type_ref = TypeRef::from_ast_opt(&self.ctx(), e.ty());
515514
self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr)
516515
}
517516
ast::Expr::RefExpr(e) => {
@@ -550,16 +549,13 @@ impl ExprCollector<'_> {
550549
arg_types.reserve_exact(num_params);
551550
for param in pl.params() {
552551
let pat = this.collect_pat_top(param.pat());
553-
let type_ref =
554-
param.ty().map(|it| Interned::new(TypeRef::from_ast(&this.ctx(), it)));
552+
let type_ref = param.ty().map(|it| TypeRef::from_ast(&this.ctx(), it));
555553
args.push(pat);
556554
arg_types.push(type_ref);
557555
}
558556
}
559-
let ret_type = e
560-
.ret_type()
561-
.and_then(|r| r.ty())
562-
.map(|it| Interned::new(TypeRef::from_ast(&this.ctx(), it)));
557+
let ret_type =
558+
e.ret_type().and_then(|r| r.ty()).map(|it| TypeRef::from_ast(&this.ctx(), it));
563559

564560
let prev_is_lowering_coroutine = mem::take(&mut this.is_lowering_coroutine);
565561
let prev_try_block_label = this.current_try_block_label.take();
@@ -697,14 +693,18 @@ impl ExprCollector<'_> {
697693
ast::Expr::UnderscoreExpr(_) => self.alloc_expr(Expr::Underscore, syntax_ptr),
698694
ast::Expr::AsmExpr(e) => self.lower_inline_asm(e, syntax_ptr),
699695
ast::Expr::OffsetOfExpr(e) => {
700-
let container = Interned::new(TypeRef::from_ast_opt(&self.ctx(), e.ty()));
696+
let container = TypeRef::from_ast_opt(&self.ctx(), e.ty());
701697
let fields = e.fields().map(|it| it.as_name()).collect();
702698
self.alloc_expr(Expr::OffsetOf(OffsetOf { container, fields }), syntax_ptr)
703699
}
704700
ast::Expr::FormatArgsExpr(f) => self.collect_format_args(f, syntax_ptr),
705701
})
706702
}
707703

704+
fn parse_path(&mut self, path: ast::Path) -> Option<Path> {
705+
self.expander.parse_path(self.db, path, &mut self.body.types, &mut self.source_map.types)
706+
}
707+
708708
fn initialize_binding_owner(
709709
&mut self,
710710
syntax_ptr: AstPtr<ast::Expr>,
@@ -1119,8 +1119,7 @@ impl ExprCollector<'_> {
11191119
return;
11201120
}
11211121
let pat = self.collect_pat_top(stmt.pat());
1122-
let type_ref =
1123-
stmt.ty().map(|it| Interned::new(TypeRef::from_ast(&self.ctx(), it)));
1122+
let type_ref = stmt.ty().map(|it| TypeRef::from_ast(&self.ctx(), it));
11241123
let initializer = stmt.initializer().map(|e| self.collect_expr(e));
11251124
let else_branch = stmt
11261125
.let_else()
@@ -1302,8 +1301,7 @@ impl ExprCollector<'_> {
13021301
return pat;
13031302
}
13041303
ast::Pat::TupleStructPat(p) => {
1305-
let path =
1306-
p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
1304+
let path = p.path().and_then(|path| self.parse_path(path)).map(Box::new);
13071305
let (args, ellipsis) = self.collect_tuple_pat(
13081306
p.fields(),
13091307
comma_follows_token(p.l_paren_token()),
@@ -1317,8 +1315,7 @@ impl ExprCollector<'_> {
13171315
Pat::Ref { pat, mutability }
13181316
}
13191317
ast::Pat::PathPat(p) => {
1320-
let path =
1321-
p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
1318+
let path = p.path().and_then(|path| self.parse_path(path)).map(Box::new);
13221319
path.map(Pat::Path).unwrap_or(Pat::Missing)
13231320
}
13241321
ast::Pat::OrPat(p) => 'b: {
@@ -1361,8 +1358,7 @@ impl ExprCollector<'_> {
13611358
}
13621359
ast::Pat::WildcardPat(_) => Pat::Wild,
13631360
ast::Pat::RecordPat(p) => {
1364-
let path =
1365-
p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
1361+
let path = p.path().and_then(|path| self.parse_path(path)).map(Box::new);
13661362
let record_pat_field_list =
13671363
&p.record_pat_field_list().expect("every struct should have a field list");
13681364
let args = record_pat_field_list

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

+1-3
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

+13-14
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, "(");
@@ -408,7 +407,7 @@ impl Printer<'_> {
408407
Expr::Cast { expr, type_ref } => {
409408
self.print_expr(*expr);
410409
w!(self, " as ");
411-
self.print_type_ref(type_ref);
410+
self.print_type_ref(*type_ref, &self.body.types);
412411
}
413412
Expr::Ref { expr, rawness, mutability } => {
414413
w!(self, "&");
@@ -496,13 +495,13 @@ impl Printer<'_> {
496495
self.print_pat(*pat);
497496
if let Some(ty) = ty {
498497
w!(self, ": ");
499-
self.print_type_ref(ty);
498+
self.print_type_ref(*ty, &self.body.types);
500499
}
501500
}
502501
w!(self, "|");
503502
if let Some(ret_ty) = ret_type {
504503
w!(self, " -> ");
505-
self.print_type_ref(ret_ty);
504+
self.print_type_ref(*ret_ty, &self.body.types);
506505
}
507506
self.whitespace();
508507
self.print_expr(*body);
@@ -729,7 +728,7 @@ impl Printer<'_> {
729728
self.print_pat(*pat);
730729
if let Some(ty) = type_ref {
731730
w!(self, ": ");
732-
self.print_type_ref(ty);
731+
self.print_type_ref(*ty, &self.body.types);
733732
}
734733
if let Some(init) = initializer {
735734
w!(self, " = ");
@@ -787,14 +786,14 @@ impl Printer<'_> {
787786
}
788787
}
789788

790-
fn print_type_ref(&mut self, ty: &TypeRef) {
789+
fn print_type_ref(&mut self, ty: TypeRefId, map: &TypesMap) {
791790
let edition = self.edition;
792-
print_type_ref(self.db, ty, self, edition).unwrap();
791+
print_type_ref(self.db, ty, map, self, edition).unwrap();
793792
}
794793

795794
fn print_path(&mut self, path: &Path) {
796795
let edition = self.edition;
797-
print_path(self.db, path, self, edition).unwrap();
796+
print_path(self.db, path, &self.body.types, self, edition).unwrap();
798797
}
799798

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

0 commit comments

Comments
 (0)