Auto merge of #86806 - GuillaumeGomez:rollup-pr5r37w, r=GuillaumeGomez

Rollup of 5 pull requests

Successful merges:

 - #85749 (Revert "Don't load all extern crates unconditionally")
 - #86714 (Add linked list cursor end methods)
 - #86737 (Document rustfmt on nightly-rustc)
 - #86776 (Skip layout query when computing integer type size during mangling)
 - #86797 (Stabilize `Bound::cloned()`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-07-02 11:42:38 +00:00
commit ce331ee6ee
18 changed files with 327 additions and 174 deletions

View File

@ -3,9 +3,11 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::def_id::{CrateNum, DefId};
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::print::{Print, Printer}; use rustc_middle::ty::print::{Print, Printer};
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
use rustc_middle::ty::{self, FloatTy, Instance, IntTy, Ty, TyCtxt, TypeFoldable, UintTy}; use rustc_middle::ty::{self, FloatTy, Instance, IntTy, Ty, TyCtxt, TypeFoldable, UintTy};
use rustc_target::abi::Integer;
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
use std::fmt::Write; use std::fmt::Write;
@ -553,11 +555,9 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
ty::Uint(_) | ty::Bool | ty::Char => { ty::Uint(_) | ty::Bool | ty::Char => {
ct.try_eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty) ct.try_eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty)
} }
ty::Int(_) => { ty::Int(ity) => {
let param_env = ty::ParamEnv::reveal_all(); ct.try_eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty).and_then(|b| {
ct.try_eval_bits(self.tcx, param_env, ct.ty).and_then(|b| { let val = Integer::from_int_ty(&self.tcx, *ity).size().sign_extend(b) as i128;
let sz = self.tcx.layout_of(param_env.and(ct.ty)).ok()?.size;
let val = sz.sign_extend(b) as i128;
if val < 0 { if val < 0 {
neg = true; neg = true;
} }

View File

@ -1243,6 +1243,20 @@ impl<'a, T> Cursor<'a, T> {
prev.map(|prev| &(*prev.as_ptr()).element) prev.map(|prev| &(*prev.as_ptr()).element)
} }
} }
/// Provides a reference to the front element of the cursor's parent list,
/// or None if the list is empty.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn front(&self) -> Option<&'a T> {
self.list.front()
}
/// Provides a reference to the back element of the cursor's parent list,
/// or None if the list is empty.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn back(&self) -> Option<&'a T> {
self.list.back()
}
} }
impl<'a, T> CursorMut<'a, T> { impl<'a, T> CursorMut<'a, T> {
@ -1506,6 +1520,135 @@ impl<'a, T> CursorMut<'a, T> {
self.index = 0; self.index = 0;
unsafe { self.list.split_off_before_node(self.current, split_off_idx) } unsafe { self.list.split_off_before_node(self.current, split_off_idx) }
} }
/// Appends an element to the front of the cursor's parent list. The node
/// that the cursor points to is unchanged, even if it is the "ghost" node.
///
/// This operation should compute in O(1) time.
// `push_front` continues to point to "ghost" when it addes a node to mimic
// the behavior of `insert_before` on an empty list.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn push_front(&mut self, elt: T) {
// Safety: We know that `push_front` does not change the position in
// memory of other nodes. This ensures that `self.current` remains
// valid.
self.list.push_front(elt);
self.index += 1;
}
/// Appends an element to the back of the cursor's parent list. The node
/// that the cursor points to is unchanged, even if it is the "ghost" node.
///
/// This operation should compute in O(1) time.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn push_back(&mut self, elt: T) {
// Safety: We know that `push_back` does not change the position in
// memory of other nodes. This ensures that `self.current` remains
// valid.
self.list.push_back(elt);
if self.current().is_none() {
// The index of "ghost" is the length of the list, so we just need
// to increment self.index to reflect the new length of the list.
self.index += 1;
}
}
/// Removes the first element from the cursor's parent list and returns it,
/// or None if the list is empty. The element the cursor points to remains
/// unchanged, unless it was pointing to the front element. In that case, it
/// points to the new front element.
///
/// This operation should compute in O(1) time.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn pop_front(&mut self) -> Option<T> {
// We can't check if current is empty, we must check the list directly.
// It is possible for `self.current == None` and the list to be
// non-empty.
if self.list.is_empty() {
None
} else {
// We can't point to the node that we pop. Copying the behavior of
// `remove_current`, we move on the the next node in the sequence.
// If the list is of length 1 then we end pointing to the "ghost"
// node at index 0, which is expected.
if self.list.head == self.current {
self.move_next();
} else {
self.index -= 1;
}
self.list.pop_front()
}
}
/// Removes the last element from the cursor's parent list and returns it,
/// or None if the list is empty. The element the cursor points to remains
/// unchanged, unless it was pointing to the back element. In that case, it
/// points to the "ghost" element.
///
/// This operation should compute in O(1) time.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn pop_back(&mut self) -> Option<T> {
if self.list.is_empty() {
None
} else {
if self.list.tail == self.current {
// The index now reflects the length of the list. It was the
// length of the list minus 1, but now the list is 1 smaller. No
// change is needed for `index`.
self.current = None;
} else if self.current.is_none() {
self.index = self.list.len - 1;
}
self.list.pop_back()
}
}
/// Provides a reference to the front element of the cursor's parent list,
/// or None if the list is empty.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn front(&self) -> Option<&T> {
self.list.front()
}
/// Provides a mutable reference to the front element of the cursor's
/// parent list, or None if the list is empty.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn front_mut(&mut self) -> Option<&mut T> {
self.list.front_mut()
}
/// Provides a reference to the back element of the cursor's parent list,
/// or None if the list is empty.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn back(&self) -> Option<&T> {
self.list.back()
}
/// Provides a mutable reference to back element of the cursor's parent
/// list, or `None` if the list is empty.
///
/// # Examples
/// Building and mutating a list with a cursor, then getting the back element:
/// ```
/// #![feature(linked_list_cursors)]
/// use std::collections::LinkedList;
/// let mut dl = LinkedList::new();
/// dl.push_front(3);
/// dl.push_front(2);
/// dl.push_front(1);
/// let mut cursor = dl.cursor_front_mut();
/// *cursor.current().unwrap() = 99;
/// *cursor.back_mut().unwrap() = 0;
/// let mut contents = dl.into_iter();
/// assert_eq!(contents.next(), Some(99));
/// assert_eq!(contents.next(), Some(2));
/// assert_eq!(contents.next(), Some(0));
/// assert_eq!(contents.next(), None);
/// ```
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn back_mut(&mut self) -> Option<&mut T> {
self.list.back_mut()
}
} }
/// An iterator produced by calling `drain_filter` on LinkedList. /// An iterator produced by calling `drain_filter` on LinkedList.

