Skip to content

Commit ceb2e03

Browse files
committed
Add fn visibility local provider in rustc_metadata
This also changes rustc_metadata to use `tcx.visibility()` for `record!`ing metadata.
1 parent c38f001 commit ceb2e03

File tree

2 files changed

+79
-32
lines changed

2 files changed

+79
-32
lines changed

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+1
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ pub fn provide(providers: &mut Providers) {
288288
Lrc::new(link_args::collect(tcx))
289289
},
290290

291+
visibility: crate::rmeta::encoder::visibility,
291292
// Returns a map from a sufficiently visible external item (i.e., an
292293
// external item that is visible from at least one local module) to a
293294
// sufficiently visible parent (considering modules that re-export the

compiler/rustc_metadata/src/rmeta/encoder.rs

+78-32
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));
@@ -1030,7 +1009,7 @@ impl EncodeContext<'a, 'tcx> {
10301009
EntryKind::AssocType(container)
10311010
}
10321011
});
1033-
record!(self.tables.visibility[def_id] <- trait_item.vis);
1012+
record!(self.tables.visibility[def_id] <- tcx.visibility(def_id));
10341013
record!(self.tables.span[def_id] <- ast_item.span);
10351014
record!(self.tables.attributes[def_id] <- ast_item.attrs);
10361015
self.encode_ident_span(def_id, ast_item.ident);
@@ -1112,7 +1091,7 @@ impl EncodeContext<'a, 'tcx> {
11121091
}
11131092
ty::AssocKind::Type => EntryKind::AssocType(container)
11141093
});
1115-
record!(self.tables.visibility[def_id] <- impl_item.vis);
1094+
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
11161095
record!(self.tables.span[def_id] <- ast_item.span);
11171096
record!(self.tables.attributes[def_id] <- ast_item.attrs);
11181097
self.encode_ident_span(def_id, impl_item.ident);
@@ -1261,7 +1240,7 @@ impl EncodeContext<'a, 'tcx> {
12611240
EntryKind::Fn(self.lazy(data))
12621241
}
12631242
hir::ItemKind::Mod(ref m) => {
1264-
return self.encode_info_for_mod(item.hir_id, m, &item.attrs, &item.vis);
1243+
return self.encode_info_for_mod(item.hir_id, m, &item.attrs);
12651244
}
12661245
hir::ItemKind::ForeignMod(_) => EntryKind::ForeignMod,
12671246
hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm,
@@ -1762,8 +1741,7 @@ impl EncodeContext<'a, 'tcx> {
17621741
hir::ForeignItemKind::Static(_, hir::Mutability::Not) => EntryKind::ForeignImmStatic,
17631742
hir::ForeignItemKind::Type => EntryKind::ForeignType,
17641743
});
1765-
record!(self.tables.visibility[def_id] <-
1766-
ty::Visibility::from_hir(&nitem.vis, nitem.hir_id, self.tcx));
1744+
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
17671745
record!(self.tables.span[def_id] <- nitem.span);
17681746
record!(self.tables.attributes[def_id] <- nitem.attrs);
17691747
self.encode_ident_span(def_id, nitem.ident);
@@ -2122,3 +2100,71 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata {
21222100

21232101
EncodedMetadata { raw_data: result }
21242102
}
2103+
2104+
crate fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility {
2105+
use rustc_hir::Node;
2106+
2107+
// crates are not in the HIR map
2108+
if def_id.index == CRATE_DEF_INDEX {
2109+
return ty::Visibility::Public;
2110+
}
2111+
2112+
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.as_local().unwrap());
2113+
let vis = match tcx.hir().get(hir_id) {
2114+
Node::Item(item) => ty::Visibility::from_hir(&item.vis, hir_id, tcx),
2115+
Node::Variant(_) => {
2116+
let enum_id = tcx.hir().local_def_id_to_hir_id(hir_id.owner);
2117+
let enum_vis = &tcx.hir().expect_item(enum_id).vis;
2118+
ty::Visibility::from_hir(enum_vis, enum_id, tcx)
2119+
}
2120+
Node::Field(_) => {
2121+
let adt_def = tcx.adt_def(hir_id.owner);
2122+
let field = &adt_def.all_fields().find(|field| field.did == def_id);
2123+
field.unwrap().vis
2124+
}
2125+
Node::Ctor(hir::VariantData::Struct(..)) => {
2126+
let adt_def = tcx.adt_def(hir_id.owner);
2127+
let struct_id = tcx.hir().local_def_id_to_hir_id(adt_def.did.expect_local());
2128+
let struct_vis = &tcx.hir().expect_item(struct_id).vis;
2129+
let mut ctor_vis = ty::Visibility::from_hir(struct_vis, struct_id, tcx);
2130+
2131+
let variant = adt_def.non_enum_variant();
2132+
for field in &variant.fields {
2133+
if ctor_vis.is_at_least(field.vis, tcx) {
2134+
ctor_vis = field.vis;
2135+
}
2136+
}
2137+
2138+
// If the structure is marked as non_exhaustive then lower the visibility
2139+
// to within the crate.
2140+
if adt_def.non_enum_variant().is_field_list_non_exhaustive()
2141+
&& ctor_vis == ty::Visibility::Public
2142+
{
2143+
ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
2144+
}
2145+
2146+
ctor_vis
2147+
}
2148+
Node::Ctor(_) => {
2149+
// Variant constructors have the same visibility as the parent enums, unless marked as
2150+
// non-exhaustive, in which case they are lowered to `pub(crate)`.
2151+
let parent = tcx.hir().local_def_id_to_hir_id(hir_id.owner);
2152+
let enum_vis = &tcx.hir().expect_item(parent).vis;
2153+
let mut ctor_vis = ty::Visibility::from_hir(enum_vis, hir_id, tcx);
2154+
2155+
let adt_def = tcx.adt_def(hir_id.owner);
2156+
debug!("looking for variant of {:?} with id {:?}", adt_def, def_id);
2157+
let variant = adt_def.variant_with_ctor_id(def_id);
2158+
if variant.is_field_list_non_exhaustive() && ctor_vis == ty::Visibility::Public {
2159+
ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
2160+
}
2161+
ctor_vis
2162+
}
2163+
Node::TraitItem(_) | Node::ImplItem(_) => tcx.associated_item(def_id).vis,
2164+
Node::ForeignItem(nitem) => ty::Visibility::from_hir(&nitem.vis, nitem.hir_id, tcx),
2165+
other => bug!("visibility: unknown node {:?}", other),
2166+
};
2167+
2168+
debug!("found {:?} to have visibility {:?}", def_id, vis);
2169+
vis
2170+
}

0 commit comments

Comments
 (0)