Auto merge of #82688 - GuillaumeGomez:rollup-b754t11, r=GuillaumeGomez
Rollup of 7 pull requests Successful merges: - #80734 (check that first arg to `panic!()` in const is `&str`) - #81932 (Always compile rustdoc with debug logging enabled when `download-rustc` is set) - #82018 (Remove the dummy cache in `DocContext`; delete RenderInfo) - #82598 (Check stability and feature attributes in rustdoc) - #82655 (Highlight identifier span instead of whole pattern span in `unused` lint) - #82662 (Warn about unknown doc attributes) - #82676 (Change twice used large const table to static) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
ef0d5924c2
@ -4554,6 +4554,9 @@ dependencies = [
|
||||
"serde_json",
|
||||
"smallvec 1.6.1",
|
||||
"tempfile",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"tracing-tree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -377,6 +377,18 @@ impl NonConstOp for Panic {
|
||||
}
|
||||
}
|
||||
|
||||
/// A call to a `panic()` lang item where the first argument is _not_ a `&str`.
|
||||
#[derive(Debug)]
|
||||
pub struct PanicNonStr;
|
||||
impl NonConstOp for PanicNonStr {
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
ccx.tcx.sess.struct_span_err(
|
||||
span,
|
||||
"argument to `panic!()` in a const context must have type `&str`",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RawPtrComparison;
|
||||
impl NonConstOp for RawPtrComparison {
|
||||
|
@ -819,7 +819,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
|
||||
self.super_terminator(terminator, location);
|
||||
|
||||
match &terminator.kind {
|
||||
TerminatorKind::Call { func, .. } => {
|
||||
TerminatorKind::Call { func, args, .. } => {
|
||||
let ConstCx { tcx, body, param_env, .. } = *self.ccx;
|
||||
let caller = self.def_id().to_def_id();
|
||||
|
||||
@ -881,9 +881,17 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
|
||||
}
|
||||
|
||||
// At this point, we are calling a function, `callee`, whose `DefId` is known...
|
||||
|
||||
if is_lang_panic_fn(tcx, callee) {
|
||||
self.check_op(ops::Panic);
|
||||
|
||||
// const-eval of the `begin_panic` fn assumes the argument is `&str`
|
||||
if Some(callee) == tcx.lang_items().begin_panic_fn() {
|
||||
match args[0].ty(&self.ccx.body.local_decls, tcx).kind() {
|
||||
ty::Ref(_, ty, _) if ty.is_str() => (),
|
||||
_ => self.check_op(ops::PanicNonStr),
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -544,6 +544,41 @@ impl CheckAttrVisitor<'tcx> {
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} else if let Some(i_meta) = meta.meta_item() {
|
||||
if ![
|
||||
sym::cfg,
|
||||
sym::hidden,
|
||||
sym::html_favicon_url,
|
||||
sym::html_logo_url,
|
||||
sym::html_no_source,
|
||||
sym::html_playground_url,
|
||||
sym::html_root_url,
|
||||
sym::include,
|
||||
sym::inline,
|
||||
sym::issue_tracker_base_url,
|
||||
sym::masked,
|
||||
sym::no_default_passes, // deprecated
|
||||
sym::no_inline,
|
||||
sym::passes, // deprecated
|
||||
sym::primitive,
|
||||
sym::spotlight,
|
||||
sym::test,
|
||||
]
|
||||
.iter()
|
||||
.any(|m| i_meta.has_name(*m))
|
||||
{
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(
|
||||
meta.span(),
|
||||
&format!(
|
||||
"unknown `doc` attribute `{}`",
|
||||
i_meta.name_or_empty(),
|
||||
),
|
||||
)
|
||||
.emit();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1494,12 +1494,13 @@ impl<'tcx> Liveness<'_, 'tcx> {
|
||||
// bindings, and we also consider the first pattern to be the "authoritative" set of ids.
|
||||
// However, we should take the ids and spans of variables with the same name from the later
|
||||
// patterns so the suggestions to prefix with underscores will apply to those too.
|
||||
let mut vars: FxIndexMap<Symbol, (LiveNode, Variable, Vec<(HirId, Span)>)> = <_>::default();
|
||||
let mut vars: FxIndexMap<Symbol, (LiveNode, Variable, Vec<(HirId, Span, Span)>)> =
|
||||
<_>::default();
|
||||
|
||||
pat.each_binding(|_, hir_id, pat_sp, ident| {
|
||||
let ln = entry_ln.unwrap_or_else(|| self.live_node(hir_id, pat_sp));
|
||||
let var = self.variable(hir_id, ident.span);
|
||||
let id_and_sp = (hir_id, pat_sp);
|
||||
let id_and_sp = (hir_id, pat_sp, ident.span);
|
||||
vars.entry(self.ir.variable_name(var))
|
||||
.and_modify(|(.., hir_ids_and_spans)| hir_ids_and_spans.push(id_and_sp))
|
||||
.or_insert_with(|| (ln, var, vec![id_and_sp]));
|
||||
@ -1508,7 +1509,8 @@ impl<'tcx> Liveness<'_, 'tcx> {
|
||||
for (_, (ln, var, hir_ids_and_spans)) in vars {
|
||||
if self.used_on_entry(ln, var) {
|
||||
let id = hir_ids_and_spans[0].0;
|
||||
let spans = hir_ids_and_spans.into_iter().map(|(_, sp)| sp).collect();
|
||||
let spans =
|
||||
hir_ids_and_spans.into_iter().map(|(_, _, ident_span)| ident_span).collect();
|
||||
on_used_on_entry(spans, id, ln, var);
|
||||
} else {
|
||||
self.report_unused(hir_ids_and_spans, ln, var);
|
||||
@ -1516,7 +1518,12 @@ impl<'tcx> Liveness<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn report_unused(&self, hir_ids_and_spans: Vec<(HirId, Span)>, ln: LiveNode, var: Variable) {
|
||||
fn report_unused(
|
||||
&self,
|
||||
hir_ids_and_spans: Vec<(HirId, Span, Span)>,
|
||||
ln: LiveNode,
|
||||
var: Variable,
|
||||
) {
|
||||
let first_hir_id = hir_ids_and_spans[0].0;
|
||||
|
||||
if let Some(name) = self.should_warn(var).filter(|name| name != "self") {
|
||||
@ -1530,7 +1537,10 @@ impl<'tcx> Liveness<'_, 'tcx> {
|
||||
self.ir.tcx.struct_span_lint_hir(
|
||||
lint::builtin::UNUSED_VARIABLES,
|
||||
first_hir_id,
|
||||
hir_ids_and_spans.into_iter().map(|(_, sp)| sp).collect::<Vec<_>>(),
|
||||
hir_ids_and_spans
|
||||
.into_iter()
|
||||
.map(|(_, _, ident_span)| ident_span)
|
||||
.collect::<Vec<_>>(),
|
||||
|lint| {
|
||||
lint.build(&format!("variable `{}` is assigned to, but never used", name))
|
||||
.note(&format!("consider using `_{}` instead", name))
|
||||
@ -1538,54 +1548,67 @@ impl<'tcx> Liveness<'_, 'tcx> {
|
||||
},
|
||||
)
|
||||
} else {
|
||||
self.ir.tcx.struct_span_lint_hir(
|
||||
lint::builtin::UNUSED_VARIABLES,
|
||||
first_hir_id,
|
||||
hir_ids_and_spans.iter().map(|(_, sp)| *sp).collect::<Vec<_>>(),
|
||||
|lint| {
|
||||
let mut err = lint.build(&format!("unused variable: `{}`", name));
|
||||
let (shorthands, non_shorthands): (Vec<_>, Vec<_>) =
|
||||
hir_ids_and_spans.iter().copied().partition(|(hir_id, _, ident_span)| {
|
||||
let var = self.variable(*hir_id, *ident_span);
|
||||
self.ir.variable_is_shorthand(var)
|
||||
});
|
||||
|
||||
let (shorthands, non_shorthands): (Vec<_>, Vec<_>) =
|
||||
hir_ids_and_spans.into_iter().partition(|(hir_id, span)| {
|
||||
let var = self.variable(*hir_id, *span);
|
||||
self.ir.variable_is_shorthand(var)
|
||||
});
|
||||
|
||||
let mut shorthands = shorthands
|
||||
.into_iter()
|
||||
.map(|(_, span)| (span, format!("{}: _", name)))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// If we have both shorthand and non-shorthand, prefer the "try ignoring
|
||||
// the field" message, and suggest `_` for the non-shorthands. If we only
|
||||
// have non-shorthand, then prefix with an underscore instead.
|
||||
if !shorthands.is_empty() {
|
||||
shorthands.extend(
|
||||
non_shorthands
|
||||
.into_iter()
|
||||
.map(|(_, span)| (span, "_".to_string()))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
// If we have both shorthand and non-shorthand, prefer the "try ignoring
|
||||
// the field" message, and suggest `_` for the non-shorthands. If we only
|
||||
// have non-shorthand, then prefix with an underscore instead.
|
||||
if !shorthands.is_empty() {
|
||||
let shorthands = shorthands
|
||||
.into_iter()
|
||||
.map(|(_, pat_span, _)| (pat_span, format!("{}: _", name)))
|
||||
.chain(
|
||||
non_shorthands
|
||||
.into_iter()
|
||||
.map(|(_, pat_span, _)| (pat_span, "_".to_string())),
|
||||
)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
self.ir.tcx.struct_span_lint_hir(
|
||||
lint::builtin::UNUSED_VARIABLES,
|
||||
first_hir_id,
|
||||
hir_ids_and_spans
|
||||
.iter()
|
||||
.map(|(_, pat_span, _)| *pat_span)
|
||||
.collect::<Vec<_>>(),
|
||||
|lint| {
|
||||
let mut err = lint.build(&format!("unused variable: `{}`", name));
|
||||
err.multipart_suggestion(
|
||||
"try ignoring the field",
|
||||
shorthands,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
err.emit()
|
||||
},
|
||||
);
|
||||
} else {
|
||||
let non_shorthands = non_shorthands
|
||||
.into_iter()
|
||||
.map(|(_, _, ident_span)| (ident_span, format!("_{}", name)))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
self.ir.tcx.struct_span_lint_hir(
|
||||
lint::builtin::UNUSED_VARIABLES,
|
||||
first_hir_id,
|
||||
hir_ids_and_spans
|
||||
.iter()
|
||||
.map(|(_, _, ident_span)| *ident_span)
|
||||
.collect::<Vec<_>>(),
|
||||
|lint| {
|
||||
let mut err = lint.build(&format!("unused variable: `{}`", name));
|
||||
err.multipart_suggestion(
|
||||
"if this is intentional, prefix it with an underscore",
|
||||
non_shorthands
|
||||
.into_iter()
|
||||
.map(|(_, span)| (span, format!("_{}", name)))
|
||||
.collect::<Vec<_>>(),
|
||||
non_shorthands,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
|
||||
err.emit()
|
||||
},
|
||||
);
|
||||
err.emit()
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ pub const MIN_E: i16 = -305;
|
||||
pub const MAX_E: i16 = 305;
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub const POWERS: ([u64; 611], [i16; 611]) = (
|
||||
pub static POWERS: ([u64; 611], [i16; 611]) = (
|
||||
[
|
||||
0xe0b62e2929aba83c,
|
||||
0x8c71dcd9ba0b4926,
|
||||
|
@ -23,6 +23,7 @@ pub use crate::sys::windows_ext as windows;
|
||||
pub mod linux;
|
||||
|
||||
#[cfg(doc)]
|
||||
#[stable(feature = "wasi_ext_doc", since = "1.35.0")]
|
||||
pub use crate::sys::wasi_ext as wasi;
|
||||
|
||||
// If we're not documenting libstd then we just expose the main modules as we otherwise would.
|
||||
|
@ -111,7 +111,7 @@ cfg_if::cfg_if! {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_os = "wasi")] {
|
||||
// On WASI we'll document what's already available
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[stable(feature = "wasi_ext_doc", since = "1.35.0")]
|
||||
pub use self::ext as wasi_ext;
|
||||
} else if #[cfg(any(target_os = "hermit",
|
||||
target_arch = "wasm32",
|
||||
@ -125,6 +125,7 @@ cfg_if::cfg_if! {
|
||||
} else {
|
||||
// On other platforms like Windows document the bare bones of WASI
|
||||
#[path = "wasi/ext/mod.rs"]
|
||||
#[stable(feature = "wasi_ext_doc", since = "1.35.0")]
|
||||
pub mod wasi_ext;
|
||||
}
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ def print_proper_powers():
|
||||
print()
|
||||
print("#[rustfmt::skip]")
|
||||
typ = "([u64; {0}], [i16; {0}])".format(len(powers))
|
||||
print("pub const POWERS: ", typ, " = (", sep='')
|
||||
print("pub static POWERS: ", typ, " = (", sep='')
|
||||
print(" [")
|
||||
for z in powers:
|
||||
print(" 0x{:x},".format(z.sig))
|
||||
|
@ -19,6 +19,13 @@ tempfile = "3"
|
||||
itertools = "0.9"
|
||||
regex = "1"
|
||||
rustdoc-json-types = { path = "../rustdoc-json-types" }
|
||||
tracing = "0.1"
|
||||
tracing-tree = "0.1.6"
|
||||
|
||||
[dependencies.tracing-subscriber]
|
||||
version = "0.2.13"
|
||||
default-features = false
|
||||
features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"]
|
||||
|
||||
[dev-dependencies]
|
||||
expect-test = "1.0"
|
||||
|
@ -21,7 +21,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
|
||||
debug!("get_blanket_impls({:?})", ty);
|
||||
let mut impls = Vec::new();
|
||||
for &trait_def_id in self.cx.tcx.all_traits(LOCAL_CRATE).iter() {
|
||||
if !self.cx.renderinfo.access_levels.is_public(trait_def_id)
|
||||
if !self.cx.cache.access_levels.is_public(trait_def_id)
|
||||
|| self.cx.generated_synthetics.get(&(ty, trait_def_id)).is_some()
|
||||
{
|
||||
continue;
|
||||
|
@ -17,6 +17,7 @@ use rustc_span::Span;
|
||||
|
||||
use crate::clean::{self, Attributes, GetDefId, ToSource, TypeKind};
|
||||
use crate::core::DocContext;
|
||||
use crate::formats::item_type::ItemType;
|
||||
|
||||
use super::Clean;
|
||||
|
||||
@ -122,7 +123,7 @@ crate fn try_inline(
|
||||
let target_attrs = load_attrs(cx, did);
|
||||
let attrs = box merge_attrs(cx, Some(parent_module), target_attrs, attrs_clone);
|
||||
|
||||
cx.renderinfo.inlined.insert(did);
|
||||
cx.inlined.insert(did);
|
||||
let what_rustc_thinks = clean::Item::from_def_id_and_parts(did, Some(name), kind, cx);
|
||||
ret.push(clean::Item { attrs, ..what_rustc_thinks });
|
||||
Some(ret)
|
||||
@ -181,9 +182,9 @@ crate fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: clean::Typ
|
||||
};
|
||||
|
||||
if did.is_local() {
|
||||
cx.renderinfo.exact_paths.insert(did, fqn);
|
||||
cx.cache.exact_paths.insert(did, fqn);
|
||||
} else {
|
||||
cx.renderinfo.external_paths.insert(did, (fqn, kind));
|
||||
cx.cache.external_paths.insert(did, (fqn, ItemType::from(kind)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -315,7 +316,7 @@ crate fn build_impl(
|
||||
attrs: Option<Attrs<'_>>,
|
||||
ret: &mut Vec<clean::Item>,
|
||||
) {
|
||||
if !cx.renderinfo.inlined.insert(did) {
|
||||
if !cx.inlined.insert(did) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -327,7 +328,7 @@ crate fn build_impl(
|
||||
if !did.is_local() {
|
||||
if let Some(traitref) = associated_trait {
|
||||
let did = traitref.def_id;
|
||||
if !cx.renderinfo.access_levels.is_public(did) {
|
||||
if !cx.cache.access_levels.is_public(did) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -359,7 +360,7 @@ crate fn build_impl(
|
||||
// reachable in rustdoc generated documentation
|
||||
if !did.is_local() {
|
||||
if let Some(did) = for_.def_id() {
|
||||
if !cx.renderinfo.access_levels.is_public(did) {
|
||||
if !cx.cache.access_levels.is_public(did) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1304,7 +1304,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
|
||||
// Substitute private type aliases
|
||||
if let Some(def_id) = def_id.as_local() {
|
||||
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id);
|
||||
if !cx.renderinfo.access_levels.is_exported(def_id.to_def_id()) {
|
||||
if !cx.cache.access_levels.is_exported(def_id.to_def_id()) {
|
||||
alias = Some(&cx.tcx.hir().expect_item(hir_id).kind);
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,6 @@ thread_local!(crate static MAX_DEF_IDX: RefCell<FxHashMap<CrateNum, DefIndex>> =
|
||||
#[derive(Clone, Debug)]
|
||||
crate struct Crate {
|
||||
crate name: Symbol,
|
||||
crate version: Option<String>,
|
||||
crate src: FileName,
|
||||
crate module: Option<Item>,
|
||||
crate externs: Vec<(CrateNum, ExternalCrate)>,
|
||||
|
@ -17,21 +17,21 @@ use rustc_middle::ty::{self, DefIdTree, TyCtxt};
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use std::mem;
|
||||
|
||||
crate fn krate(mut cx: &mut DocContext<'_>) -> Crate {
|
||||
crate fn krate(cx: &mut DocContext<'_>) -> Crate {
|
||||
use crate::visit_lib::LibEmbargoVisitor;
|
||||
|
||||
let krate = cx.tcx.hir().krate();
|
||||
let module = crate::visit_ast::RustdocVisitor::new(&mut cx).visit(krate);
|
||||
let module = crate::visit_ast::RustdocVisitor::new(cx).visit(krate);
|
||||
|
||||
cx.renderinfo.deref_trait_did = cx.tcx.lang_items().deref_trait();
|
||||
cx.renderinfo.deref_mut_trait_did = cx.tcx.lang_items().deref_mut_trait();
|
||||
cx.renderinfo.owned_box_did = cx.tcx.lang_items().owned_box();
|
||||
cx.cache.deref_trait_did = cx.tcx.lang_items().deref_trait();
|
||||
cx.cache.deref_mut_trait_did = cx.tcx.lang_items().deref_mut_trait();
|
||||
cx.cache.owned_box_did = cx.tcx.lang_items().owned_box();
|
||||
|
||||
let mut externs = Vec::new();
|
||||
for &cnum in cx.tcx.crates().iter() {
|
||||
externs.push((cnum, cnum.clean(cx)));
|
||||
// Analyze doc-reachability for extern items
|
||||
LibEmbargoVisitor::new(&mut cx).visit_lib(cnum);
|
||||
LibEmbargoVisitor::new(cx).visit_lib(cnum);
|
||||
}
|
||||
externs.sort_by(|&(a, _), &(b, _)| a.cmp(&b));
|
||||
|
||||
@ -77,7 +77,6 @@ crate fn krate(mut cx: &mut DocContext<'_>) -> Crate {
|
||||
|
||||
Crate {
|
||||
name,
|
||||
version: None,
|
||||
src,
|
||||
module: Some(module),
|
||||
externs,
|
||||
|
@ -4,9 +4,7 @@ use std::ffi::OsStr;
|
||||
use std::fmt;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::middle::privacy::AccessLevels;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_session::config::{self, parse_crate_types_from_list, parse_externs, CrateType};
|
||||
use rustc_session::config::{
|
||||
build_codegen_options, build_debugging_options, get_cmd_lint_options, host_triple,
|
||||
@ -268,20 +266,6 @@ crate struct RenderOptions {
|
||||
crate unstable_features: rustc_feature::UnstableFeatures,
|
||||
}
|
||||
|
||||
/// Temporary storage for data obtained during `RustdocVisitor::clean()`.
|
||||
/// Later on moved into `cache`.
|
||||
#[derive(Default, Clone)]
|
||||
crate struct RenderInfo {
|
||||
crate inlined: FxHashSet<DefId>,
|
||||
crate external_paths: crate::core::ExternalPaths,
|
||||
crate exact_paths: FxHashMap<DefId, Vec<String>>,
|
||||
crate access_levels: AccessLevels<DefId>,
|
||||
crate deref_trait_did: Option<DefId>,
|
||||
crate deref_mut_trait_did: Option<DefId>,
|
||||
crate owned_box_did: Option<DefId>,
|
||||
crate output_format: OutputFormat,
|
||||
}
|
||||
|
||||
impl Options {
|
||||
/// Parses the given command-line for options. If an error message or other early-return has
|
||||
/// been printed, returns `Err` with the exit code.
|
||||
|
@ -31,15 +31,12 @@ use std::{cell::RefCell, collections::hash_map::Entry};
|
||||
use crate::clean;
|
||||
use crate::clean::inline::build_external_trait;
|
||||
use crate::clean::{AttributesExt, TraitWithExtraInfo, MAX_DEF_IDX};
|
||||
use crate::config::{Options as RustdocOptions, RenderOptions};
|
||||
use crate::config::{OutputFormat, RenderInfo};
|
||||
use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions};
|
||||
use crate::formats::cache::Cache;
|
||||
use crate::passes::{self, Condition::*, ConditionalPass};
|
||||
|
||||
crate use rustc_session::config::{DebuggingOptions, Input, Options};
|
||||
|
||||
crate type ExternalPaths = FxHashMap<DefId, (Vec<String>, clean::TypeKind)>;
|
||||
|
||||
crate struct DocContext<'tcx> {
|
||||
crate tcx: TyCtxt<'tcx>,
|
||||
/// Name resolver. Used for intra-doc links.
|
||||
@ -52,8 +49,6 @@ crate struct DocContext<'tcx> {
|
||||
///
|
||||
/// Most of this logic is copied from rustc_lint::late.
|
||||
crate param_env: ParamEnv<'tcx>,
|
||||
/// Later on moved into `cache`
|
||||
crate renderinfo: RenderInfo,
|
||||
/// Later on moved through `clean::Crate` into `cache`
|
||||
crate external_traits: Rc<RefCell<FxHashMap<DefId, clean::TraitWithExtraInfo>>>,
|
||||
/// Used while populating `external_traits` to ensure we don't process the same trait twice at
|
||||
@ -81,8 +76,12 @@ crate struct DocContext<'tcx> {
|
||||
/// See `collect_intra_doc_links::traits_implemented_by` for more details.
|
||||
/// `map<module, set<trait>>`
|
||||
crate module_trait_cache: RefCell<FxHashMap<DefId, FxHashSet<DefId>>>,
|
||||
/// Fake empty cache used when cache is required as parameter.
|
||||
/// 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>,
|
||||
/// Used by `calculate_doc_coverage`.
|
||||
crate output_format: OutputFormat,
|
||||
}
|
||||
|
||||
impl<'tcx> DocContext<'tcx> {
|
||||
@ -465,7 +464,7 @@ crate fn run_global_ctxt(
|
||||
mut manual_passes: Vec<String>,
|
||||
render_options: RenderOptions,
|
||||
output_format: OutputFormat,
|
||||
) -> (clean::Crate, RenderInfo, RenderOptions) {
|
||||
) -> (clean::Crate, RenderOptions, Cache) {
|
||||
// Certain queries assume that some checks were run elsewhere
|
||||
// (see https://github.com/rust-lang/rust/pull/73566#issuecomment-656954425),
|
||||
// so type-check everything other than function bodies in this crate before running lints.
|
||||
@ -492,6 +491,7 @@ crate fn run_global_ctxt(
|
||||
tcx.ensure().check_mod_attrs(module);
|
||||
}
|
||||
});
|
||||
rustc_passes::stability::check_unused_or_stable_features(tcx);
|
||||
|
||||
let access_levels = tcx.privacy_access_levels(LOCAL_CRATE);
|
||||
// Convert from a HirId set to a DefId set since we don't always have easy access
|
||||
@ -504,17 +504,12 @@ crate fn run_global_ctxt(
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let mut renderinfo = RenderInfo::default();
|
||||
renderinfo.access_levels = access_levels;
|
||||
renderinfo.output_format = output_format;
|
||||
|
||||
let mut ctxt = DocContext {
|
||||
tcx,
|
||||
resolver,
|
||||
param_env: ParamEnv::empty(),
|
||||
external_traits: Default::default(),
|
||||
active_extern_traits: Default::default(),
|
||||
renderinfo,
|
||||
ty_substs: Default::default(),
|
||||
lt_substs: Default::default(),
|
||||
ct_substs: Default::default(),
|
||||
@ -527,9 +522,11 @@ crate fn run_global_ctxt(
|
||||
.cloned()
|
||||
.filter(|trait_def_id| tcx.trait_is_auto(*trait_def_id))
|
||||
.collect(),
|
||||
render_options,
|
||||
module_trait_cache: RefCell::new(FxHashMap::default()),
|
||||
cache: Cache::default(),
|
||||
cache: Cache::new(access_levels, render_options.document_private),
|
||||
inlined: FxHashSet::default(),
|
||||
output_format,
|
||||
render_options,
|
||||
};
|
||||
|
||||
// Small hack to force the Sized trait to be present.
|
||||
@ -647,10 +644,16 @@ crate fn run_global_ctxt(
|
||||
|
||||
ctxt.sess().abort_if_errors();
|
||||
|
||||
let render_options = ctxt.render_options;
|
||||
let mut cache = ctxt.cache;
|
||||
krate = tcx.sess.time("create_format_cache", || {
|
||||
cache.populate(krate, tcx, &render_options.extern_html_root_urls, &render_options.output)
|
||||
});
|
||||
|
||||
// The main crate doc comments are always collapsed.
|
||||
krate.collapsed = true;
|
||||
|
||||
(krate, ctxt.renderinfo, ctxt.render_options)
|
||||
(krate, render_options, cache)
|
||||
}
|
||||
|
||||
/// Due to <https://github.com/rust-lang/rust/pull/73566>,
|
||||
|
@ -11,7 +11,6 @@ use rustc_span::symbol::sym;
|
||||
use rustc_span::Symbol;
|
||||
|
||||
use crate::clean::{self, GetDefId};
|
||||
use crate::config::RenderInfo;
|
||||
use crate::fold::DocFolder;
|
||||
use crate::formats::item_type::ItemType;
|
||||
use crate::formats::Impl;
|
||||
@ -131,44 +130,23 @@ struct CacheBuilder<'a, 'tcx> {
|
||||
}
|
||||
|
||||
impl Cache {
|
||||
crate fn from_krate<'tcx>(
|
||||
render_info: RenderInfo,
|
||||
document_private: bool,
|
||||
crate fn new(access_levels: AccessLevels<DefId>, document_private: bool) -> Self {
|
||||
Cache { access_levels, document_private, ..Cache::default() }
|
||||
}
|
||||
|
||||
/// Populates the `Cache` with more data. The returned `Crate` will be missing some data that was
|
||||
/// in `krate` due to the data being moved into the `Cache`.
|
||||
crate fn populate(
|
||||
&mut self,
|
||||
mut krate: clean::Crate,
|
||||
tcx: TyCtxt<'_>,
|
||||
extern_html_root_urls: &BTreeMap<String, String>,
|
||||
dst: &Path,
|
||||
mut krate: clean::Crate,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> (clean::Crate, Cache) {
|
||||
) -> clean::Crate {
|
||||
// Crawl the crate to build various caches used for the output
|
||||
let RenderInfo {
|
||||
inlined: _,
|
||||
external_paths,
|
||||
exact_paths,
|
||||
access_levels,
|
||||
deref_trait_did,
|
||||
deref_mut_trait_did,
|
||||
owned_box_did,
|
||||
..
|
||||
} = render_info;
|
||||
|
||||
let external_paths =
|
||||
external_paths.into_iter().map(|(k, (v, t))| (k, (v, ItemType::from(t)))).collect();
|
||||
|
||||
let mut cache = Cache {
|
||||
external_paths,
|
||||
exact_paths,
|
||||
parent_is_trait_impl: false,
|
||||
stripped_mod: false,
|
||||
access_levels,
|
||||
crate_version: krate.version.take(),
|
||||
document_private,
|
||||
traits: krate.external_traits.replace(Default::default()),
|
||||
deref_trait_did,
|
||||
deref_mut_trait_did,
|
||||
owned_box_did,
|
||||
masked_crates: mem::take(&mut krate.masked_crates),
|
||||
..Cache::default()
|
||||
};
|
||||
debug!(?self.crate_version);
|
||||
self.traits = krate.external_traits.take();
|
||||
self.masked_crates = mem::take(&mut krate.masked_crates);
|
||||
|
||||
// Cache where all our extern crates are located
|
||||
// FIXME: this part is specific to HTML so it'd be nice to remove it from the common code
|
||||
@ -181,12 +159,11 @@ impl Cache {
|
||||
_ => PathBuf::new(),
|
||||
};
|
||||
let extern_url = extern_html_root_urls.get(&*e.name.as_str()).map(|u| &**u);
|
||||
cache
|
||||
.extern_locations
|
||||
self.extern_locations
|
||||
.insert(n, (e.name, src_root, extern_location(e, extern_url, &dst)));
|
||||
|
||||
let did = DefId { krate: n, index: CRATE_DEF_INDEX };
|
||||
cache.external_paths.insert(did, (vec![e.name.to_string()], ItemType::Module));
|
||||
self.external_paths.insert(did, (vec![e.name.to_string()], ItemType::Module));
|
||||
}
|
||||
|
||||
// Cache where all known primitives have their documentation located.
|
||||
@ -195,27 +172,26 @@ impl Cache {
|
||||
// reverse topological order.
|
||||
for &(_, ref e) in krate.externs.iter().rev() {
|
||||
for &(def_id, prim) in &e.primitives {
|
||||
cache.primitive_locations.insert(prim, def_id);
|
||||
self.primitive_locations.insert(prim, def_id);
|
||||
}
|
||||
}
|
||||
for &(def_id, prim) in &krate.primitives {
|
||||
cache.primitive_locations.insert(prim, def_id);
|
||||
self.primitive_locations.insert(prim, def_id);
|
||||
}
|
||||
|
||||
cache.stack.push(krate.name.to_string());
|
||||
self.stack.push(krate.name.to_string());
|
||||
|
||||
krate = CacheBuilder { tcx, cache: &mut cache, empty_cache: Cache::default() }
|
||||
.fold_crate(krate);
|
||||
krate = CacheBuilder { tcx, cache: self, empty_cache: Cache::default() }.fold_crate(krate);
|
||||
|
||||
for (trait_did, dids, impl_) in cache.orphan_trait_impls.drain(..) {
|
||||
if cache.traits.contains_key(&trait_did) {
|
||||
for (trait_did, dids, impl_) in self.orphan_trait_impls.drain(..) {
|
||||
if self.traits.contains_key(&trait_did) {
|
||||
for did in dids {
|
||||
cache.impls.entry(did).or_default().push(impl_.clone());
|
||||
self.impls.entry(did).or_default().push(impl_.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(krate, cache)
|
||||
krate
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::edition::Edition;
|
||||
|
||||
use crate::clean;
|
||||
use crate::config::{RenderInfo, RenderOptions};
|
||||
use crate::config::RenderOptions;
|
||||
use crate::error::Error;
|
||||
use crate::formats::cache::Cache;
|
||||
|
||||
@ -18,7 +18,6 @@ crate trait FormatRenderer<'tcx>: Clone {
|
||||
fn init(
|
||||
krate: clean::Crate,
|
||||
options: RenderOptions,
|
||||
render_info: RenderInfo,
|
||||
edition: Edition,
|
||||
cache: Cache,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
@ -49,26 +48,16 @@ crate trait FormatRenderer<'tcx>: Clone {
|
||||
crate fn run_format<'tcx, T: FormatRenderer<'tcx>>(
|
||||
krate: clean::Crate,
|
||||
options: RenderOptions,
|
||||
render_info: RenderInfo,
|
||||
cache: Cache,
|
||||
diag: &rustc_errors::Handler,
|
||||
edition: Edition,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> Result<(), Error> {
|
||||
let (krate, cache) = tcx.sess.time("create_format_cache", || {
|
||||
Cache::from_krate(
|
||||
render_info.clone(),
|
||||
options.document_private,
|
||||
&options.extern_html_root_urls,
|
||||
&options.output,
|
||||
krate,
|
||||
tcx,
|
||||
)
|
||||
});
|
||||
let prof = &tcx.sess.prof;
|
||||
|
||||
let (mut format_renderer, mut krate) = prof
|
||||
.extra_verbose_generic_activity("create_renderer", T::descr())
|
||||
.run(|| T::init(krate, options, render_info, edition, cache, tcx))?;
|
||||
.run(|| T::init(krate, options, edition, cache, tcx))?;
|
||||
|
||||
let mut item = match krate.module.take() {
|
||||
Some(i) => i,
|
||||
|
@ -66,7 +66,7 @@ use serde::ser::SerializeSeq;
|
||||
use serde::{Serialize, Serializer};
|
||||
|
||||
use crate::clean::{self, AttributesExt, GetDefId, RenderedLink, SelfTy, TypeKind};
|
||||
use crate::config::{RenderInfo, RenderOptions};
|
||||
use crate::config::RenderOptions;
|
||||
use crate::docfs::{DocFS, PathError};
|
||||
use crate::error::Error;
|
||||
use crate::formats::cache::Cache;
|
||||
@ -385,7 +385,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
||||
fn init(
|
||||
mut krate: clean::Crate,
|
||||
options: RenderOptions,
|
||||
_render_info: RenderInfo,
|
||||
edition: Edition,
|
||||
mut cache: Cache,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
@ -19,7 +19,7 @@ use rustc_span::edition::Edition;
|
||||
use rustdoc_json_types as types;
|
||||
|
||||
use crate::clean;
|
||||
use crate::config::{RenderInfo, RenderOptions};
|
||||
use crate::config::RenderOptions;
|
||||
use crate::error::Error;
|
||||
use crate::formats::cache::Cache;
|
||||
use crate::formats::FormatRenderer;
|
||||
@ -133,7 +133,6 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
||||
fn init(
|
||||
krate: clean::Crate,
|
||||
options: RenderOptions,
|
||||
_render_info: RenderInfo,
|
||||
_edition: Edition,
|
||||
cache: Cache,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
@ -200,7 +199,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
||||
|
||||
fn after_krate(
|
||||
&mut self,
|
||||
krate: &clean::Crate,
|
||||
_krate: &clean::Crate,
|
||||
_diag: &rustc_errors::Handler,
|
||||
) -> Result<(), Error> {
|
||||
debug!("Done with crate");
|
||||
@ -211,7 +210,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
||||
#[allow(rustc::default_hash_types)]
|
||||
let output = types::Crate {
|
||||
root: types::Id(String::from("0:0")),
|
||||
crate_version: krate.version.clone(),
|
||||
crate_version: self.cache.crate_version.clone(),
|
||||
includes_private: self.cache.document_private,
|
||||
index: index.into_iter().collect(),
|
||||
paths: self
|
||||
|
@ -49,6 +49,7 @@ extern crate rustc_metadata;
|
||||
extern crate rustc_middle;
|
||||
extern crate rustc_mir;
|
||||
extern crate rustc_parse;
|
||||
extern crate rustc_passes;
|
||||
extern crate rustc_resolve;
|
||||
extern crate rustc_session;
|
||||
extern crate rustc_span as rustc_span;
|
||||
@ -94,7 +95,19 @@ mod visit_lib;
|
||||
pub fn main() {
|
||||
rustc_driver::set_sigpipe_handler();
|
||||
rustc_driver::install_ice_hook();
|
||||
|
||||
// When using CI artifacts (with `download_stage1 = true`), tracing is unconditionally built
|
||||
// with `--features=static_max_level_info`, which disables almost all rustdoc logging. To avoid
|
||||
// this, compile our own version of `tracing` that logs all levels.
|
||||
// NOTE: this compiles both versions of tracing unconditionally, because
|
||||
// - The compile time hit is not that bad, especially compared to rustdoc's incremental times, and
|
||||
// - Otherwise, there's no warning that logging is being ignored when `download_stage1 = true`.
|
||||
// NOTE: The reason this doesn't show double logging when `download_stage1 = false` and
|
||||
// `debug_logging = true` is because all rustc logging goes to its version of tracing (the one
|
||||
// in the sysroot), and all of rustdoc's logging goes to its version (the one in Cargo.toml).
|
||||
init_logging();
|
||||
rustc_driver::init_env_logger("RUSTDOC_LOG");
|
||||
|
||||
let exit_code = rustc_driver::catch_with_exit_code(|| match get_args() {
|
||||
Some(args) => main_args(&args),
|
||||
_ => Err(ErrorReported),
|
||||
@ -102,6 +115,68 @@ pub fn main() {
|
||||
process::exit(exit_code);
|
||||
}
|
||||
|
||||
fn init_logging() {
|
||||
use std::io;
|
||||
|
||||
// FIXME remove these and use winapi 0.3 instead
|
||||
// Duplicates: bootstrap/compile.rs, librustc_errors/emitter.rs, rustc_driver/lib.rs
|
||||
#[cfg(unix)]
|
||||
fn stdout_isatty() -> bool {
|
||||
extern crate libc;
|
||||
unsafe { libc::isatty(libc::STDOUT_FILENO) != 0 }
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn stdout_isatty() -> bool {
|
||||
extern crate winapi;
|
||||
use winapi::um::consoleapi::GetConsoleMode;
|
||||
use winapi::um::processenv::GetStdHandle;
|
||||
use winapi::um::winbase::STD_OUTPUT_HANDLE;
|
||||
|
||||
unsafe {
|
||||
let handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
let mut out = 0;
|
||||
GetConsoleMode(handle, &mut out) != 0
|
||||
}
|
||||
}
|
||||
|
||||
let color_logs = match std::env::var("RUSTDOC_LOG_COLOR") {
|
||||
Ok(value) => match value.as_ref() {
|
||||
"always" => true,
|
||||
"never" => false,
|
||||
"auto" => stdout_isatty(),
|
||||
_ => early_error(
|
||||
ErrorOutputType::default(),
|
||||
&format!(
|
||||
"invalid log color value '{}': expected one of always, never, or auto",
|
||||
value
|
||||
),
|
||||
),
|
||||
},
|
||||
Err(std::env::VarError::NotPresent) => stdout_isatty(),
|
||||
Err(std::env::VarError::NotUnicode(_value)) => early_error(
|
||||
ErrorOutputType::default(),
|
||||
"non-Unicode log color value: expected one of always, never, or auto",
|
||||
),
|
||||
};
|
||||
let filter = tracing_subscriber::EnvFilter::from_env("RUSTDOC_LOG");
|
||||
let layer = tracing_tree::HierarchicalLayer::default()
|
||||
.with_writer(io::stderr)
|
||||
.with_indent_lines(true)
|
||||
.with_ansi(color_logs)
|
||||
.with_targets(true)
|
||||
.with_wraparound(10)
|
||||
.with_verbose_exit(true)
|
||||
.with_verbose_entry(true)
|
||||
.with_indent_amount(2);
|
||||
#[cfg(parallel_compiler)]
|
||||
let layer = layer.with_thread_ids(true).with_thread_names(true);
|
||||
|
||||
use tracing_subscriber::layer::SubscriberExt;
|
||||
let subscriber = tracing_subscriber::Registry::default().with(filter).with(layer);
|
||||
tracing::subscriber::set_global_default(subscriber).unwrap();
|
||||
}
|
||||
|
||||
fn get_args() -> Option<Vec<String>> {
|
||||
env::args_os()
|
||||
.enumerate()
|
||||
@ -479,12 +554,12 @@ fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> MainRes
|
||||
fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>(
|
||||
krate: clean::Crate,
|
||||
renderopts: config::RenderOptions,
|
||||
render_info: config::RenderInfo,
|
||||
cache: formats::cache::Cache,
|
||||
diag: &rustc_errors::Handler,
|
||||
edition: rustc_span::edition::Edition,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> MainResult {
|
||||
match formats::run_format::<T>(krate, renderopts, render_info, &diag, edition, tcx) {
|
||||
match formats::run_format::<T>(krate, renderopts, cache, &diag, edition, tcx) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
let mut msg = diag.struct_err(&format!("couldn't generate documentation: {}", e.error));
|
||||
@ -553,7 +628,7 @@ fn main_options(options: config::Options) -> MainResult {
|
||||
let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess).peek_mut();
|
||||
|
||||
global_ctxt.enter(|tcx| {
|
||||
let (mut krate, render_info, render_opts) = sess.time("run_global_ctxt", || {
|
||||
let (krate, render_opts, mut cache) = sess.time("run_global_ctxt", || {
|
||||
core::run_global_ctxt(
|
||||
tcx,
|
||||
resolver,
|
||||
@ -565,7 +640,7 @@ fn main_options(options: config::Options) -> MainResult {
|
||||
});
|
||||
info!("finished with rustc");
|
||||
|
||||
krate.version = crate_version;
|
||||
cache.crate_version = crate_version;
|
||||
|
||||
if show_coverage {
|
||||
// if we ran coverage, bail early, we don't need to also generate docs at this point
|
||||
@ -584,7 +659,7 @@ fn main_options(options: config::Options) -> MainResult {
|
||||
run_renderer::<html::render::Context<'_>>(
|
||||
krate,
|
||||
render_opts,
|
||||
render_info,
|
||||
cache,
|
||||
&diag,
|
||||
edition,
|
||||
tcx,
|
||||
@ -594,7 +669,7 @@ fn main_options(options: config::Options) -> MainResult {
|
||||
run_renderer::<json::JsonRenderer<'_>>(
|
||||
krate,
|
||||
render_opts,
|
||||
render_info,
|
||||
cache,
|
||||
&diag,
|
||||
edition,
|
||||
tcx,
|
||||
|
@ -127,7 +127,7 @@ impl<'a, 'b> CoverageCalculator<'a, 'b> {
|
||||
}
|
||||
|
||||
fn print_results(&self) {
|
||||
let output_format = self.ctx.renderinfo.output_format;
|
||||
let output_format = self.ctx.output_format;
|
||||
if output_format.is_json() {
|
||||
println!("{}", self.to_json());
|
||||
return;
|
||||
|
@ -47,7 +47,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
|
||||
// FIXME(eddyb) is this `doc(hidden)` check needed?
|
||||
if !cx.tcx.get_attrs(def_id).lists(sym::doc).has_word(sym::hidden) {
|
||||
let impls = get_auto_trait_and_blanket_impls(cx, def_id);
|
||||
new_items.extend(impls.filter(|i| cx.renderinfo.inlined.insert(i.def_id)));
|
||||
new_items.extend(impls.filter(|i| cx.inlined.insert(i.def_id)));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ crate fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) {
|
||||
|lint| lint.build("missing code example in this documentation").emit(),
|
||||
);
|
||||
}
|
||||
} else if tests.found_tests > 0 && !cx.renderinfo.access_levels.is_public(item.def_id) {
|
||||
} else if tests.found_tests > 0 && !cx.cache.access_levels.is_public(item.def_id) {
|
||||
cx.tcx.struct_span_lint_hir(
|
||||
lint::builtin::PRIVATE_DOC_TESTS,
|
||||
hir_id,
|
||||
|
@ -17,13 +17,12 @@ crate const STRIP_PRIVATE: Pass = Pass {
|
||||
crate fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
|
||||
// This stripper collects all *retained* nodes.
|
||||
let mut retained = DefIdSet::default();
|
||||
let access_levels = cx.renderinfo.access_levels.clone();
|
||||
|
||||
// strip all private items
|
||||
{
|
||||
let mut stripper = Stripper {
|
||||
retained: &mut retained,
|
||||
access_levels: &access_levels,
|
||||
access_levels: &cx.cache.access_levels,
|
||||
update_retained: true,
|
||||
};
|
||||
krate = ImportStripper.fold_crate(stripper.fold_crate(krate));
|
||||
|
@ -113,7 +113,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
assert_eq!(cur_mod_def_id, macro_parent_def_id);
|
||||
cur_mod.macros.push((def, None));
|
||||
}
|
||||
self.cx.renderinfo.exact_paths = self.exact_paths;
|
||||
self.cx.cache.exact_paths = self.exact_paths;
|
||||
top_level_module
|
||||
}
|
||||
|
||||
@ -199,7 +199,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
} else {
|
||||
// All items need to be handled here in case someone wishes to link
|
||||
// to them with intra-doc links
|
||||
self.cx.renderinfo.access_levels.map.insert(did, AccessLevel::Public);
|
||||
self.cx.cache.access_levels.map.insert(did, AccessLevel::Public);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -211,7 +211,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
None => return false,
|
||||
};
|
||||
|
||||
let is_private = !self.cx.renderinfo.access_levels.is_public(res_did);
|
||||
let is_private = !self.cx.cache.access_levels.is_public(res_did);
|
||||
let is_hidden = inherits_doc_hidden(self.cx, res_hir_id);
|
||||
|
||||
// Only inline if requested or if the item would otherwise be stripped.
|
||||
|
@ -25,7 +25,7 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
|
||||
crate fn new(cx: &'a mut crate::core::DocContext<'tcx>) -> LibEmbargoVisitor<'a, 'tcx> {
|
||||
LibEmbargoVisitor {
|
||||
tcx: cx.tcx,
|
||||
access_levels: &mut cx.renderinfo.access_levels,
|
||||
access_levels: &mut cx.cache.access_levels,
|
||||
prev_level: Some(AccessLevel::Public),
|
||||
visited_mods: FxHashSet::default(),
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
// edition:2018
|
||||
// compile-flags: --crate-version 1.0.0
|
||||
|
||||
// @is nested.json "$.index[*][?(@.name=='nested')].kind" \"module\"
|
||||
// @is nested.json "$.crate_version" \"1.0.0\"
|
||||
// @is - "$.index[*][?(@.name=='nested')].kind" \"module\"
|
||||
// @is - "$.index[*][?(@.name=='nested')].inner.is_crate" true
|
||||
// @count - "$.index[*][?(@.name=='nested')].inner.items[*]" 1
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// check-pass
|
||||
|
||||
#![doc(no_default_passes, passes = "collapse-docs unindent-comments")]
|
||||
#![doc(no_default_passes, passes = "unindent-comments")]
|
||||
|
||||
struct SomeStruct;
|
||||
|
||||
|
5
src/test/rustdoc-ui/doc-attr.rs
Normal file
5
src/test/rustdoc-ui/doc-attr.rs
Normal file
@ -0,0 +1,5 @@
|
||||
#![crate_type = "lib"]
|
||||
#![doc(as_ptr)] //~ ERROR
|
||||
|
||||
#[doc(as_ptr)] //~ ERROR
|
||||
pub fn foo() {}
|
14
src/test/rustdoc-ui/doc-attr.stderr
Normal file
14
src/test/rustdoc-ui/doc-attr.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: unknown `doc` attribute `as_ptr`
|
||||
--> $DIR/doc-attr.rs:4:7
|
||||
|
|
||||
LL | #[doc(as_ptr)]
|
||||
| ^^^^^^
|
||||
|
||||
error: unknown `doc` attribute `as_ptr`
|
||||
--> $DIR/doc-attr.rs:2:8
|
||||
|
|
||||
LL | #![doc(as_ptr)]
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
4
src/test/rustdoc-ui/rustc-check-passes.rs
Normal file
4
src/test/rustdoc-ui/rustc-check-passes.rs
Normal file
@ -0,0 +1,4 @@
|
||||
#![feature(box_syntax)]
|
||||
#![feature(box_syntax)] //~ ERROR
|
||||
|
||||
pub fn foo() {}
|
9
src/test/rustdoc-ui/rustc-check-passes.stderr
Normal file
9
src/test/rustdoc-ui/rustc-check-passes.stderr
Normal file
@ -0,0 +1,9 @@
|
||||
error[E0636]: the feature `box_syntax` has already been declared
|
||||
--> $DIR/rustc-check-passes.rs:2:12
|
||||
|
|
||||
LL | #![feature(box_syntax)]
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0636`.
|
@ -1,3 +1,4 @@
|
||||
#![stable(feature = "bar", since = "OLD 1.0")]
|
||||
#![crate_name = "foo"]
|
||||
|
||||
#![feature(staged_api)]
|
||||
@ -8,6 +9,7 @@ pub trait Bar {}
|
||||
#[stable(feature = "baz", since = "OLD 1.0")]
|
||||
pub trait Baz {}
|
||||
|
||||
#[stable(feature = "baz", since = "OLD 1.0")]
|
||||
pub struct Foo;
|
||||
|
||||
// @has foo/trait.Bar.html '//div[@id="implementors-list"]//span[@class="since"]' 'NEW 2.0'
|
||||
|
5
src/test/ui/attributes/doc-attr.rs
Normal file
5
src/test/ui/attributes/doc-attr.rs
Normal file
@ -0,0 +1,5 @@
|
||||
#![crate_type = "lib"]
|
||||
#![doc(as_ptr)] //~ ERROR
|
||||
|
||||
#[doc(as_ptr)] //~ ERROR
|
||||
pub fn foo() {}
|
14
src/test/ui/attributes/doc-attr.stderr
Normal file
14
src/test/ui/attributes/doc-attr.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: unknown `doc` attribute `as_ptr`
|
||||
--> $DIR/doc-attr.rs:4:7
|
||||
|
|
||||
LL | #[doc(as_ptr)]
|
||||
| ^^^^^^
|
||||
|
||||
error: unknown `doc` attribute `as_ptr`
|
||||
--> $DIR/doc-attr.rs:2:8
|
||||
|
|
||||
LL | #![doc(as_ptr)]
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
17
src/test/ui/consts/issue-66693-panic-in-array-len.rs
Normal file
17
src/test/ui/consts/issue-66693-panic-in-array-len.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// This is a separate test from `issue-66693.rs` because array lengths are evaluated
|
||||
// in a separate stage before `const`s and `statics` and so the error below is hit and
|
||||
// the compiler exits before generating errors for the others.
|
||||
|
||||
#![feature(const_panic)]
|
||||
|
||||
fn main() {
|
||||
let _ = [0i32; panic!(2f32)];
|
||||
//~^ ERROR: argument to `panic!()` in a const context must have type `&str`
|
||||
|
||||
// ensure that conforming panics are handled correctly
|
||||
let _ = [false; panic!()];
|
||||
//~^ ERROR: evaluation of constant value failed
|
||||
|
||||
// typechecking halts before getting to this one
|
||||
let _ = ['a', panic!("panic in array len")];
|
||||
}
|
19
src/test/ui/consts/issue-66693-panic-in-array-len.stderr
Normal file
19
src/test/ui/consts/issue-66693-panic-in-array-len.stderr
Normal file
@ -0,0 +1,19 @@
|
||||
error: argument to `panic!()` in a const context must have type `&str`
|
||||
--> $DIR/issue-66693-panic-in-array-len.rs:8:20
|
||||
|
|
||||
LL | let _ = [0i32; panic!(2f32)];
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/issue-66693-panic-in-array-len.rs:12:21
|
||||
|
|
||||
LL | let _ = [false; panic!()];
|
||||
| ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-66693-panic-in-array-len.rs:12:21
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
24
src/test/ui/consts/issue-66693.rs
Normal file
24
src/test/ui/consts/issue-66693.rs
Normal file
@ -0,0 +1,24 @@
|
||||
// Tests that the compiler does not ICE when const-evaluating a `panic!()` invocation with a
|
||||
// non-`&str` argument.
|
||||
|
||||
#![feature(const_panic)]
|
||||
|
||||
const _: () = panic!(1);
|
||||
//~^ ERROR: argument to `panic!()` in a const context must have type `&str`
|
||||
|
||||
static _FOO: () = panic!(true);
|
||||
//~^ ERROR: argument to `panic!()` in a const context must have type `&str`
|
||||
|
||||
const fn _foo() {
|
||||
panic!(&1); //~ ERROR: argument to `panic!()` in a const context must have type `&str`
|
||||
}
|
||||
|
||||
// ensure that conforming panics don't cause an error
|
||||
const _: () = panic!();
|
||||
static _BAR: () = panic!("panic in static");
|
||||
|
||||
const fn _bar() {
|
||||
panic!("panic in const fn");
|
||||
}
|
||||
|
||||
fn main() {}
|
26
src/test/ui/consts/issue-66693.stderr
Normal file
26
src/test/ui/consts/issue-66693.stderr
Normal file
@ -0,0 +1,26 @@
|
||||
error: argument to `panic!()` in a const context must have type `&str`
|
||||
--> $DIR/issue-66693.rs:13:5
|
||||
|
|
||||
LL | panic!(&1);
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: argument to `panic!()` in a const context must have type `&str`
|
||||
--> $DIR/issue-66693.rs:6:15
|
||||
|
|
||||
LL | const _: () = panic!(1);
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: argument to `panic!()` in a const context must have type `&str`
|
||||
--> $DIR/issue-66693.rs:9:19
|
||||
|
|
||||
LL | static _FOO: () = panic!(true);
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
@ -1,3 +1,5 @@
|
||||
struct Bug([u8; panic!(1)]); //~ ERROR panicking in constants is unstable
|
||||
// Note: non-`&str` panic arguments gained a separate error in PR #80734
|
||||
// which is why this doesn't match the issue
|
||||
struct Bug([u8; panic!("panic")]); //~ ERROR panicking in constants is unstable
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,8 +1,8 @@
|
||||
error[E0658]: panicking in constants is unstable
|
||||
--> $DIR/issue-76064.rs:1:17
|
||||
--> $DIR/issue-76064.rs:3:17
|
||||
|
|
||||
LL | struct Bug([u8; panic!(1)]);
|
||||
| ^^^^^^^^^
|
||||
LL | struct Bug([u8; panic!("panic")]);
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #51999 <https://github.com/rust-lang/rust/issues/51999> for more information
|
||||
= help: add `#![feature(const_panic)]` to the crate attributes to enable
|
||||
|
@ -12,16 +12,16 @@ LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
|
||||
= note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
|
||||
|
||||
warning: unused variable: `mut_unused_var`
|
||||
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:33:9
|
||||
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:33:13
|
||||
|
|
||||
LL | let mut mut_unused_var = 1;
|
||||
| ^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_mut_unused_var`
|
||||
| ^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_mut_unused_var`
|
||||
|
||||
warning: unused variable: `var`
|
||||
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:10
|
||||
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:14
|
||||
|
|
||||
LL | let (mut var, unused_var) = (1, 2);
|
||||
| ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_var`
|
||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_var`
|
||||
|
||||
warning: unused variable: `unused_var`
|
||||
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:19
|
||||
@ -36,10 +36,10 @@ LL | if let SoulHistory { corridors_of_light,
|
||||
| ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _`
|
||||
|
||||
warning: variable `hours_are_suns` is assigned to, but never used
|
||||
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:46:26
|
||||
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:46:30
|
||||
|
|
||||
LL | mut hours_are_suns,
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: consider using `_hours_are_suns` instead
|
||||
|
||||
|
12
src/test/ui/lint/issue-81314-unused-span-ident.fixed
Normal file
12
src/test/ui/lint/issue-81314-unused-span-ident.fixed
Normal file
@ -0,0 +1,12 @@
|
||||
// run-rustfix
|
||||
// Regression test for #81314: Unused variable lint should
|
||||
// span only the identifier and not the rest of the pattern
|
||||
|
||||
#![deny(unused)]
|
||||
|
||||
fn main() {
|
||||
let [_rest @ ..] = [1, 2, 3]; //~ ERROR unused variable
|
||||
}
|
||||
|
||||
pub fn foo([_rest @ ..]: &[i32]) { //~ ERROR unused variable
|
||||
}
|
12
src/test/ui/lint/issue-81314-unused-span-ident.rs
Normal file
12
src/test/ui/lint/issue-81314-unused-span-ident.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// run-rustfix
|
||||
// Regression test for #81314: Unused variable lint should
|
||||
// span only the identifier and not the rest of the pattern
|
||||
|
||||
#![deny(unused)]
|
||||
|
||||
fn main() {
|
||||
let [rest @ ..] = [1, 2, 3]; //~ ERROR unused variable
|
||||
}
|
||||
|
||||
pub fn foo([rest @ ..]: &[i32]) { //~ ERROR unused variable
|
||||
}
|
21
src/test/ui/lint/issue-81314-unused-span-ident.stderr
Normal file
21
src/test/ui/lint/issue-81314-unused-span-ident.stderr
Normal file
@ -0,0 +1,21 @@
|
||||
error: unused variable: `rest`
|
||||
--> $DIR/issue-81314-unused-span-ident.rs:8:10
|
||||
|
|
||||
LL | let [rest @ ..] = [1, 2, 3];
|
||||
| ^^^^ help: if this is intentional, prefix it with an underscore: `_rest`
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/issue-81314-unused-span-ident.rs:5:9
|
||||
|
|
||||
LL | #![deny(unused)]
|
||||
| ^^^^^^
|
||||
= note: `#[deny(unused_variables)]` implied by `#[deny(unused)]`
|
||||
|
||||
error: unused variable: `rest`
|
||||
--> $DIR/issue-81314-unused-span-ident.rs:11:13
|
||||
|
|
||||
LL | pub fn foo([rest @ ..]: &[i32]) {
|
||||
| ^^^^ help: if this is intentional, prefix it with an underscore: `_rest`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -1,8 +1,8 @@
|
||||
warning: variable `a` is assigned to, but never used
|
||||
--> $DIR/liveness-consts.rs:7:9
|
||||
--> $DIR/liveness-consts.rs:7:13
|
||||
|
|
||||
LL | let mut a = 0;
|
||||
| ^^^^^
|
||||
| ^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/liveness-consts.rs:2:9
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: value assigned to `x` is never read
|
||||
--> $DIR/liveness-dead.rs:9:9
|
||||
--> $DIR/liveness-dead.rs:9:13
|
||||
|
|
||||
LL | let mut x: isize = 3;
|
||||
| ^^^^^
|
||||
| ^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/liveness-dead.rs:2:9
|
||||
@ -20,10 +20,10 @@ LL | x = 4;
|
||||
= help: maybe it is overwritten before being read?
|
||||
|
||||
error: value passed to `x` is never read
|
||||
--> $DIR/liveness-dead.rs:20:7
|
||||
--> $DIR/liveness-dead.rs:20:11
|
||||
|
|
||||
LL | fn f4(mut x: i32) {
|
||||
| ^^^^^
|
||||
| ^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
|
||||
|
@ -44,10 +44,10 @@ LL | let x = 3;
|
||||
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
||||
|
||||
error: variable `x` is assigned to, but never used
|
||||
--> $DIR/liveness-unused.rs:30:9
|
||||
--> $DIR/liveness-unused.rs:30:13
|
||||
|
|
||||
LL | let mut x = 3;
|
||||
| ^^^^^
|
||||
| ^
|
||||
|
|
||||
= note: consider using `_x` instead
|
||||
|
||||
@ -65,10 +65,10 @@ LL | #![deny(unused_assignments)]
|
||||
= help: maybe it is overwritten before being read?
|
||||
|
||||
error: variable `z` is assigned to, but never used
|
||||
--> $DIR/liveness-unused.rs:37:9
|
||||
--> $DIR/liveness-unused.rs:37:13
|
||||
|
|
||||
LL | let mut z = 3;
|
||||
| ^^^^^
|
||||
| ^
|
||||
|
|
||||
= note: consider using `_z` instead
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user