Skip to content

rustc: Remove local variable IDs from Exports #88677

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 12, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_data_structures/src/lib.rs
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@
#![feature(iter_map_while)]
#![feature(maybe_uninit_uninit_array)]
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(type_alias_impl_trait)]
#![feature(new_uninit)]
#![feature(nll)]
6 changes: 6 additions & 0 deletions compiler/rustc_data_structures/src/stable_hasher.rs
Original file line number Diff line number Diff line change
@@ -209,6 +209,12 @@ impl_stable_hash_via_hash!(i128);
impl_stable_hash_via_hash!(char);
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 {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
self.get().hash_stable(ctx, hasher)
5 changes: 5 additions & 0 deletions compiler/rustc_hir/src/def.rs
Original file line number Diff line number Diff line change
@@ -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> {
match self {
Res::Def(DefKind::Macro(kind), _) => Some(kind),
5 changes: 1 addition & 4 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
@@ -1019,10 +1019,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
}

/// Iterates over each child of the given item.
fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F, sess: &Session)
where
F: FnMut(Export<hir::HirId>),
{
fn each_child_of_item(&self, id: DefIndex, mut callback: impl FnMut(Export), sess: &Session) {
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
* as a proc macro crate.
40 changes: 17 additions & 23 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
@@ -5,7 +5,6 @@ use crate::rmeta::encoder;

use rustc_ast as ast;
use rustc_data_structures::stable_map::FxHashMap;
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE};
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`)
{
let visible_parent_map = &mut visible_parent_map;
let mut add_child =
|bfs_queue: &mut VecDeque<_>, child: &Export<hir::HirId>, parent: DefId| {
if child.vis != ty::Visibility::Public {
return;
}
let mut add_child = |bfs_queue: &mut VecDeque<_>, child: &Export, parent: DefId| {
if child.vis != ty::Visibility::Public {
return;
}

if let Some(child) = child.res.opt_def_id() {
match visible_parent_map.entry(child) {
Entry::Occupied(mut entry) => {
// If `child` is defined in crate `cnum`, ensure
// that it is mapped to a parent in `cnum`.
if child.is_local() && entry.get().is_local() {
entry.insert(parent);
}
}
Entry::Vacant(entry) => {
if let Some(child) = child.res.opt_def_id() {
match visible_parent_map.entry(child) {
Entry::Occupied(mut entry) => {
// If `child` is defined in crate `cnum`, ensure
// that it is mapped to a parent in `cnum`.
if child.is_local() && entry.get().is_local() {
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() {
for child in tcx.item_children(def).iter() {
@@ -393,11 +391,7 @@ impl CStore {
self.get_crate_data(def.krate).get_visibility(def.index)
}

pub fn item_children_untracked(
&self,
def_id: DefId,
sess: &Session,
) -> Vec<Export<hir::HirId>> {
pub fn item_children_untracked(&self, def_id: DefId, sess: &Session) -> Vec<Export> {
let mut result = vec![];
self.get_crate_data(def_id.krate).each_child_of_item(
def_id.index,
9 changes: 1 addition & 8 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
@@ -1065,14 +1065,7 @@ impl EncodeContext<'a, 'tcx> {
// items - we encode information about proc-macros later on.
let reexports = if !self.is_proc_macro {
match tcx.module_exports(local_def_id) {
Some(exports) => {
let hir = self.tcx.hir();
self.lazy(
exports
.iter()
.map(|export| export.map_id(|id| hir.local_def_id_to_hir_id(id))),
)
}
Some(exports) => self.lazy(exports),
_ => Lazy::empty(),
}
} else {
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
@@ -359,7 +359,7 @@ struct RenderedConst(String);

#[derive(MetadataEncodable, MetadataDecodable)]
struct ModData {
reexports: Lazy<[Export<hir::HirId>]>,
reexports: Lazy<[Export]>,
expansion: ExpnId,
}

13 changes: 4 additions & 9 deletions compiler/rustc_middle/src/hir/exports.rs
Original file line number Diff line number Diff line change
@@ -11,23 +11,18 @@ use std::fmt::Debug;

/// This is the replacement export map. It maps a module to all of the exports
/// within.
pub type ExportMap<Id> = FxHashMap<LocalDefId, Vec<Export<Id>>>;
pub type ExportMap = FxHashMap<LocalDefId, Vec<Export>>;

#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
pub struct Export<Id> {
pub struct Export {
/// The name of the target.
pub ident: Ident,
/// 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.
pub span: Span,
/// The visibility of the export.
/// We include non-`pub` exports for hygienic macros that get used from extern crates.
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 }
}
}
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
@@ -1181,7 +1181,7 @@ rustc_queries! {
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()) }
}

@@ -1393,7 +1393,7 @@ rustc_queries! {
eval_always
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) }
}
query extern_mod_stmt_cnum(def_id: LocalDefId) -> Option<CrateNum> {
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
@@ -127,7 +127,7 @@ pub struct ResolverOutputs {
pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
pub maybe_unused_trait_imports: FxHashSet<LocalDefId>,
pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
pub export_map: ExportMap<LocalDefId>,
pub export_map: ExportMap,
pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
/// Extern prelude entries. The value is `true` if the entry was introduced
/// via `extern crate` item and not `--extern` option or compiler built-in.
4 changes: 2 additions & 2 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
@@ -228,7 +228,6 @@ impl<'a> Resolver<'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");
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);
BuildReducedGraphVisitor { r: self, parent_scope }
.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.
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 Export { ident, res, vis, span } = child;
let res = res.expect_non_local();
let expansion = self.parent_scope.expansion;
// Record primary definitions.
match res {
5 changes: 2 additions & 3 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,6 @@ use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBindin

use rustc_ast::unwrap_or;
use rustc_ast::NodeId;
use rustc_ast_lowering::ResolverAstLowering;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::ptr_key::PtrKey;
use rustc_errors::{pluralize, struct_span_err, Applicability};
@@ -1387,13 +1386,13 @@ impl<'a, 'b> ImportResolver<'a, 'b> {

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.
// FIXME: Implement actual cross-crate hygiene.
let is_good_import =
binding.is_import() && !binding.is_ambiguity() && !ident.span.from_expansion();
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 {
reexports.push(Export { ident, res, span: binding.span, vis: binding.vis });
}
3 changes: 2 additions & 1 deletion compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@
#![feature(crate_visibility_modifier)]
#![feature(format_args_capture)]
#![feature(iter_zip)]
#![feature(never_type)]
#![feature(nll)]
#![recursion_limit = "256"]
#![allow(rustdoc::private_intra_doc_links)]
@@ -911,7 +912,7 @@ pub struct Resolver<'a> {

/// `CrateNum` resolutions of `extern crate` items.
extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
export_map: ExportMap<LocalDefId>,
export_map: ExportMap,
trait_map: Option<NodeMap<Vec<TraitCandidate>>>,

/// A map from nodes to anonymous modules.
12 changes: 12 additions & 0 deletions compiler/rustc_serialize/src/serialize.rs
Original file line number Diff line number Diff line change
@@ -366,6 +366,18 @@ direct_serialize_impls! {
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 {
fn encode(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_u32(self.get())
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/method/suggest.rs
Original file line number Diff line number Diff line change
@@ -1655,7 +1655,7 @@ fn compute_all_traits(tcx: TyCtxt<'_>, (): ()) -> &[DefId] {
tcx: TyCtxt<'_>,
traits: &mut Vec<DefId>,
external_mods: &mut FxHashSet<DefId>,
res: Res,
res: Res<!>,
) {
match res {
Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) => {
11 changes: 5 additions & 6 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
@@ -482,12 +482,13 @@ fn build_module(
// visit each node at most once.
for &item in cx.tcx.item_children(did).iter() {
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) {
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.
let prim_ty = clean::PrimitiveType::from(p);
items.push(clean::Item {
@@ -500,7 +501,7 @@ fn build_module(
clean::ImportSource {
path: clean::Path {
global: false,
res: item.res,
res,
segments: vec![clean::PathSegment {
name: prim_ty.as_sym(),
args: clean::GenericArgs::AngleBracketed {
@@ -515,9 +516,7 @@ fn build_module(
))),
cfg: None,
});
} else if let Some(i) =
try_inline(cx, did, None, item.res, item.ident.name, None, visited)
{
} else if let Some(i) = try_inline(cx, did, None, res, item.ident.name, None, visited) {
items.extend(i)
}
}
9 changes: 5 additions & 4 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
@@ -212,7 +212,7 @@ impl ExternalCrate {
crate fn keywords(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, Symbol)> {
let root = self.def_id();

let as_keyword = |res: Res| {
let as_keyword = |res: Res<!>| {
if let Res::Def(DefKind::Mod, def_id) = res {
let attrs = tcx.get_attrs(def_id);
let mut keyword = None;
@@ -243,7 +243,8 @@ impl ExternalCrate {
hir::ItemKind::Use(ref path, hir::UseKind::Single)
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,
}
@@ -274,7 +275,7 @@ impl ExternalCrate {
// Also note that this does not attempt to deal with modules tagged
// duplicately for the same primitive. This is handled later on when
// 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 {
let attrs = tcx.get_attrs(def_id);
let mut prim = None;
@@ -309,7 +310,7 @@ impl ExternalCrate {
hir::ItemKind::Use(ref path, hir::UseKind::Single)
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.
(id.def_id.to_def_id(), prim)
})
2 changes: 1 addition & 1 deletion src/librustdoc/visit_lib.rs
Original file line number Diff line number Diff line change
@@ -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 vis = self.tcx.visibility(def_id);
let inherited_item_level = if vis == Visibility::Public { self.prev_level } else { None };
4 changes: 2 additions & 2 deletions src/tools/clippy/clippy_utils/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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)
.iter()
.find(|item| item.ident.name.as_str() == name)
@@ -557,7 +557,7 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
None
}
});
try_res!(last).res
try_res!(last).res.expect_non_local()
}

/// Convenience function to get the `DefId` of a trait by path.