Skip to content

Commit 25b0846

Browse files
authored
Merge pull request rust-lang#18074 from ChayimFriedman2/typeref-source-map
internal: Build source map for `hir_def::TypeRef`s
2 parents 5346e84 + 3f63848 commit 25b0846

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+2510
-928
lines changed

src/tools/rust-analyzer/crates/hir-def/src/body.rs

+17
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

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

@@ -139,6 +141,8 @@ pub struct BodySourceMap {
139141
field_map_back: FxHashMap<ExprId, FieldSource>,
140142
pat_field_map_back: FxHashMap<PatId, PatFieldSource>,
141143

144+
types: TypesSourceMap,
145+
142146
// FIXME: Make this a sane struct.
143147
template_map: Option<
144148
Box<(
@@ -304,6 +308,7 @@ impl Body {
304308
binding_hygiene,
305309
expr_hygiene,
306310
pat_hygiene,
311+
types,
307312
} = self;
308313
block_scopes.shrink_to_fit();
309314
exprs.shrink_to_fit();
@@ -314,6 +319,7 @@ impl Body {
314319
binding_hygiene.shrink_to_fit();
315320
expr_hygiene.shrink_to_fit();
316321
pat_hygiene.shrink_to_fit();
322+
types.shrink_to_fit();
317323
}
318324

319325
pub fn walk_bindings_in_pat(&self, pat_id: PatId, mut f: impl FnMut(BindingId)) {
@@ -542,6 +548,7 @@ impl Default for Body {
542548
binding_hygiene: Default::default(),
543549
expr_hygiene: Default::default(),
544550
pat_hygiene: Default::default(),
551+
types: Default::default(),
545552
}
546553
}
547554
}
@@ -578,6 +585,14 @@ impl Index<BindingId> for Body {
578585
}
579586
}
580587

588+
impl Index<TypeRefId> for Body {
589+
type Output = TypeRef;
590+
591+
fn index(&self, b: TypeRefId) -> &TypeRef {
592+
&self.types[b]
593+
}
594+
}
595+
581596
// FIXME: Change `node_` prefix to something more reasonable.
582597
// Perhaps `expr_syntax` and `expr_id`?
583598
impl BodySourceMap {
@@ -691,6 +706,7 @@ impl BodySourceMap {
691706
template_map,
692707
diagnostics,
693708
binding_definitions,
709+
types,
694710
} = self;
695711
if let Some(template_map) = template_map {
696712
template_map.0.shrink_to_fit();
@@ -707,5 +723,6 @@ impl BodySourceMap {
707723
expansions.shrink_to_fit();
708724
diagnostics.shrink_to_fit();
709725
binding_definitions.shrink_to_fit();
726+
types.shrink_to_fit();
710727
}
711728
}

src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs

+26-38
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use hir_expand::{
1212
span_map::{ExpansionSpanMap, SpanMap},
1313
InFile, MacroDefId,
1414
};
15-
use intern::{sym, Interned, Symbol};
15+
use intern::{sym, Symbol};
1616
use rustc_hash::FxHashMap;
1717
use span::AstIdMap;
1818
use stdx::never;
@@ -274,8 +274,8 @@ impl ExprCollector<'_> {
274274
(self.body, self.source_map)
275275
}
276276

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

