use rustc_errors::json::JsonEmitter;
use rustc_feature::UnstableFeatures;
use rustc_hir::def::Res;
-use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE};
+use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
use rustc_hir::HirId;
use rustc_hir::{
intravisit::{self, NestedVisitorMap, Visitor},
use rustc_span::Span;
use std::cell::RefCell;
-use std::collections::hash_map::Entry;
use std::mem;
use std::rc::Rc;
-use crate::clean;
use crate::clean::inline::build_external_trait;
-use crate::clean::{TraitWithExtraInfo, MAX_DEF_IDX};
+use crate::clean::{self, FakeDefId, TraitWithExtraInfo};
use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions};
use crate::formats::cache::Cache;
use crate::passes::{self, Condition::*, ConditionalPass};
crate ct_substs: FxHashMap<DefId, clean::Constant>,
/// Table synthetic type parameter for `impl Trait` in argument position -> bounds
crate impl_trait_bounds: FxHashMap<ImplTraitParam, Vec<clean::GenericBound>>,
- crate fake_def_ids: FxHashMap<CrateNum, DefIndex>,
/// Auto-trait or blanket impls processed so far, as `(self_ty, trait_def_id)`.
// FIXME(eddyb) make this a `ty::TraitRef<'tcx>` set.
crate generated_synthetics: FxHashSet<(Ty<'tcx>, DefId)>,
/// This same cache is used throughout rustdoc, including in [`crate::html::render`].
crate cache: Cache,
/// Used by [`clean::inline`] to tell if an item has already been inlined.
- crate inlined: FxHashSet<DefId>,
+ crate inlined: FxHashSet<FakeDefId>,
/// Used by `calculate_doc_coverage`.
crate output_format: OutputFormat,
}
r
}
- /// Create a new "fake" [`DefId`].
- ///
- /// This is an ugly hack, but it's the simplest way to handle synthetic impls without greatly
- /// refactoring either rustdoc or [`rustc_middle`]. In particular, allowing new [`DefId`]s
- /// to be registered after the AST is constructed would require storing the [`DefId`] mapping
- /// in a [`RefCell`], decreasing the performance for normal compilation for very little gain.
- ///
- /// Instead, we construct "fake" [`DefId`]s, which start immediately after the last `DefId`.
- /// In the [`Debug`] impl for [`clean::Item`], we explicitly check for fake `DefId`s,
- /// as we'll end up with a panic if we use the `DefId` `Debug` impl for fake `DefId`s.
- ///
- /// [`RefCell`]: std::cell::RefCell
- /// [`Debug`]: std::fmt::Debug
- /// [`clean::Item`]: crate::clean::types::Item
- crate fn next_def_id(&mut self, crate_num: CrateNum) -> DefId {
- let def_index = match self.fake_def_ids.entry(crate_num) {
- Entry::Vacant(e) => {
- let num_def_idx = {
- let num_def_idx = if crate_num == LOCAL_CRATE {
- self.tcx.hir().definitions().def_path_table().num_def_ids()
- } else {
- self.resolver.borrow_mut().access(|r| r.cstore().num_def_ids(crate_num))
- };
-
- DefIndex::from_usize(num_def_idx)
- };
-
- MAX_DEF_IDX.with(|m| {
- m.borrow_mut().insert(crate_num, num_def_idx);
- });
- e.insert(num_def_idx)
- }
- Entry::Occupied(e) => e.into_mut(),
- };
- *def_index = *def_index + 1;
-
- DefId { krate: crate_num, index: *def_index }
- }
-
/// Like `hir().local_def_id_to_hir_id()`, but skips calling it on fake DefIds.
/// (This avoids a slice-index-out-of-bounds panic.)
- crate fn as_local_hir_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option<HirId> {
- if MAX_DEF_IDX.with(|m| {
- m.borrow().get(&def_id.krate).map(|&idx| idx <= def_id.index).unwrap_or(false)
- }) {
- None
- } else {
- def_id.as_local().map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id))
+ crate fn as_local_hir_id(tcx: TyCtxt<'_>, def_id: FakeDefId) -> Option<HirId> {
+ match def_id {
+ FakeDefId::Real(real_id) => {
+ real_id.as_local().map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id))
+ }
+ FakeDefId::Fake(_, _) => None,
}
}
}
lints_to_show.extend(crate::lint::RUSTDOC_LINTS.iter().map(|lint| lint.name.to_string()));
let (lint_opts, lint_caps) = crate::lint::init_lints(lints_to_show, lint_opts, |lint| {
- // FIXME: why is this necessary?
- if lint.name == crate::lint::BROKEN_INTRA_DOC_LINKS.name
- || lint.name == crate::lint::INVALID_CODEBLOCK_ATTRIBUTES.name
- {
- None
- } else {
- Some((lint.name_lower(), lint::Allow))
- }
+ Some((lint.name_lower(), lint::Allow))
});
let crate_types =
});
rustc_passes::stability::check_unused_or_stable_features(tcx);
- let access_levels = tcx.privacy_access_levels(LOCAL_CRATE);
+ let access_levels = tcx.privacy_access_levels(());
// Convert from a HirId set to a DefId set since we don't always have easy access
// to the map from defid -> hirid
let access_levels = AccessLevels {
lt_substs: Default::default(),
ct_substs: Default::default(),
impl_trait_bounds: Default::default(),
- fake_def_ids: Default::default(),
generated_synthetics: Default::default(),
auto_traits: tcx
.all_traits(LOCAL_CRATE)
let mut krate = tcx.sess.time("clean_crate", || clean::krate(&mut ctxt));
if krate.module.doc_value().map(|d| d.is_empty()).unwrap_or(true) {
- let help = format!(
- "The following guide may be of use:\n\
- https://doc.rust-lang.org/{}/rustdoc/how-to-write-documentation.html",
- crate::doc_rust_lang_org_channel(),
- );
+ let help = "The following guide may be of use:\n\
+ https://doc.rust-lang.org/nightly/rustdoc/how-to-write-documentation.html";
tcx.struct_lint_node(
crate::lint::MISSING_CRATE_LEVEL_DOCS,
DocContext::as_local_hir_id(tcx, krate.module.def_id).unwrap(),
|lint| {
let mut diag =
lint.build("no documentation found for this crate's top-level module");
- diag.help(&help);
+ diag.help(help);
diag.emit();
},
);
/// for `impl Trait` in argument position.
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
crate enum ImplTraitParam {
- DefId(DefId),
+ DefId(FakeDefId),
ParamIndex(u32),
}
-impl From<DefId> for ImplTraitParam {
- fn from(did: DefId) -> Self {
+impl From<FakeDefId> for ImplTraitParam {
+ fn from(did: FakeDefId) -> Self {
ImplTraitParam::DefId(did)
}
}