Skip to content

Commit 1eaadeb

Browse files
committed
Auto merge of #78077 - petrochenkov:qvis, r=davidtwco
Calculate visibilities once in resolve Then use them through a query based on resolver outputs. Item visibilities were previously calculated in three places - initially in `rustc_resolve`, then in `rustc_privacy` during type privacy checkin, and then in `rustc_metadata` during metadata encoding. The visibility logic is not entirely trivial, especially for things like constructors or enum variants, and all of it was duplicated. This PR deduplicates all the visibility calculations, visibilities are determined once during early name resolution and then stored in `ResolverOutputs` and are later available through `tcx` as a query `tcx.visibility(def_id)`. (This query existed previously, but only worked for other crates.) Some special cases (e.g. visibilities for closure types, which are needed for type privacy checking) are not processed in resolve, but deferred and performed directly in the query instead.
2 parents 1d27267 + cee5521 commit 1eaadeb

26 files changed

+322
-408
lines changed

compiler/rustc_hir/src/hir.rs

-9
Original file line numberDiff line numberDiff line change
@@ -2381,15 +2381,6 @@ impl VisibilityKind<'_> {
23812381
VisibilityKind::Crate(..) | VisibilityKind::Restricted { .. } => true,
23822382
}
23832383
}
2384-
2385-
pub fn descr(&self) -> &'static str {
2386-
match *self {
2387-
VisibilityKind::Public => "public",
2388-
VisibilityKind::Inherited => "private",
2389-
VisibilityKind::Crate(..) => "crate-visible",
2390-
VisibilityKind::Restricted { .. } => "restricted",
2391-
}
2392-
}
23932384
}
23942385

23952386
#[derive(Debug, HashStable_Generic)]

compiler/rustc_metadata/src/rmeta/encoder.rs

+13-56
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
2828
use rustc_serialize::{opaque, Encodable, Encoder};
2929
use rustc_session::config::CrateType;
3030
use rustc_span::hygiene::{ExpnDataEncodeMode, HygieneEncodeContext};
31-
use rustc_span::source_map::Spanned;
3231
use rustc_span::symbol::{sym, Ident, Symbol};
3332
use rustc_span::{self, ExternalSource, FileName, SourceFile, Span, SyntaxContext};
3433
use rustc_target::abi::VariantIdx;
@@ -436,8 +435,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
436435

437436
fn encode_info_for_items(&mut self) {
438437
let krate = self.tcx.hir().krate();
439-
let vis = Spanned { span: rustc_span::DUMMY_SP, node: hir::VisibilityKind::Public };
440-
self.encode_info_for_mod(hir::CRATE_HIR_ID, &krate.item.module, &krate.item.attrs, &vis);
438+
self.encode_info_for_mod(hir::CRATE_HIR_ID, &krate.item.module, &krate.item.attrs);
441439

442440
// Proc-macro crates only export proc-macro items, which are looked
443441
// up using `proc_macro_data`
@@ -739,12 +737,8 @@ impl EncodeContext<'a, 'tcx> {
739737
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
740738
};
741739

742-
let enum_id = tcx.hir().local_def_id_to_hir_id(def.did.expect_local());
743-
let enum_vis = &tcx.hir().expect_item(enum_id).vis;
744-
745740
record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
746-
record!(self.tables.visibility[def_id] <-
747-
ty::Visibility::from_hir(enum_vis, enum_id, self.tcx));
741+
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
748742
record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
749743
record!(self.tables.attributes[def_id] <- &self.tcx.get_attrs(def_id)[..]);
750744
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expansion_that_defined(def_id));
@@ -785,17 +779,8 @@ impl EncodeContext<'a, 'tcx> {
785779
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
786780
};
787781

