rustc: Remove local variable IDs from Exports

Local variables can never be exported.
This commit is contained in:
Vadim Petrochenkov 2021-09-05 23:37:15 +03:00
parent b69fe57261
commit 294510e1bb
19 changed files with 71 additions and 68 deletions

View file

@ -21,6 +21,7 @@
#![feature(iter_map_while)] #![feature(iter_map_while)]
#![feature(maybe_uninit_uninit_array)] #![feature(maybe_uninit_uninit_array)]
#![feature(min_specialization)] #![feature(min_specialization)]
#![feature(never_type)]
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
#![feature(new_uninit)] #![feature(new_uninit)]
#![feature(nll)] #![feature(nll)]

View file

@ -209,6 +209,12 @@ impl_stable_hash_via_hash!(i128);
impl_stable_hash_via_hash!(char); impl_stable_hash_via_hash!(char);
impl_stable_hash_via_hash!(()); impl_stable_hash_via_hash!(());
impl<CTX> HashStable<CTX> for ! {
fn hash_stable(&self, _ctx: &mut CTX, _hasher: &mut StableHasher) {
unreachable!()
}
}
impl<CTX> HashStable<CTX> for ::std::num::NonZeroU32 { impl<CTX> HashStable<CTX> for ::std::num::NonZeroU32 {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
self.get().hash_stable(ctx, hasher) self.get().hash_stable(ctx, hasher)

View file

@ -598,6 +598,11 @@ impl<Id> Res<Id> {
} }
} }
#[track_caller]
pub fn expect_non_local<OtherId>(self) -> Res<OtherId> {
self.map_id(|_| panic!("unexpected `Res::Local`"))
}
pub fn macro_kind(self) -> Option<MacroKind> { pub fn macro_kind(self) -> Option<MacroKind> {
match self { match self {
Res::Def(DefKind::Macro(kind), _) => Some(kind), Res::Def(DefKind::Macro(kind), _) => Some(kind),

View file

@ -1019,10 +1019,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
} }
/// Iterates over each child of the given item. /// Iterates over each child of the given item.
fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F, sess: &Session) fn each_child_of_item(&self, id: DefIndex, mut callback: impl FnMut(Export), sess: &Session) {
where
F: FnMut(Export<hir::HirId>),
{
if let Some(data) = &self.root.proc_macro_data { if let Some(data) = &self.root.proc_macro_data {
/* If we are loading as a proc macro, we want to return the view of this crate /* If we are loading as a proc macro, we want to return the view of this crate
* as a proc macro crate. * as a proc macro crate.

View file

@ -5,7 +5,6 @@ use crate::rmeta::encoder;
use rustc_ast as ast; use rustc_ast as ast;
use rustc_data_structures::stable_map::FxHashMap; use rustc_data_structures::stable_map::FxHashMap;
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def::{CtorKind, DefKind};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
@ -326,28 +325,27 @@ pub fn provide(providers: &mut Providers) {
// (restrict scope of mutable-borrow of `visible_parent_map`) // (restrict scope of mutable-borrow of `visible_parent_map`)
{ {
let visible_parent_map = &mut visible_parent_map; let visible_parent_map = &mut visible_parent_map;
let mut add_child = let mut add_child = |bfs_queue: &mut VecDeque<_>, child: &Export, parent: DefId| {
|bfs_queue: &mut VecDeque<_>, child: &Export<hir::HirId>, parent: DefId| { if child.vis != ty::Visibility::Public {
if child.vis != ty::Visibility::Public { return;
return; }
}
if let Some(child) = child.res.opt_def_id() { if let Some(child) = child.res.opt_def_id() {
match visible_parent_map.entry(child) { match visible_parent_map.entry(child) {
Entry::Occupied(mut entry) => { Entry::Occupied(mut entry) => {
// If `child` is defined in crate `cnum`, ensure // If `child` is defined in crate `cnum`, ensure
// that it is mapped to a parent in `cnum`. // that it is mapped to a parent in `cnum`.
if child.is_local() && entry.get().is_local() { if child.is_local() && entry.get().is_local() {
entry.insert(parent);
}
}
Entry::Vacant(entry) => {
entry.insert(parent); entry.insert(parent);
bfs_queue.push_back(child);
} }
} }
Entry::Vacant(entry) => {
entry.insert(parent);
bfs_queue.push_back(child);
}
} }
}; }
};
while let Some(def) = bfs_queue.pop_front() { while let Some(def) = bfs_queue.pop_front() {
for child in tcx.item_children(def).iter() { for child in tcx.item_children(def).iter() {
@ -393,11 +391,7 @@ impl CStore {
self.get_crate_data(def.krate).get_visibility(def.index) self.get_crate_data(def.krate).get_visibility(def.index)
} }
pub fn item_children_untracked( pub fn item_children_untracked(&self, def_id: DefId, sess: &Session) -> Vec<Export> {
&self,
def_id: DefId,
sess: &Session,
) -> Vec<Export<hir::HirId>> {
let mut result = vec![]; let mut result = vec![];
self.get_crate_data(def_id.krate).each_child_of_item( self.get_crate_data(def_id.krate).each_child_of_item(
def_id.index, def_id.index,

View file

@ -1065,14 +1065,7 @@ impl EncodeContext<'a, 'tcx> {
// items - we encode information about proc-macros later on. // items - we encode information about proc-macros later on.
let reexports = if !self.is_proc_macro { let reexports = if !self.is_proc_macro {
match tcx.module_exports(local_def_id) { match tcx.module_exports(local_def_id) {
Some(exports) => { Some(exports) => self.lazy(exports),
let hir = self.tcx.hir();
self.lazy(
exports
.iter()
.map(|export| export.map_id(|id| hir.local_def_id_to_hir_id(id))),
)
}
_ => Lazy::empty(), _ => Lazy::empty(),
} }
} else { } else {

View file

@ -359,7 +359,7 @@ struct RenderedConst(String);
#[derive(MetadataEncodable, MetadataDecodable)] #[derive(MetadataEncodable, MetadataDecodable)]
struct ModData { struct ModData {
reexports: Lazy<[Export<hir::HirId>]>, reexports: Lazy<[Export]>,
expansion: ExpnId, expansion: ExpnId,
} }

View file

@ -11,23 +11,18 @@ use std::fmt::Debug;
/// This is the replacement export map. It maps a module to all of the exports /// This is the replacement export map. It maps a module to all of the exports
/// within. /// within.
pub type ExportMap<Id> = FxHashMap<LocalDefId, Vec<Export<Id>>>; pub type ExportMap = FxHashMap<LocalDefId, Vec<Export>>;
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)] #[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
pub struct Export<Id> { pub struct Export {
/// The name of the target. /// The name of the target.
pub ident: Ident, pub ident: Ident,
/// The resolution of the target. /// The resolution of the target.
pub res: Res<Id>, /// Local variables cannot be exported, so this `Res` doesn't need the ID parameter.
pub res: Res<!>,
/// The span of the target. /// The span of the target.
pub span: Span, pub span: Span,
/// The visibility of the export. /// The visibility of the export.
/// We include non-`pub` exports for hygienic macros that get used from extern crates. /// We include non-`pub` exports for hygienic macros that get used from extern crates.
pub vis: ty::Visibility, pub vis: ty::Visibility,
} }
impl<Id> Export<Id> {
pub fn map_id<R>(self, map: impl FnMut(Id) -> R) -> Export<R> {
Export { ident: self.ident, res: self.res.map_id(map), span: self.span, vis: self.vis }
}
}

View file

@ -1181,7 +1181,7 @@ rustc_queries! {
desc { "traits in scope at a block" } desc { "traits in scope at a block" }
} }
query module_exports(def_id: LocalDefId) -> Option<&'tcx [Export<LocalDefId>]> { query module_exports(def_id: LocalDefId) -> Option<&'tcx [Export]> {
desc { |tcx| "looking up items exported by `{}`", tcx.def_path_str(def_id.to_def_id()) } desc { |tcx| "looking up items exported by `{}`", tcx.def_path_str(def_id.to_def_id()) }
} }
@ -1393,7 +1393,7 @@ rustc_queries! {
eval_always eval_always
desc { "fetching what a crate is named" } desc { "fetching what a crate is named" }
} }
query item_children(def_id: DefId) -> &'tcx [Export<hir::HirId>] { query item_children(def_id: DefId) -> &'tcx [Export] {
desc { |tcx| "collecting child items of `{}`", tcx.def_path_str(def_id) } desc { |tcx| "collecting child items of `{}`", tcx.def_path_str(def_id) }
} }
query extern_mod_stmt_cnum(def_id: LocalDefId) -> Option<CrateNum> { query extern_mod_stmt_cnum(def_id: LocalDefId) -> Option<CrateNum> {

View file

@ -127,7 +127,7 @@ pub struct ResolverOutputs {
pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>, pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
pub maybe_unused_trait_imports: FxHashSet<LocalDefId>, pub maybe_unused_trait_imports: FxHashSet<LocalDefId>,
pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>, pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
pub export_map: ExportMap<LocalDefId>, pub export_map: ExportMap,
pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>, pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
/// Extern prelude entries. The value is `true` if the entry was introduced /// Extern prelude entries. The value is `true` if the entry was introduced
/// via `extern crate` item and not `--extern` option or compiler built-in. /// via `extern crate` item and not `--extern` option or compiler built-in.

View file

@ -228,7 +228,6 @@ impl<'a> Resolver<'a> {
crate fn build_reduced_graph_external(&mut self, module: Module<'a>) { crate fn build_reduced_graph_external(&mut self, module: Module<'a>) {
let def_id = module.def_id().expect("unpopulated module without a def-id"); let def_id = module.def_id().expect("unpopulated module without a def-id");
for child in self.cstore().item_children_untracked(def_id, self.session) { for child in self.cstore().item_children_untracked(def_id, self.session) {
let child = child.map_id(|_| panic!("unexpected id"));
let parent_scope = ParentScope::module(module, self); let parent_scope = ParentScope::module(module, self);
BuildReducedGraphVisitor { r: self, parent_scope } BuildReducedGraphVisitor { r: self, parent_scope }
.build_reduced_graph_for_external_crate_res(child); .build_reduced_graph_for_external_crate_res(child);
@ -946,9 +945,10 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
} }
/// Builds the reduced graph for a single item in an external crate. /// Builds the reduced graph for a single item in an external crate.
fn build_reduced_graph_for_external_crate_res(&mut self, child: Export<NodeId>) { fn build_reduced_graph_for_external_crate_res(&mut self, child: Export) {
let parent = self.parent_scope.module; let parent = self.parent_scope.module;
let Export { ident, res, vis, span } = child; let Export { ident, res, vis, span } = child;
let res = res.expect_non_local();
let expansion = self.parent_scope.expansion; let expansion = self.parent_scope.expansion;
// Record primary definitions. // Record primary definitions.
match res { match res {

View file

@ -11,7 +11,6 @@ use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBindin
use rustc_ast::unwrap_or; use rustc_ast::unwrap_or;
use rustc_ast::NodeId; use rustc_ast::NodeId;
use rustc_ast_lowering::ResolverAstLowering;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::ptr_key::PtrKey; use rustc_data_structures::ptr_key::PtrKey;
use rustc_errors::{pluralize, struct_span_err, Applicability}; use rustc_errors::{pluralize, struct_span_err, Applicability};
@ -1387,13 +1386,13 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
let mut reexports = Vec::new(); let mut reexports = Vec::new();
module.for_each_child(self.r, |this, ident, _, binding| { module.for_each_child(self.r, |_, ident, _, binding| {
// Filter away ambiguous imports and anything that has def-site hygiene. // Filter away ambiguous imports and anything that has def-site hygiene.
// FIXME: Implement actual cross-crate hygiene. // FIXME: Implement actual cross-crate hygiene.
let is_good_import = let is_good_import =
binding.is_import() && !binding.is_ambiguity() && !ident.span.from_expansion(); binding.is_import() && !binding.is_ambiguity() && !ident.span.from_expansion();
if is_good_import || binding.is_macro_def() { if is_good_import || binding.is_macro_def() {
let res = binding.res().map_id(|id| this.local_def_id(id)); let res = binding.res().expect_non_local();
if res != def::Res::Err { if res != def::Res::Err {
reexports.push(Export { ident, res, span: binding.span, vis: binding.vis }); reexports.push(Export { ident, res, span: binding.span, vis: binding.vis });
} }

View file

@ -14,6 +14,7 @@
#![feature(crate_visibility_modifier)] #![feature(crate_visibility_modifier)]
#![feature(format_args_capture)] #![feature(format_args_capture)]
#![feature(iter_zip)] #![feature(iter_zip)]
#![feature(never_type)]
#![feature(nll)] #![feature(nll)]
#![recursion_limit = "256"] #![recursion_limit = "256"]
#![allow(rustdoc::private_intra_doc_links)] #![allow(rustdoc::private_intra_doc_links)]
@ -911,7 +912,7 @@ pub struct Resolver<'a> {
/// `CrateNum` resolutions of `extern crate` items. /// `CrateNum` resolutions of `extern crate` items.
extern_crate_map: FxHashMap<LocalDefId, CrateNum>, extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
export_map: ExportMap<LocalDefId>, export_map: ExportMap,
trait_map: Option<NodeMap<Vec<TraitCandidate>>>, trait_map: Option<NodeMap<Vec<TraitCandidate>>>,
/// A map from nodes to anonymous modules. /// A map from nodes to anonymous modules.

View file

@ -366,6 +366,18 @@ direct_serialize_impls! {
char emit_char read_char char emit_char read_char
} }
impl<S: Encoder> Encodable<S> for ! {
fn encode(&self, _s: &mut S) -> Result<(), S::Error> {
unreachable!()
}
}
impl<D: Decoder> Decodable<D> for ! {
fn decode(_d: &mut D) -> Result<!, D::Error> {
unreachable!()
}
}
impl<S: Encoder> Encodable<S> for ::std::num::NonZeroU32 { impl<S: Encoder> Encodable<S> for ::std::num::NonZeroU32 {
fn encode(&self, s: &mut S) -> Result<(), S::Error> { fn encode(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_u32(self.get()) s.emit_u32(self.get())

View file

@ -1655,7 +1655,7 @@ fn compute_all_traits(tcx: TyCtxt<'_>, (): ()) -> &[DefId] {
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
traits: &mut Vec<DefId>, traits: &mut Vec<DefId>,
external_mods: &mut FxHashSet<DefId>, external_mods: &mut FxHashSet<DefId>,
res: Res, res: Res<!>,
) { ) {
match res { match res {
Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) => { Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) => {

View file

@ -482,12 +482,13 @@ fn build_module(
// visit each node at most once. // visit each node at most once.
for &item in cx.tcx.item_children(did).iter() { for &item in cx.tcx.item_children(did).iter() {
if item.vis == ty::Visibility::Public { if item.vis == ty::Visibility::Public {
if let Some(def_id) = item.res.mod_def_id() { let res = item.res.expect_non_local();
if let Some(def_id) = res.mod_def_id() {
if did == def_id || !visited.insert(def_id) { if did == def_id || !visited.insert(def_id) {
continue; continue;
} }
} }
if let Res::PrimTy(p) = item.res { if let Res::PrimTy(p) = res {
// Primitive types can't be inlined so generate an import instead. // Primitive types can't be inlined so generate an import instead.
let prim_ty = clean::PrimitiveType::from(p); let prim_ty = clean::PrimitiveType::from(p);
items.push(clean::Item { items.push(clean::Item {
@ -500,7 +501,7 @@ fn build_module(
clean::ImportSource { clean::ImportSource {
path: clean::Path { path: clean::Path {
global: false, global: false,
res: item.res, res,
segments: vec![clean::PathSegment { segments: vec![clean::PathSegment {
name: prim_ty.as_sym(), name: prim_ty.as_sym(),
args: clean::GenericArgs::AngleBracketed { args: clean::GenericArgs::AngleBracketed {
@ -515,9 +516,7 @@ fn build_module(
))), ))),
cfg: None, cfg: None,
}); });
} else if let Some(i) = } else if let Some(i) = try_inline(cx, did, None, res, item.ident.name, None, visited) {
try_inline(cx, did, None, item.res, item.ident.name, None, visited)
{
items.extend(i) items.extend(i)
} }
} }

View file

@ -212,7 +212,7 @@ impl ExternalCrate {
crate fn keywords(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, Symbol)> { crate fn keywords(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, Symbol)> {
let root = self.def_id(); let root = self.def_id();
let as_keyword = |res: Res| { let as_keyword = |res: Res<!>| {
if let Res::Def(DefKind::Mod, def_id) = res { if let Res::Def(DefKind::Mod, def_id) = res {
let attrs = tcx.get_attrs(def_id); let attrs = tcx.get_attrs(def_id);
let mut keyword = None; let mut keyword = None;
@ -243,7 +243,8 @@ impl ExternalCrate {
hir::ItemKind::Use(ref path, hir::UseKind::Single) hir::ItemKind::Use(ref path, hir::UseKind::Single)
if item.vis.node.is_pub() => if item.vis.node.is_pub() =>
{ {
as_keyword(path.res).map(|(_, prim)| (id.def_id.to_def_id(), prim)) as_keyword(path.res.expect_non_local())
.map(|(_, prim)| (id.def_id.to_def_id(), prim))
} }
_ => None, _ => None,
} }
@ -274,7 +275,7 @@ impl ExternalCrate {
// Also note that this does not attempt to deal with modules tagged // Also note that this does not attempt to deal with modules tagged
// duplicately for the same primitive. This is handled later on when // duplicately for the same primitive. This is handled later on when
// rendering by delegating everything to a hash map. // rendering by delegating everything to a hash map.
let as_primitive = |res: Res| { let as_primitive = |res: Res<!>| {
if let Res::Def(DefKind::Mod, def_id) = res { if let Res::Def(DefKind::Mod, def_id) = res {
let attrs = tcx.get_attrs(def_id); let attrs = tcx.get_attrs(def_id);
let mut prim = None; let mut prim = None;
@ -309,7 +310,7 @@ impl ExternalCrate {
hir::ItemKind::Use(ref path, hir::UseKind::Single) hir::ItemKind::Use(ref path, hir::UseKind::Single)
if item.vis.node.is_pub() => if item.vis.node.is_pub() =>
{ {
as_primitive(path.res).map(|(_, prim)| { as_primitive(path.res.expect_non_local()).map(|(_, prim)| {
// Pretend the primitive is local. // Pretend the primitive is local.
(id.def_id.to_def_id(), prim) (id.def_id.to_def_id(), prim)
}) })

View file

@ -67,7 +67,7 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
} }
} }
fn visit_item(&mut self, res: Res) { fn visit_item(&mut self, res: Res<!>) {
let def_id = res.def_id(); let def_id = res.def_id();
let vis = self.tcx.visibility(def_id); let vis = self.tcx.visibility(def_id);
let inherited_item_level = if vis == Visibility::Public { self.prev_level } else { None }; let inherited_item_level = if vis == Visibility::Public { self.prev_level } else { None };

View file

@ -520,7 +520,7 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
} }
}; };
} }
fn item_child_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Option<&'tcx Export<HirId>> { fn item_child_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Option<&'tcx Export> {
tcx.item_children(def_id) tcx.item_children(def_id)
.iter() .iter()
.find(|item| item.ident.name.as_str() == name) .find(|item| item.ident.name.as_str() == name)
@ -557,7 +557,7 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
None None
} }
}); });
try_res!(last).res try_res!(last).res.expect_non_local()
} }
/// Convenience function to get the `DefId` of a trait by path. /// Convenience function to get the `DefId` of a trait by path.