Skip to content

Commit 10ef344

Browse files
committed
Auto merge of #46011 - euclio:reachability-redux, r=nrc
Allow filtering analysis by reachability Fixes #43521. Fixes rust-dev-tools/rls-analysis#79. This PR allows a user to filter items present in the save-analysis data by setting the `reachable_only` config option. This option is intended for use by the new rustdoc. The PR isn't quite finished, because it's dependent on a new release of rls-data, but I want to make sure that the approach is valid. rust-dev-tools/rls-analysis#79 mentions that `pub use` might need to be handled, but my thinking is that the consumer of the analysis data would be able to infer which imports are `pub use`, and which items are only reachable through `pub use`, so that doesn't need to be handled here. r? @nrc
2 parents 6af4515 + 794ada0 commit 10ef344

File tree

5 files changed

+100
-47
lines changed

5 files changed

+100
-47
lines changed

src/Cargo.lock

+11-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/bootstrap/bin/rustc.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,8 @@ fn main() {
183183
if env::var("RUSTC_SAVE_ANALYSIS") == Ok("api".to_string()) {
184184
cmd.arg("-Zsave-analysis");
185185
cmd.env("RUST_SAVE_ANALYSIS_CONFIG",
186-
"{\"output_file\": null,\"full_docs\": false,\"pub_only\": true,\
186+
"{\"output_file\": null,\"full_docs\": false,\
187+
\"pub_only\": true,\"reachable_only\": false,\
187188
\"distro_crate\": true,\"signatures\": false,\"borrow_data\": false}");
188189
}
189190

src/librustc_save_analysis/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ rustc_data_structures = { path = "../librustc_data_structures" }
1515
rustc_typeck = { path = "../librustc_typeck" }
1616
syntax = { path = "../libsyntax" }
1717
syntax_pos = { path = "../libsyntax_pos" }
18-
rls-data = "0.12"
18+
rls-data = "0.13"
1919
rls-span = "0.4"
2020
# FIXME(#40527) should move rustc serialize out of tree
2121
rustc-serialize = "0.3"

src/librustc_save_analysis/dump_visitor.rs

+70-36
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use syntax::codemap::Spanned;
4242
use syntax_pos::*;
4343

4444
use {escape, generated_code, lower_attributes, PathCollector, SaveContext};
45-
use json_dumper::{DumpOutput, JsonDumper};
45+
use json_dumper::{Access, DumpOutput, JsonDumper};
4646
use span_utils::SpanUtils;
4747
use sig;
4848

@@ -59,6 +59,15 @@ macro_rules! down_cast_data {
5959
};
6060
}
6161