281281
fn collect_expr(&mut self, expr: ast::Expr) -> ExprId {
@@ -436,7 +436,7 @@ impl ExprCollector<'_> {
436436
}
437437
ast::Expr::PathExpr(e) => {
438438
let (path, hygiene) = self
439-
.collect_expr_path(&e)
439+
.collect_expr_path(e)
440440
.map(|(path, hygiene)| (Expr::Path(path), hygiene))
441441
.unwrap_or((Expr::Missing, HygieneId::ROOT));
442442
let expr_id = self.alloc_expr(path, syntax_ptr);
@@ -486,8 +486,7 @@ impl ExprCollector<'_> {
486486
self.alloc_expr(Expr::Yeet { expr }, syntax_ptr)
487487
}
488488
ast::Expr::RecordExpr(e) => {
489-
let path =
490-
e.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
489+
let path = e.path().and_then(|path| self.parse_path(path)).map(Box::new);
491490
let record_lit = if let Some(nfl) = e.record_expr_field_list() {
492491
let fields = nfl
493492
.fields()
@@ -534,7 +533,7 @@ impl ExprCollector<'_> {
534533
ast::Expr::TryExpr(e) => self.collect_try_operator(syntax_ptr, e),
535534
ast::Expr::CastExpr(e) => {
536535
let expr = self.collect_expr_opt(e.expr());
537-
let type_ref = Interned::new(TypeRef::from_ast_opt(&self.ctx(), e.ty()));
536+
let type_ref = TypeRef::from_ast_opt(&self.ctx(), e.ty());
538537
self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr)
539538
}
540539
ast::Expr::RefExpr(e) => {
@@ -573,16 +572,13 @@ impl ExprCollector<'_> {
573572
arg_types.reserve_exact(num_params);
574573
for param in pl.params() {
575574
let pat = this.collect_pat_top(param.pat());
576-
let type_ref =
577-
param.ty().map(|it| Interned::new(TypeRef::from_ast(&this.ctx(), it)));
575+
let type_ref = param.ty().map(|it| TypeRef::from_ast(&this.ctx(), it));
578576
args.push(pat);
579577
arg_types.push(type_ref);
580578
}
581579
}
582-
let ret_type = e
583-
.ret_type()
584-
.and_then(|r| r.ty())
585-
.map(|it| Interned::new(TypeRef::from_ast(&this.ctx(), it)));
580+
let ret_type =
581+
e.ret_type().and_then(|r| r.ty()).map(|it| TypeRef::from_ast(&this.ctx(), it));
586582

587583
let prev_is_lowering_coroutine = mem::take(&mut this.is_lowering_coroutine);
588584
let prev_try_block_label = this.current_try_block_label.take();
@@ -709,23 +705,23 @@ impl ExprCollector<'_> {
709705
ast::Expr::UnderscoreExpr(_) => self.alloc_expr(Expr::Underscore, syntax_ptr),
710706
ast::Expr::AsmExpr(e) => self.lower_inline_asm(e, syntax_ptr),
711707
ast::Expr::OffsetOfExpr(e) => {
712-
let container = Interned::new(TypeRef::from_ast_opt(&self.ctx(), e.ty()));
708+
let container = TypeRef::from_ast_opt(&self.ctx(), e.ty());
713709
let fields = e.fields().map(|it| it.as_name()).collect();
714710
self.alloc_expr(Expr::OffsetOf(OffsetOf { container, fields }), syntax_ptr)
715711
}
716712
ast::Expr::FormatArgsExpr(f) => self.collect_format_args(f, syntax_ptr),
717713
})
718714
}
719715

