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
Show file tree
Hide file tree
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
Expand Up @@ -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)]
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_data_structures/src/stable_hasher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_hir/src/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
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
Expand Up @@ -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};
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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,
Expand Down
9 changes: 1 addition & 8 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ struct RenderedConst(String);

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

Expand Down
13 changes: 4 additions & 9 deletions compiler/rustc_middle/src/hir/exports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Up @@ -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()) }
}

Expand Down Expand Up @@ -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> {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 {
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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 });
}
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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.
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_serialize/src/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
11 changes: 5 additions & 6 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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)
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
})
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/visit_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down
4 changes: 2 additions & 2 deletions src/tools/clippy/clippy_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand Down