Skip to content

Commit 820fb7c

Browse files
authored
Rollup merge of #65353 - Xanewok:sa-empty-tables, r=nikomatsakis
save-analysis: Don't ICE when resolving qualified type paths in struct members Previously, we failed since we use `qpath_res` via typeck tables - when using those we need to pass in a HirId that's local to the definition path the tables are rooted at (otherwise we risk frame of reference mismatch and an assertion against invalid lookup). In this case we can't get typeck tables for struct definition because it has no body, however the struct member type node is rooted under the struct definition and so we can't really do anything about it in terms of traversal. Instead, we try to "nest" the tables as always but change the default behaviour to use empty typeck tables rather than silently trying to use the current ones. This does work as we expect and for prior art, we use the same approach in the [privacy](https://github.com/rust-lang/rust/blob/7bc94cc3c2ccef8b4d393910bb978a6487db1202/src/librustc_privacy/lib.rs#L332-L341) [pass](https://github.com/rust-lang/rust/blob/7bc94cc3c2ccef8b4d393910bb978a6487db1202/src/librustc_privacy/lib.rs#L1007-L1028). Fixes #64659. Fixes #64821. r? @nikomatsakis (since this changes the default behaviour introduced in d7d3f19)
2 parents 42b3596 + eefc169 commit 820fb7c

File tree

3 files changed

+31
-13
lines changed

3 files changed

+31
-13
lines changed

src/librustc_save_analysis/dump_visitor.rs

+17-13
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,17 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
115115
F: FnOnce(&mut Self),
116116
{
117117
let item_def_id = self.tcx.hir().local_def_id_from_node_id(item_id);
118-
if self.tcx.has_typeck_tables(item_def_id) {
119-
let tables = self.tcx.typeck_tables_of(item_def_id);
120-
let old_tables = self.save_ctxt.tables;
121-
self.save_ctxt.tables = tables;
122-
f(self);
123-
self.save_ctxt.tables = old_tables;
118+
119+
let tables = if self.tcx.has_typeck_tables(item_def_id) {
120+
self.tcx.typeck_tables_of(item_def_id)
124121
} else {
125-
f(self);
126-
}
122+
self.save_ctxt.empty_tables
123+
};
124+
125+
let old_tables = self.save_ctxt.tables;
126+
self.save_ctxt.tables = tables;
127+
f(self);
128+
self.save_ctxt.tables = old_tables;
127129
}
128130

129131
fn span_from_span(&self, span: Span) -> SpanData {
@@ -530,12 +532,14 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
530532
);
531533
}
532534

533-
for field in def.fields() {
534-
self.process_struct_field_def(field, item.id);
535-
self.visit_ty(&field.ty);
536-
}
535+
self.nest_tables(item.id, |v| {
536+
for field in def.fields() {
537+
v.process_struct_field_def(field, item.id);
538+
v.visit_ty(&field.ty);
539+
}
537540

538-
self.process_generic_params(ty_params, &qualname, item.id);
541+
v.process_generic_params(ty_params, &qualname, item.id);
542+
});
539543
}
540544

541545
fn process_enum(

src/librustc_save_analysis/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ use log::{debug, error, info};
4848
pub struct SaveContext<'l, 'tcx> {
4949
tcx: TyCtxt<'tcx>,
5050
tables: &'l ty::TypeckTables<'tcx>,
51+
/// Used as a fallback when nesting the typeck tables during item processing
52+
/// (if these are not available for that item, e.g. don't own a body)
53+
empty_tables: &'l ty::TypeckTables<'tcx>,
5154
access_levels: &'l AccessLevels,
5255
span_utils: SpanUtils<'tcx>,
5356
config: Config,
@@ -1114,6 +1117,7 @@ pub fn process_crate<'l, 'tcx, H: SaveHandler>(
11141117
let save_ctxt = SaveContext {
11151118
tcx,
11161119
tables: &ty::TypeckTables::empty(None),
1120+
empty_tables: &ty::TypeckTables::empty(None),
11171121
access_levels: &access_levels,
11181122
span_utils: SpanUtils::new(&tcx.sess),
11191123
config: find_config(config),
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// check-pass
2+
// compile-flags: -Zsave-analysis
3+
4+
trait Trait { type Assoc; }
5+
6+
fn main() {
7+
struct Data<T: Trait> {
8+
x: T::Assoc,
9+
}
10+
}

0 commit comments

Comments
 (0)