720-
fn collect_expr_path(&mut self, e: &ast::PathExpr) -> Option<(Path, HygieneId)> {
716+
fn parse_path(&mut self, path: ast::Path) -> Option<Path> {
717+
self.expander.parse_path(self.db, path, &mut self.body.types, &mut self.source_map.types)
718+
}
719+
720+
fn collect_expr_path(&mut self, e: ast::PathExpr) -> Option<(Path, HygieneId)> {
721721
e.path().and_then(|path| {
722-
let path = self.expander.parse_path(self.db, path)?;
723-
let Path::Normal { type_anchor, mod_path, generic_args } = &path else {
724-
panic!("path parsing produced a non-normal path");
725-
};
722+
let path = self.parse_path(path)?;
726723
// Need to enable `mod_path.len() < 1` for `self`.
727-
let may_be_variable =
728-
type_anchor.is_none() && mod_path.len() <= 1 && generic_args.is_none();
724+
let may_be_variable = matches!(&path, Path::BarePath(mod_path) if mod_path.len() <= 1);
729725
let hygiene = if may_be_variable {
730726
self.hygiene_id_for(e.syntax().text_range().start())
731727
} else {
@@ -790,17 +786,14 @@ impl ExprCollector<'_> {
790786
}
791787
ast::Expr::CallExpr(e) => {
792788
let path = collect_path(self, e.expr()?)?;
793-
let path = path
794-
.path()
795-
.and_then(|path| self.expander.parse_path(self.db, path))
796-
.map(Box::new);
789+
let path = path.path().and_then(|path| self.parse_path(path)).map(Box::new);
797790
let (ellipsis, args) = collect_tuple(self, e.arg_list()?.args());
798791
self.alloc_pat_from_expr(Pat::TupleStruct { path, args, ellipsis }, syntax_ptr)
799792
}
800793
ast::Expr::PathExpr(e) => {
801794
let (path, hygiene) = self
802-
.collect_expr_path(e)
803-
.map(|(path, hygiene)| (Pat::Path(Box::new(path)), hygiene))
795+
.collect_expr_path(e.clone())
796+
.map(|(path, hygiene)| (Pat::Path(path), hygiene))
804797
.unwrap_or((Pat::Missing, HygieneId::ROOT));
805798
let pat_id = self.alloc_pat_from_expr(path, syntax_ptr);
806799
if !hygiene.is_root() {
@@ -819,8 +812,7 @@ impl ExprCollector<'_> {
819812
id
820813
}
821814
ast::Expr::RecordExpr(e) => {
822-
let path =
823-
e.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
815+
let path = e.path().and_then(|path| self.parse_path(path)).map(Box::new);
824816
let record_field_list = e.record_expr_field_list()?;
825817
let ellipsis = record_field_list.dotdot_token().is_some();
826818
// FIXME: Report an error here if `record_field_list.spread().is_some()`.
@@ -1063,7 +1055,7 @@ impl ExprCollector<'_> {
10631055
syntax_ptr,
10641056
);
10651057
let none_arm = MatchArm {
1066-
pat: self.alloc_pat_desugared(Pat::Path(Box::new(option_none))),
1058+
pat: self.alloc_pat_desugared(Pat::Path(option_none)),
10671059
guard: None,
10681060
expr: self.alloc_expr(Expr::Break { expr: None, label: None }, syntax_ptr),
10691061
};
@@ -1325,8 +1317,7 @@ impl ExprCollector<'_> {
13251317
return;
13261318
}
13271319
let pat = self.collect_pat_top(stmt.pat());
1328-
let type_ref =
1329-
stmt.ty().map(|it| Interned::new(TypeRef::from_ast(&self.ctx(), it)));
1320+
let type_ref = stmt.ty().map(|it| TypeRef::from_ast(&self.ctx(), it));
13301321
let initializer = stmt.initializer().map(|e| self.collect_expr(e));
13311322
let else_branch = stmt
13321323
.let_else()
@@ -1552,8 +1543,7 @@ impl ExprCollector<'_> {
15521543
return pat;
15531544
}
15541545
ast::Pat::TupleStructPat(p) => {
1555-
let path =
1556-
p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
1546+
let path = p.path().and_then(|path| self.parse_path(path)).map(Box::new);
15571547
let (args, ellipsis) = self.collect_tuple_pat(
15581548
p.fields(),
15591549
comma_follows_token(p.l_paren_token()),
@@ -1567,8 +1557,7 @@ impl ExprCollector<'_> {
15671557
Pat::Ref { pat, mutability }
15681558
}
15691559
ast::Pat::PathPat(p) => {
1570-
let path =
1571-
p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
1560+
let path = p.path().and_then(|path| self.parse_path(path));
15721561
path.map(Pat::Path).unwrap_or(Pat::Missing)
15731562
}
15741563
ast::Pat::OrPat(p) => 'b: {
@@ -1615,8 +1604,7 @@ impl ExprCollector<'_> {
16151604
}
16161605
ast::Pat::WildcardPat(_) => Pat::Wild,
16171606
ast::Pat::RecordPat(p) => {
1618-
let path =
1619-
p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
1607+
let path = p.path().and_then(|path| self.parse_path(path)).map(Box::new);
16201608
let record_pat_field_list =
16211609
&p.record_pat_field_list().expect("every struct should have a field list");
16221610
let args = record_pat_field_list

src/tools/rust-analyzer/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)

src/tools/rust-analyzer/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, "(");
@@ -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)