View File

@ -428,3 +428,50 @@ fn test_cursor_mut_insert() {
check_links(&m); check_links(&m);
assert_eq!(m.iter().cloned().collect::<Vec<_>>(), &[200, 201, 202, 203, 1, 100, 101]); assert_eq!(m.iter().cloned().collect::<Vec<_>>(), &[200, 201, 202, 203, 1, 100, 101]);
} }
#[test]
fn test_cursor_push_front_back() {
let mut ll: LinkedList<u32> = LinkedList::new();
ll.extend(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
let mut c = ll.cursor_front_mut();
assert_eq!(c.current(), Some(&mut 1));
assert_eq!(c.index(), Some(0));
c.push_front(0);
assert_eq!(c.current(), Some(&mut 1));
assert_eq!(c.peek_prev(), Some(&mut 0));
assert_eq!(c.index(), Some(1));
c.push_back(11);
drop(c);
let p = ll.cursor_back().front().unwrap();
assert_eq!(p, &0);
assert_eq!(ll, (0..12).collect());
check_links(&ll);
}
#[test]
fn test_cursor_pop_front_back() {
let mut ll: LinkedList<u32> = LinkedList::new();
ll.extend(&[1, 2, 3, 4, 5, 6]);
let mut c = ll.cursor_back_mut();
assert_eq!(c.pop_front(), Some(1));
c.move_prev();
c.move_prev();
c.move_prev();
assert_eq!(c.pop_back(), Some(6));
let c = c.as_cursor();
assert_eq!(c.front(), Some(&2));
assert_eq!(c.back(), Some(&5));
assert_eq!(c.index(), Some(1));
drop(c);
assert_eq!(ll, (2..6).collect());
check_links(&ll);
let mut c = ll.cursor_back_mut();
assert_eq!(c.current(), Some(&mut 5));
assert_eq!(c.index, 3);
assert_eq!(c.pop_back(), Some(5));
assert_eq!(c.current(), None);
assert_eq!(c.index, 3);
assert_eq!(c.pop_back(), Some(4));
assert_eq!(c.current(), None);
assert_eq!(c.index, 2);
}

View File

@ -737,14 +737,13 @@ impl<T: Clone> Bound<&T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(bound_cloned)]
/// use std::ops::Bound::*; /// use std::ops::Bound::*;
/// use std::ops::RangeBounds; /// use std::ops::RangeBounds;
/// ///
/// assert_eq!((1..12).start_bound(), Included(&1)); /// assert_eq!((1..12).start_bound(), Included(&1));
/// assert_eq!((1..12).start_bound().cloned(), Included(1)); /// assert_eq!((1..12).start_bound().cloned(), Included(1));
/// ``` /// ```
#[unstable(feature = "bound_cloned", issue = "61356")] #[stable(feature = "bound_cloned", since = "1.55.0")]
pub fn cloned(self) -> Bound<T> { pub fn cloned(self) -> Bound<T> {
match self { match self {
Bound::Unbounded => Bound::Unbounded, Bound::Unbounded => Bound::Unbounded,

View File

@ -4,7 +4,6 @@
#![feature(array_map)] #![feature(array_map)]
#![feature(array_windows)] #![feature(array_windows)]
#![feature(bool_to_option)] #![feature(bool_to_option)]
#![feature(bound_cloned)]
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(cell_update)] #![feature(cell_update)]
#![feature(cfg_panic)] #![feature(cfg_panic)]

View File

@ -31,7 +31,6 @@
#![feature(restricted_std)] #![feature(restricted_std)]
#![feature(rustc_attrs)] #![feature(rustc_attrs)]
#![feature(min_specialization)] #![feature(min_specialization)]
#![feature(bound_cloned)]
#![recursion_limit = "256"] #![recursion_limit = "256"]
#[unstable(feature = "proc_macro_internals", issue = "27812")] #[unstable(feature = "proc_macro_internals", issue = "27812")]

View File

@ -465,6 +465,7 @@ impl<'a> Builder<'a> {
doc::Std, doc::Std,
doc::Rustc, doc::Rustc,
doc::Rustdoc, doc::Rustdoc,
doc::Rustfmt,
doc::ErrorIndex, doc::ErrorIndex,
doc::Nomicon, doc::Nomicon,
doc::Reference, doc::Reference,

View File

@ -593,84 +593,97 @@ impl Step for Rustc {
} }
} }
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] macro_rules! tool_doc {
pub struct Rustdoc { ($tool: ident, $should_run: literal, $path: literal, [$($krate: literal),+ $(,)?] $(, binary=$bin:expr)?) => {
stage: u32, #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
target: TargetSelection, pub struct $tool {
} stage: u32,
target: TargetSelection,
impl Step for Rustdoc {
type Output = ();
const DEFAULT: bool = true;
const ONLY_HOSTS: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.krate("rustdoc-tool")
}
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(Rustdoc { stage: run.builder.top_stage, target: run.target });
}
/// Generates compiler documentation.
///
/// This will generate all documentation for compiler and dependencies.
/// Compiler documentation is distributed separately, so we make sure
/// we do not merge it with the other documentation from std, test and
/// proc_macros. This is largely just a wrapper around `cargo doc`.
fn run(self, builder: &Builder<'_>) {
let stage = self.stage;
let target = self.target;
builder.info(&format!("Documenting stage{} rustdoc ({})", stage, target));
// This is the intended out directory for compiler documentation.
let out = builder.compiler_doc_out(target);
t!(fs::create_dir_all(&out));
let compiler = builder.compiler(stage, builder.config.build);
if !builder.config.compiler_docs {
builder.info("\tskipping - compiler/librustdoc docs disabled");
return;
} }
// Build rustc docs so that we generate relative links. impl Step for $tool {
builder.ensure(Rustc { stage, target }); type Output = ();
const DEFAULT: bool = true;
const ONLY_HOSTS: bool = true;
// Build rustdoc. fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
builder.ensure(tool::Rustdoc { compiler }); run.krate($should_run)
}
// Symlink compiler docs to the output directory of rustdoc documentation. fn make_run(run: RunConfig<'_>) {
let out_dir = builder.stage_out(compiler, Mode::ToolRustc).join(target.triple).join("doc"); run.builder.ensure($tool { stage: run.builder.top_stage, target: run.target });
t!(fs::create_dir_all(&out_dir)); }
t!(symlink_dir_force(&builder.config, &out, &out_dir));
// Build cargo command. /// Generates compiler documentation.
let mut cargo = prepare_tool_cargo( ///
builder, /// This will generate all documentation for compiler and dependencies.
compiler, /// Compiler documentation is distributed separately, so we make sure
Mode::ToolRustc, /// we do not merge it with the other documentation from std, test and
target, /// proc_macros. This is largely just a wrapper around `cargo doc`.
"doc", fn run(self, builder: &Builder<'_>) {
"src/tools/rustdoc", let stage = self.stage;
SourceType::InTree, let target = self.target;
&[], builder.info(&format!("Documenting stage{} {} ({})", stage, stringify!($tool).to_lowercase(), target));
);
cargo.arg("-Zskip-rustdoc-fingerprint"); // This is the intended out directory for compiler documentation.
// Only include compiler crates, no dependencies of those, such as `libc`. let out = builder.compiler_doc_out(target);
cargo.arg("--no-deps"); t!(fs::create_dir_all(&out));
cargo.arg("-p").arg("rustdoc");
cargo.arg("-p").arg("rustdoc-json-types");
cargo.rustdocflag("--document-private-items"); let compiler = builder.compiler(stage, builder.config.build);
cargo.rustdocflag("--enable-index-page");
cargo.rustdocflag("--show-type-layout"); if !builder.config.compiler_docs {
cargo.rustdocflag("-Zunstable-options"); builder.info("\tskipping - compiler/tool docs disabled");
builder.run(&mut cargo.into()); return;
}
// Build rustc docs so that we generate relative links.
builder.ensure(Rustc { stage, target });
// Symlink compiler docs to the output directory of rustdoc documentation.
let out_dir = builder.stage_out(compiler, Mode::ToolRustc).join(target.triple).join("doc");
t!(fs::create_dir_all(&out_dir));
t!(symlink_dir_force(&builder.config, &out, &out_dir));
// Build cargo command.
let mut cargo = prepare_tool_cargo(
builder,
compiler,
Mode::ToolRustc,
target,
"doc",
$path,
SourceType::InTree,
&[],
);
cargo.arg("-Zskip-rustdoc-fingerprint");
// Only include compiler crates, no dependencies of those, such as `libc`.
cargo.arg("--no-deps");
$(
cargo.arg("-p").arg($krate);
)+
$(if !$bin {
cargo.rustdocflag("--document-private-items");
})?
cargo.rustdocflag("--enable-index-page");
cargo.rustdocflag("--show-type-layout");
cargo.rustdocflag("-Zunstable-options");
builder.run(&mut cargo.into());
}
}
} }
} }
tool_doc!(Rustdoc, "rustdoc-tool", "src/tools/rustdoc", ["rustdoc", "rustdoc-json-types"]);
tool_doc!(
Rustfmt,
"rustfmt-nightly",
"src/tools/rustfmt",
["rustfmt-nightly", "rustfmt-config_proc_macro"],
binary = true
);
#[derive(Ord, PartialOrd, Debug, Copy, Clone, Hash, PartialEq, Eq)] #[derive(Ord, PartialOrd, Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct ErrorIndex { pub struct ErrorIndex {
pub target: TargetSelection, pub target: TargetSelection,