62+
macro_rules! access_from {
63+
($save_ctxt:expr, $item:expr) => {
64+
Access {
65+
public: $item.vis == ast::Visibility::Public,
66+
reachable: $save_ctxt.analysis.access_levels.is_reachable($item.id),
67+
}
68+
}
69+
}
70+
6271
pub struct DumpVisitor<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> {
6372
save_ctxt: SaveContext<'l, 'tcx>,
6473
tcx: TyCtxt<'l, 'tcx, 'tcx>,
@@ -341,7 +350,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
341350
let span = self.span_from_span(sub_span.expect("No span found for variable"));
342351

343352
self.dumper.dump_def(
344-
false,
353+
&Access {
354+
public: false,
355+
reachable: false,
356+
},
345357
Def {
346358
kind: DefKind::Local,
347359
id,
@@ -387,8 +399,12 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
387399

388400
method_data.value = sig_str;
389401
method_data.sig = sig::method_signature(id, name, generics, sig, &self.save_ctxt);
390-
self.dumper
391-
.dump_def(vis == ast::Visibility::Public, method_data);
402+
self.dumper.dump_def(
403+
&Access {
404+
public: vis == ast::Visibility::Public,
405+
reachable: self.save_ctxt.analysis.access_levels.is_reachable(id),
406+
},
407+
method_data);
392408
}
393409

394410
// walk arg and return types
@@ -409,8 +425,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
409425
fn process_struct_field_def(&mut self, field: &ast::StructField, parent_id: NodeId) {
410426
let field_data = self.save_ctxt.get_field_data(field, parent_id);
411427
if let Some(field_data) = field_data {
412-
self.dumper
413-
.dump_def(field.vis == ast::Visibility::Public, field_data);
428+
self.dumper.dump_def(&access_from!(self.save_ctxt, field), field_data);
414429
}
415430
}
416431

@@ -432,7 +447,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
432447
let span = self.span_from_span(param_ss);
433448

434449
self.dumper.dump_def(
435-
false,
450+
&Access {
451+
public: false,
452+
reachable: false,
453+
},
436454
Def {
437455
kind: DefKind::Type,
438456
id,
@@ -467,8 +485,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
467485
|v| v.process_formals(&decl.inputs, &fn_data.qualname),
468486
);
469487
self.process_generic_params(ty_params, item.span, &fn_data.qualname, item.id);
470-
self.dumper
471-
.dump_def(item.vis == ast::Visibility::Public, fn_data);
488+
self.dumper.dump_def(&access_from!(self.save_ctxt, item), fn_data);
472489
}
473490

474491
for arg in &decl.inputs {
@@ -491,8 +508,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
491508
self.nest_tables(item.id, |v| {
492509
if let Some(var_data) = v.save_ctxt.get_item_data(item) {
493510
down_cast_data!(var_data, DefData, item.span);
494-
v.dumper
495-
.dump_def(item.vis == ast::Visibility::Public, var_data);
511+
v.dumper.dump_def(&access_from!(v.save_ctxt, item), var_data);
496512
}
497513
v.visit_ty(&typ);
498514
v.visit_expr(expr);
@@ -516,14 +532,16 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
516532

517533
if !self.span.filter_generated(sub_span, span) {
518534
let sig = sig::assoc_const_signature(id, name, typ, expr, &self.save_ctxt);
519-
let id = ::id_from_node_id(id, &self.save_ctxt);
520535
let span = self.span_from_span(sub_span.expect("No span found for variable"));
521536

522537
self.dumper.dump_def(
523-
vis == ast::Visibility::Public,
538+
&Access {
539+
public: vis == ast::Visibility::Public,
540+
reachable: self.save_ctxt.analysis.access_levels.is_reachable(id),
541+
},
524542
Def {
525543
kind: DefKind::Const,
526-
id,
544+
id: ::id_from_node_id(id, &self.save_ctxt),
527545
span,
528546
name: name.to_string(),
529547
qualname,
@@ -596,7 +614,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
596614
if !self.span.filter_generated(sub_span, item.span) {
597615
let span = self.span_from_span(sub_span.expect("No span found for struct"));
598616
self.dumper.dump_def(
599-
item.vis == ast::Visibility::Public,
617+
&access_from!(self.save_ctxt, item),
600618
Def {
601619
kind,
602620
id: ::id_from_node_id(item.id, &self.save_ctxt),
@@ -635,6 +653,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
635653
};
636654
down_cast_data!(enum_data, DefData, item.span);
637655

656+
let access = access_from!(self.save_ctxt, item);
657+
638658
for variant in &enum_definition.variants {
639659
let name = variant.node.name.name.to_string();
640660
let mut qualname = enum_data.qualname.clone();
@@ -660,7 +680,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
660680
let parent = Some(::id_from_node_id(item.id, &self.save_ctxt));
661681

662682
self.dumper.dump_def(
663-
item.vis == ast::Visibility::Public,
683+
&access,
664684
Def {
665685
kind: DefKind::StructVariant,
666686
id,
@@ -700,7 +720,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
700720
let parent = Some(::id_from_node_id(item.id, &self.save_ctxt));
701721

702722
self.dumper.dump_def(
703-
item.vis == ast::Visibility::Public,
723+
&access,
704724
Def {
705725
kind: DefKind::TupleVariant,
706726
id,
@@ -730,8 +750,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
730750
}
731751
}
732752
self.process_generic_params(ty_params, item.span, &enum_data.qualname, item.id);
733-
self.dumper
734-
.dump_def(item.vis == ast::Visibility::Public, enum_data);
753+
self.dumper.dump_def(&access, enum_data);
735754
}
736755

737756
fn process_impl(
@@ -783,7 +802,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
783802
.map(|i| ::id_from_node_id(i.id, &self.save_ctxt))
784803
.collect();
785804
self.dumper.dump_def(
786-
item.vis == ast::Visibility::Public,
805+
&access_from!(self.save_ctxt, item),
787806
Def {
788807
kind: DefKind::Trait,
789808
id,
@@ -846,8 +865,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
846865
fn process_mod(&mut self, item: &ast::Item) {
847866
if let Some(mod_data) = self.save_ctxt.get_item_data(item) {
848867
down_cast_data!(mod_data, DefData, item.span);
849-
self.dumper
850-
.dump_def(item.vis == ast::Visibility::Public, mod_data);
868+
self.dumper.dump_def(&access_from!(self.save_ctxt, item), mod_data);
851869
}
852870
}
853871

@@ -1038,7 +1056,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
10381056
let span = self.span_from_span(sub_span.expect("No span found for variable"));
10391057

10401058
self.dumper.dump_def(
1041-
false,
1059+
&Access {
1060+
public: false,
1061+
reachable: false,
1062+
},
10421063
Def {
10431064
kind: DefKind::Local,
10441065
id,
@@ -1138,7 +1159,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
11381159
let id = ::id_from_node_id(trait_item.id, &self.save_ctxt);
11391160

11401161
self.dumper.dump_def(
1141-
true,
1162+
&Access {
1163+
public: true,
1164+
reachable: true,
1165+
},
11421166
Def {
11431167
kind: DefKind::Type,
11441168
id,
@@ -1225,7 +1249,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
12251249
let span = self.span_from_span(span);
12261250

12271251
self.dumper.dump_def(
1228-
true,
1252+
&Access {
1253+
public: true,
1254+
reachable: true,
1255+
},
12291256
Def {
12301257
kind: DefKind::Mod,
12311258
id: data_id,
@@ -1249,6 +1276,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
12491276
self.process_macro_use(item.span);
12501277
match item.node {
12511278
Use(ref use_item) => {
1279+
let access = access_from!(self.save_ctxt, item);
1280+
12521281
match use_item.node {
12531282
ast::ViewPathSimple(ident, ref path) => {
12541283
let sub_span = self.span.span_for_last_ident(path.span);
@@ -1273,7 +1302,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
12731302
let span =
12741303
self.span_from_span(sub_span.expect("No span found for use"));
12751304
self.dumper.import(
1276-
item.vis == ast::Visibility::Public,
1305+
&access,
12771306
Import {
12781307
kind: ImportKind::Use,
12791308
ref_id: mod_id.map(|id| ::id_from_def_id(id)),
@@ -1302,7 +1331,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
13021331
let span =
13031332
self.span_from_span(sub_span.expect("No span found for use glob"));
13041333
self.dumper.import(
1305-
item.vis == ast::Visibility::Public,
1334+
&access,
13061335
Import {
13071336
kind: ImportKind::GlobUse,
13081337
ref_id: None,
@@ -1334,7 +1363,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
13341363
let span =
13351364
self.span_from_span(alias_span.expect("No span found for extern crate"));
13361365
self.dumper.import(
1337-
false,
1366+
&Access {
1367+
public: false,
1368+
reachable: false,
1369+
},
13381370
Import {
13391371
kind: ImportKind::ExternCrate,
13401372
ref_id: None,
@@ -1373,7 +1405,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
13731405
let id = ::id_from_node_id(item.id, &self.save_ctxt);
13741406

13751407
self.dumper.dump_def(
1376-
item.vis == ast::Visibility::Public,
1408+
&access_from!(self.save_ctxt, item),
13771409
Def {
13781410
kind: DefKind::Type,
13791411
id,
@@ -1596,7 +1628,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
15961628
let span = self.span_from_span(sp);
15971629

15981630
self.dumper.dump_def(
1599-
false,
1631+
&Access {
1632+
public: false,
1633+
reachable: false,
1634+
},
16001635
Def {
16011636
kind: DefKind::Local,
16021637
id,
@@ -1662,6 +1697,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
16621697
}
16631698

16641699
fn visit_foreign_item(&mut self, item: &'l ast::ForeignItem) {
1700+
let access = access_from!(self.save_ctxt, item);
1701+
16651702
match item.node {
16661703
ast::ForeignItemKind::Fn(ref decl, ref generics) => {
16671704
if let Some(fn_data) = self.save_ctxt.get_extern_item_data(item) {
@@ -1672,8 +1709,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
16721709
|v| v.process_formals(&decl.inputs, &fn_data.qualname),
16731710
);
16741711
self.process_generic_params(generics, item.span, &fn_data.qualname, item.id);
1675-
self.dumper
1676-
.dump_def(item.vis == ast::Visibility::Public, fn_data);
1712+
self.dumper.dump_def(&access, fn_data);
16771713
}
16781714

16791715
for arg in &decl.inputs {
@@ -1687,17 +1723,15 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
16871723
ast::ForeignItemKind::Static(ref ty, _) => {
16881724
if let Some(var_data) = self.save_ctxt.get_extern_item_data(item) {
16891725
down_cast_data!(var_data, DefData, item.span);
1690-
self.dumper
1691-
.dump_def(item.vis == ast::Visibility::Public, var_data);
1726+
self.dumper.dump_def(&access, var_data);
16921727
}
16931728

16941729
self.visit_ty(ty);
16951730
}
16961731
ast::ForeignItemKind::Ty => {
16971732
if let Some(var_data) = self.save_ctxt.get_extern_item_data(item) {
16981733
down_cast_data!(var_data, DefData, item.span);
1699-
self.dumper
1700-
.dump_def(item.vis == ast::Visibility::Public, var_data);
1734+
self.dumper.dump_def(&access, var_data);
17011735
}
17021736
}
17031737
}

0 commit comments

Comments
 (0)