Skip to content

Commit c034874

Browse files
committed
rustc_save_analysis: avoid using TypeckTables::empty for SaveContext.
1 parent 780d6cb commit c034874

File tree

2 files changed

+31
-23
lines changed

2 files changed

+31
-23
lines changed

src/librustc_save_analysis/dump_visitor.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,15 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
109109
F: FnOnce(&mut Self),
110110
{
111111
let tables = if self.tcx.has_typeck_tables(item_def_id) {
112-
self.tcx.typeck_tables_of(item_def_id)
112+
Some(self.tcx.typeck_tables_of(item_def_id))
113113
} else {
114-
self.save_ctxt.empty_tables
114+
None
115115
};
116116

117-
let old_tables = self.save_ctxt.tables;
118-
self.save_ctxt.tables = tables;
117+
let old_maybe_typeck_tables = self.save_ctxt.maybe_typeck_tables;
118+
self.save_ctxt.maybe_typeck_tables = tables;
119119
f(self);
120-
self.save_ctxt.tables = old_tables;
120+
self.save_ctxt.maybe_typeck_tables = old_maybe_typeck_tables;
121121
}
122122

123123
fn span_from_span(&self, span: Span) -> SpanData {
@@ -226,7 +226,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
226226
collector.visit_pat(&arg.pat);
227227

228228
for (hir_id, ident, ..) in collector.collected_idents {
229-
let typ = match self.save_ctxt.tables.node_type_opt(hir_id) {
229+
let typ = match self.save_ctxt.tables().node_type_opt(hir_id) {
230230
Some(s) => s.to_string(),
231231
None => continue,
232232
};
@@ -859,7 +859,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
859859
match p.kind {
860860
hir::PatKind::Struct(ref _path, fields, _) => {
861861
// FIXME do something with _path?
862-
let adt = match self.save_ctxt.tables.node_type_opt(p.hir_id) {
862+
let adt = match self.save_ctxt.tables().node_type_opt(p.hir_id) {
863863
Some(ty) if ty.ty_adt_def().is_some() => ty.ty_adt_def().unwrap(),
864864
_ => {
865865
intravisit::walk_pat(self, p);
@@ -900,7 +900,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
900900
Res::Local(hir_id) => {
901901
let typ = self
902902
.save_ctxt
903-
.tables
903+
.tables()
904904
.node_type_opt(hir_id)
905905
.map(|t| t.to_string())
906906
.unwrap_or_default();
@@ -1393,7 +1393,7 @@ impl<'l, 'tcx> Visitor<'tcx> for DumpVisitor<'l, 'tcx> {
13931393
match ex.kind {
13941394
hir::ExprKind::Struct(ref path, ref fields, ref base) => {
13951395
let hir_expr = self.save_ctxt.tcx.hir().expect_expr(ex.hir_id);
1396-
let adt = match self.save_ctxt.tables.expr_ty_opt(&hir_expr) {
1396+
let adt = match self.save_ctxt.tables().expr_ty_opt(&hir_expr) {
13971397
Some(ty) if ty.ty_adt_def().is_some() => ty.ty_adt_def().unwrap(),
13981398
_ => {
13991399
intravisit::walk_expr(self, ex);

src/librustc_save_analysis/lib.rs

+22-14
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
22
#![feature(nll)]
33
#![feature(or_patterns)]
4+
#![cfg_attr(bootstrap, feature(track_caller))]
45
#![recursion_limit = "256"]
56

67
mod dump_visitor;
@@ -47,12 +48,9 @@ use rls_data::{
4748

4849
use log::{debug, error, info};
4950

50-
pub struct SaveContext<'l, 'tcx> {
51+
pub struct SaveContext<'l, 'tcx: 'l> {
5152
tcx: TyCtxt<'tcx>,
52-
tables: &'l ty::TypeckTables<'tcx>,
53-
/// Used as a fallback when nesting the typeck tables during item processing
54-
/// (if these are not available for that item, e.g. don't own a body)
55-
empty_tables: &'l ty::TypeckTables<'tcx>,
53+
maybe_typeck_tables: Option<&'tcx ty::TypeckTables<'tcx>>,
5654
access_levels: &'l AccessLevels,
5755
span_utils: SpanUtils<'tcx>,
5856
config: Config,
@@ -67,6 +65,14 @@ pub enum Data {
6765
}
6866

6967
impl<'l, 'tcx> SaveContext<'l, 'tcx> {
68+
/// Gets the type-checking side-tables for the current body.
69+
/// As this will ICE if called outside bodies, only call when working with
70+
/// `Expr` or `Pat` nodes (they are guaranteed to be found only in bodies).
71+
#[track_caller]
72+
fn tables(&self) -> &'tcx ty::TypeckTables<'tcx> {
73+
self.maybe_typeck_tables.expect("`SaveContext::tables` called outside of body")
74+
}
75+
7076
fn span_from_span(&self, span: Span) -> SpanData {
7177
use rls_span::{Column, Row};
7278

@@ -518,13 +524,13 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
518524
}
519525

520526
pub fn get_expr_data(&self, expr: &hir::Expr<'_>) -> Option<Data> {
521-
let ty = self.tables.expr_ty_adjusted_opt(expr)?;
527+
let ty = self.tables().expr_ty_adjusted_opt(expr)?;
522528
if matches!(ty.kind, ty::Error(_)) {
523529
return None;
524530
}
525531
match expr.kind {
526532
hir::ExprKind::Field(ref sub_ex, ident) => {
527-
match self.tables.expr_ty_adjusted(&sub_ex).kind {
533+
match self.tables().expr_ty_adjusted(&sub_ex).kind {
528534
ty::Adt(def, _) if !def.is_enum() => {
529535
let variant = &def.non_enum_variant();
530536
filter!(self.span_utils, ident.span);
@@ -569,7 +575,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
569575
}
570576
}
571577
hir::ExprKind::MethodCall(ref seg, ..) => {
572-
let method_id = match self.tables.type_dependent_def_id(expr.hir_id) {
578+
let method_id = match self.tables().type_dependent_def_id(expr.hir_id) {
573579
Some(id) => id,
574580
None => {
575581
debug!("could not resolve method id for {:?}", expr);
@@ -618,7 +624,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
618624
},
619625

620626
Node::Expr(&hir::Expr { kind: hir::ExprKind::Struct(ref qpath, ..), .. }) => {
621-
self.tables.qpath_res(qpath, hir_id)
627+
self.tables().qpath_res(qpath, hir_id)
622628
}
623629

624630
Node::Expr(&hir::Expr { kind: hir::ExprKind::Path(ref qpath), .. })
@@ -629,9 +635,12 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
629635
| hir::PatKind::TupleStruct(ref qpath, ..),
630636
..
631637
})
632-
| Node::Ty(&hir::Ty { kind: hir::TyKind::Path(ref qpath), .. }) => {
633-
self.tables.qpath_res(qpath, hir_id)
634-
}
638+
| Node::Ty(&hir::Ty { kind: hir::TyKind::Path(ref qpath), .. }) => match qpath {
639+
hir::QPath::Resolved(_, path) => path.res,
640+
hir::QPath::TypeRelative(..) => self
641+
.maybe_typeck_tables
642+
.map_or(Res::Err, |tables| tables.qpath_res(qpath, hir_id)),
643+
},
635644

636645
Node::Binding(&hir::Pat {
637646
kind: hir::PatKind::Binding(_, canonical_id, ..), ..
@@ -1001,8 +1010,7 @@ pub fn process_crate<'l, 'tcx, H: SaveHandler>(
10011010

10021011
let save_ctxt = SaveContext {
10031012
tcx,
1004-
tables: &ty::TypeckTables::empty(None),
1005-
empty_tables: &ty::TypeckTables::empty(None),
1013+
maybe_typeck_tables: None,
10061014
access_levels: &access_levels,
10071015
span_utils: SpanUtils::new(&tcx.sess),
10081016
config: find_config(config),

0 commit comments

Comments
 (0)