View File

@ -1,12 +1,12 @@
use rustc_ast as ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::{self, Lrc}; use rustc_data_structures::sync::{self, Lrc};
use rustc_driver::abort_on_err; use rustc_driver::abort_on_err;
use rustc_errors::emitter::{Emitter, EmitterWriter}; use rustc_errors::emitter::{Emitter, EmitterWriter};
use rustc_errors::json::JsonEmitter; use rustc_errors::json::JsonEmitter;
use rustc_feature::UnstableFeatures; use rustc_feature::UnstableFeatures;
use rustc_hir::def::Namespace::TypeNS;
use rustc_hir::def::Res; use rustc_hir::def::Res;
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX};
use rustc_hir::HirId; use rustc_hir::HirId;
use rustc_hir::{ use rustc_hir::{
intravisit::{self, NestedVisitorMap, Visitor}, intravisit::{self, NestedVisitorMap, Visitor},
@ -23,7 +23,7 @@ use rustc_session::DiagnosticOutput;
use rustc_session::Session; use rustc_session::Session;
use rustc_span::source_map; use rustc_span::source_map;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::Span; use rustc_span::{Span, DUMMY_SP};
use std::cell::RefCell; use std::cell::RefCell;
use std::mem; use std::mem;
@ -300,16 +300,41 @@ crate fn create_config(
} }
crate fn create_resolver<'a>( crate fn create_resolver<'a>(
externs: config::Externs,
queries: &Queries<'a>, queries: &Queries<'a>,
sess: &Session, sess: &Session,
) -> Rc<RefCell<interface::BoxedResolver>> { ) -> Rc<RefCell<interface::BoxedResolver>> {
let (krate, resolver, _) = &*abort_on_err(queries.expansion(), sess).peek(); let extern_names: Vec<String> = externs
let resolver = resolver.clone(); .iter()
.filter(|(_, entry)| entry.add_prelude)
.map(|(name, _)| name)
.cloned()
.collect();
let mut loader = crate::passes::collect_intra_doc_links::IntraLinkCrateLoader::new(resolver); let (_, resolver, _) = &*abort_on_err(queries.expansion(), sess).peek();
ast::visit::walk_crate(&mut loader, krate);
loader.resolver // Before we actually clone it, let's force all the extern'd crates to
// actually be loaded, just in case they're only referred to inside
// intra-doc links
resolver.borrow_mut().access(|resolver| {
sess.time("load_extern_crates", || {
for extern_name in &extern_names {
debug!("loading extern crate {}", extern_name);
if let Err(()) = resolver
.resolve_str_path_error(
DUMMY_SP,
extern_name,
TypeNS,
LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id(),
) {
warn!("unable to resolve external crate {} (do you have an unused `--extern` crate?)", extern_name)
}
}
});
});
// Now we're good to clone the resolver because everything should be loaded
resolver.clone()
} }
crate fn run_global_ctxt( crate fn run_global_ctxt(

View File

@ -31,7 +31,6 @@ extern crate tracing;
// Dependencies listed in Cargo.toml do not need `extern crate`. // Dependencies listed in Cargo.toml do not need `extern crate`.
extern crate rustc_ast; extern crate rustc_ast;
extern crate rustc_ast_lowering;
extern crate rustc_ast_pretty; extern crate rustc_ast_pretty;
extern crate rustc_attr; extern crate rustc_attr;
extern crate rustc_data_structures; extern crate rustc_data_structures;
@ -714,6 +713,7 @@ fn main_options(options: config::Options) -> MainResult {
let default_passes = options.default_passes; let default_passes = options.default_passes;
let output_format = options.output_format; let output_format = options.output_format;
// FIXME: fix this clone (especially render_options) // FIXME: fix this clone (especially render_options)
let externs = options.externs.clone();
let manual_passes = options.manual_passes.clone(); let manual_passes = options.manual_passes.clone();
let render_options = options.render_options.clone(); let render_options = options.render_options.clone();
let config = core::create_config(options); let config = core::create_config(options);
@ -731,7 +731,7 @@ fn main_options(options: config::Options) -> MainResult {
// We need to hold on to the complete resolver, so we cause everything to be // We need to hold on to the complete resolver, so we cause everything to be
// cloned for the analysis passes to use. Suboptimal, but necessary in the // cloned for the analysis passes to use. Suboptimal, but necessary in the
// current architecture. // current architecture.
let resolver = core::create_resolver(queries, &sess); let resolver = core::create_resolver(externs, queries, &sess);
if sess.has_errors() { if sess.has_errors() {
sess.fatal("Compilation failed, aborting rustdoc"); sess.fatal("Compilation failed, aborting rustdoc");

View File

@ -37,9 +37,6 @@ use crate::html::markdown::{markdown_links, MarkdownLink};
use crate::lint::{BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS}; use crate::lint::{BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS};
use crate::passes::Pass; use crate::passes::Pass;
mod early;
crate use early::IntraLinkCrateLoader;
crate const COLLECT_INTRA_DOC_LINKS: Pass = Pass { crate const COLLECT_INTRA_DOC_LINKS: Pass = Pass {
name: "collect-intra-doc-links", name: "collect-intra-doc-links",
run: collect_intra_doc_links, run: collect_intra_doc_links,

View File

@ -1,63 +0,0 @@
use rustc_ast as ast;
use rustc_hir::def::Namespace::TypeNS;
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX};
use rustc_interface::interface;
use std::cell::RefCell;
use std::mem;
use std::rc::Rc;
// Letting the resolver escape at the end of the function leads to inconsistencies between the
// crates the TyCtxt sees and the resolver sees (because the resolver could load more crates
// after escaping). Hopefully `IntraLinkCrateLoader` gets all the crates we need ...
crate struct IntraLinkCrateLoader {
current_mod: DefId,
crate resolver: Rc<RefCell<interface::BoxedResolver>>,
}
impl IntraLinkCrateLoader {
crate fn new(resolver: Rc<RefCell<interface::BoxedResolver>>) -> Self {
let crate_id = LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id();
Self { current_mod: crate_id, resolver }
}
}
impl ast::visit::Visitor<'_> for IntraLinkCrateLoader {
fn visit_attribute(&mut self, attr: &ast::Attribute) {
use crate::html::markdown::markdown_links;
use crate::passes::collect_intra_doc_links::preprocess_link;
if let Some(doc) = attr.doc_str() {
for link in markdown_links(&doc.as_str()) {
let path_str = if let Some(Ok(x)) = preprocess_link(&link) {
x.path_str
} else {
continue;
};
self.resolver.borrow_mut().access(|resolver| {
let _ = resolver.resolve_str_path_error(
attr.span,
&path_str,
TypeNS,
self.current_mod,
);
});
}
}
ast::visit::walk_attribute(self, attr);
}
fn visit_item(&mut self, item: &ast::Item) {
use rustc_ast_lowering::ResolverAstLowering;
if let ast::ItemKind::Mod(..) = item.kind {
let new_mod =
self.resolver.borrow_mut().access(|resolver| resolver.local_def_id(item.id));
let old_mod = mem::replace(&mut self.current_mod, new_mod.to_def_id());
ast::visit::walk_item(self, item);
self.current_mod = old_mod;
} else {
ast::visit::walk_item(self, item);
}
}
}

View File

@ -30,7 +30,7 @@ crate use self::unindent_comments::UNINDENT_COMMENTS;
mod propagate_doc_cfg; mod propagate_doc_cfg;
crate use self::propagate_doc_cfg::PROPAGATE_DOC_CFG; crate use self::propagate_doc_cfg::PROPAGATE_DOC_CFG;
crate mod collect_intra_doc_links; mod collect_intra_doc_links;
crate use self::collect_intra_doc_links::COLLECT_INTRA_DOC_LINKS; crate use self::collect_intra_doc_links::COLLECT_INTRA_DOC_LINKS;
mod doc_test_lints; mod doc_test_lints;

View File

@ -1,17 +0,0 @@
// no-prefer-dynamic
#![crate_type = "lib"]
#![no_std]
#![feature(lang_items)]
use core::panic::PanicInfo;
use core::sync::atomic::{self, Ordering};
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {
atomic::compiler_fence(Ordering::SeqCst);
}
}
#[lang = "eh_personality"]
fn foo() {}

View File

@ -1,3 +0,0 @@
// check-pass
// aux-crate:panic_item=panic-item.rs
// @has unused_extern_crate/index.html

View File

@ -0,0 +1,2 @@
/// This will be referred to by the test docstring
pub struct Something;

View File

@ -0,0 +1,10 @@
// aux-crate:priv:issue_66159_1=issue-66159-1.rs
// compile-flags:-Z unstable-options
// The issue was an ICE which meant that we never actually generated the docs
// so if we have generated the docs, we're okay.
// Since we don't generate the docs for the auxiliary files, we can't actually
// verify that the struct is linked correctly.
// @has issue_66159/index.html
//! [issue_66159_1::Something]

View File

@ -1,6 +1,7 @@
#![feature(rustc_private)] #![feature(rustc_private)]
#![deny(rust_2018_idioms)] #![deny(rust_2018_idioms)]
#![warn(unreachable_pub)] #![warn(unreachable_pub)]
#![recursion_limit = "256"]
#[macro_use] #[macro_use]
extern crate derive_new; extern crate derive_new;