788-
// Variant constructors have the same visibility as the parent enums, unless marked as
789-
// non-exhaustive, in which case they are lowered to `pub(crate)`.
790-
let enum_id = tcx.hir().local_def_id_to_hir_id(def.did.expect_local());
791-
let enum_vis = &tcx.hir().expect_item(enum_id).vis;
792-
let mut ctor_vis = ty::Visibility::from_hir(enum_vis, enum_id, tcx);
793-
if variant.is_field_list_non_exhaustive() && ctor_vis == ty::Visibility::Public {
794-
ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
795-
}
796-
797782
record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
798-
record!(self.tables.visibility[def_id] <- ctor_vis);
783+
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
799784
record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
800785
self.encode_stability(def_id);
801786
self.encode_deprecation(def_id);
@@ -811,13 +796,7 @@ impl EncodeContext<'a, 'tcx> {
811796
self.encode_promoted_mir(def_id.expect_local());
812797
}
813798

814-
fn encode_info_for_mod(
815-
&mut self,
816-
id: hir::HirId,
817-
md: &hir::Mod<'_>,
818-
attrs: &[ast::Attribute],
819-
vis: &hir::Visibility<'_>,
820-
) {
799+
fn encode_info_for_mod(&mut self, id: hir::HirId, md: &hir::Mod<'_>, attrs: &[ast::Attribute]) {
821800
let tcx = self.tcx;
822801
let local_def_id = tcx.hir().local_def_id(id);
823802
let def_id = local_def_id.to_def_id();
@@ -850,7 +829,7 @@ impl EncodeContext<'a, 'tcx> {
850829
};
851830

852831
record!(self.tables.kind[def_id] <- EntryKind::Mod(self.lazy(data)));
853-
record!(self.tables.visibility[def_id] <- ty::Visibility::from_hir(vis, id, self.tcx));
832+
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
854833
record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
855834
record!(self.tables.attributes[def_id] <- attrs);
856835
if self.is_proc_macro {
@@ -881,7 +860,7 @@ impl EncodeContext<'a, 'tcx> {
881860
let variant_data = tcx.hir().expect_variant_data(variant_id);
882861

883862
record!(self.tables.kind[def_id] <- EntryKind::Field);
884-
record!(self.tables.visibility[def_id] <- field.vis);
863+
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
885864
record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
886865
record!(self.tables.attributes[def_id] <- variant_data.fields()[field_index].attrs);
887866
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expansion_that_defined(def_id));
@@ -906,25 +885,8 @@ impl EncodeContext<'a, 'tcx> {
906885
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
907886
};
908887

909-
let struct_id = tcx.hir().local_def_id_to_hir_id(adt_def.did.expect_local());
910-
let struct_vis = &tcx.hir().expect_item(struct_id).vis;
911-
let mut ctor_vis = ty::Visibility::from_hir(struct_vis, struct_id, tcx);
912-
for field in &variant.fields {
913-
if ctor_vis.is_at_least(field.vis, tcx) {
914-
ctor_vis = field.vis;
915-
}
916-
}
917-
918-
// If the structure is marked as non_exhaustive then lower the visibility
919-
// to within the crate.
920-
if adt_def.non_enum_variant().is_field_list_non_exhaustive()
921-
&& ctor_vis == ty::Visibility::Public
922-
{
923-
ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
924-
}
925-
926888
record!(self.tables.kind[def_id] <- EntryKind::Struct(self.lazy(data), adt_def.repr));
927-
record!(self.tables.visibility[def_id] <- ctor_vis);
889+
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
928890
record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
929891
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expansion_that_defined(def_id));
930892
self.encode_stability(def_id);
@@ -1030,7 +992,7 @@ impl EncodeContext<'a, 'tcx> {
1030992
EntryKind::AssocType(container)
1031993
}
1032994
});
1033-
record!(self.tables.visibility[def_id] <- trait_item.vis);
995+
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
1034996
record!(self.tables.span[def_id] <- ast_item.span);
1035997
record!(self.tables.attributes[def_id] <- ast_item.attrs);
1036998
self.encode_ident_span(def_id, ast_item.ident);
@@ -1112,7 +1074,7 @@ impl EncodeContext<'a, 'tcx> {
11121074
}
11131075
ty::AssocKind::Type => EntryKind::AssocType(container)
11141076
});
1115-
record!(self.tables.visibility[def_id] <- impl_item.vis);
1077+
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
11161078
record!(self.tables.span[def_id] <- ast_item.span);
11171079
record!(self.tables.attributes[def_id] <- ast_item.attrs);
11181080
self.encode_ident_span(def_id, impl_item.ident);
@@ -1261,7 +1223,7 @@ impl EncodeContext<'a, 'tcx> {
12611223
EntryKind::Fn(self.lazy(data))
12621224
}
12631225
hir::ItemKind::Mod(ref m) => {
1264-
return self.encode_info_for_mod(item.hir_id, m, &item.attrs, &item.vis);
1226+
return self.encode_info_for_mod(item.hir_id, m, &item.attrs);
12651227
}
12661228
hir::ItemKind::ForeignMod(_) => EntryKind::ForeignMod,
12671229
hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm,
@@ -1352,8 +1314,7 @@ impl EncodeContext<'a, 'tcx> {
13521314
hir::ItemKind::ExternCrate(_) |
13531315
hir::ItemKind::Use(..) => bug!("cannot encode info for item {:?}", item),
13541316
});
1355-
record!(self.tables.visibility[def_id] <-
1356-
ty::Visibility::from_hir(&item.vis, item.hir_id, tcx));
1317+
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
13571318
record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
13581319
record!(self.tables.attributes[def_id] <- item.attrs);
13591320
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expansion_that_defined(def_id));
@@ -1470,7 +1431,7 @@ impl EncodeContext<'a, 'tcx> {
14701431
fn encode_info_for_macro_def(&mut self, macro_def: &hir::MacroDef<'_>) {
14711432
let def_id = self.tcx.hir().local_def_id(macro_def.hir_id).to_def_id();
14721433
record!(self.tables.kind[def_id] <- EntryKind::MacroDef(self.lazy(macro_def.ast.clone())));
1473-
record!(self.tables.visibility[def_id] <- ty::Visibility::Public);
1434+
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
14741435
record!(self.tables.span[def_id] <- macro_def.span);
14751436
record!(self.tables.attributes[def_id] <- macro_def.attrs);
14761437
self.encode_ident_span(def_id, macro_def.ident);
@@ -1480,7 +1441,6 @@ impl EncodeContext<'a, 'tcx> {
14801441

14811442
fn encode_info_for_generic_param(&mut self, def_id: DefId, kind: EntryKind, encode_type: bool) {
14821443
record!(self.tables.kind[def_id] <- kind);
1483-
record!(self.tables.visibility[def_id] <- ty::Visibility::Public);
14841444
record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
14851445
if encode_type {
14861446
self.encode_item_type(def_id);
@@ -1505,7 +1465,6 @@ impl EncodeContext<'a, 'tcx> {
15051465

15061466
_ => bug!("closure that is neither generator nor closure"),
15071467
});
1508-
record!(self.tables.visibility[def_id.to_def_id()] <- ty::Visibility::Public);
15091468
record!(self.tables.span[def_id.to_def_id()] <- self.tcx.def_span(def_id));
15101469
record!(self.tables.attributes[def_id.to_def_id()] <- &self.tcx.get_attrs(def_id.to_def_id())[..]);
15111470
self.encode_item_type(def_id.to_def_id());
@@ -1525,7 +1484,6 @@ impl EncodeContext<'a, 'tcx> {
15251484
let qualifs = self.tcx.mir_const_qualif(def_id);
15261485

15271486
record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::AnonConst(qualifs, const_data));
1528-
record!(self.tables.visibility[def_id.to_def_id()] <- ty::Visibility::Public);
15291487
record!(self.tables.span[def_id.to_def_id()] <- self.tcx.def_span(def_id));
15301488
self.encode_item_type(def_id.to_def_id());
15311489
self.encode_generics(def_id.to_def_id());
@@ -1762,8 +1720,7 @@ impl EncodeContext<'a, 'tcx> {
17621720
hir::ForeignItemKind::Static(_, hir::Mutability::Not) => EntryKind::ForeignImmStatic,
17631721
hir::ForeignItemKind::Type => EntryKind::ForeignType,
17641722
});
1765-
record!(self.tables.visibility[def_id] <-
1766-
ty::Visibility::from_hir(&nitem.vis, nitem.hir_id, self.tcx));
1723+
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
17671724
record!(self.tables.span[def_id] <- nitem.span);
17681725
record!(self.tables.attributes[def_id] <- nitem.attrs);
17691726
self.encode_ident_span(def_id, nitem.ident);

compiler/rustc_middle/src/middle/stability.rs

+5-17
Original file line numberDiff line numberDiff line change
@@ -256,24 +256,12 @@ pub enum EvalResult {
256256
}
257257

258258
// See issue #38412.
259-
fn skip_stability_check_due_to_privacy(tcx: TyCtxt<'_>, mut def_id: DefId) -> bool {
260-
// Check if `def_id` is a trait method.
261-
match tcx.def_kind(def_id) {
262-
DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => {
263-
if let ty::TraitContainer(trait_def_id) = tcx.associated_item(def_id).container {
264-
// Trait methods do not declare visibility (even
265-
// for visibility info in cstore). Use containing
266-
// trait instead, so methods of `pub` traits are
267-
// themselves considered `pub`.
268-
def_id = trait_def_id;
269-
}
270-
}
271-
_ => {}
259+
fn skip_stability_check_due_to_privacy(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
260+
if tcx.def_kind(def_id) == DefKind::TyParam {
261+
// Have no visibility, considered public for the purpose of this check.
262+
return false;
272263
}
273-
274-
let visibility = tcx.visibility(def_id);
275-
276-
match visibility {
264+
match tcx.visibility(def_id) {
277265
// Must check stability for `pub` items.
278266
ty::Visibility::Public => false,
279267

compiler/rustc_middle/src/query/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,7 @@ rustc_queries! {
12671267

12681268
TypeChecking {
12691269
query visibility(def_id: DefId) -> ty::Visibility {
1270+
eval_always
12701271
desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) }
12711272
}
12721273
}

compiler/rustc_middle/src/ty/context.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::ty::{
2222
ExistentialPredicate, FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntVar,
2323
IntVid, List, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateInner, PredicateKind,
2424
ProjectionTy, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar,
25-
TyVid, TypeAndMut,
25+
TyVid, TypeAndMut, Visibility,
2626
};
2727
use rustc_ast as ast;
2828
use rustc_ast::expand::allocator::AllocatorKind;
@@ -911,6 +911,9 @@ pub struct GlobalCtxt<'tcx> {
911911
/// Common consts, pre-interned for your convenience.
912912
pub consts: CommonConsts<'tcx>,
913913

914+
/// Visibilities produced by resolver.
915+
pub visibilities: FxHashMap<LocalDefId, Visibility>,
916+
914917
/// Resolutions of `extern crate` items produced by resolver.
915918
extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
916919

@@ -1124,6 +1127,7 @@ impl<'tcx> TyCtxt<'tcx> {
11241127
types: common_types,
11251128
lifetimes: common_lifetimes,
11261129
consts: common_consts,
1130+
visibilities: resolutions.visibilities,
11271131
extern_crate_map: resolutions.extern_crate_map,
11281132
trait_map,
11291133
export_map: resolutions.export_map,

compiler/rustc_middle/src/ty/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ mod sty;
125125
pub struct ResolverOutputs {
126126
pub definitions: rustc_hir::definitions::Definitions,
127127
pub cstore: Box<CrateStoreDyn>,
128+
pub visibilities: FxHashMap<LocalDefId, Visibility>,
128129
pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
129130
pub maybe_unused_trait_imports: FxHashSet<LocalDefId>,
130131
pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,

0 commit comments

Comments
 (0)