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:
commit
ce331ee6ee
@ -3,9 +3,11 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{CrateNum, DefId};
|
||||
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
|
||||
use rustc_middle::ty::layout::IntegerExt;
|
||||
use rustc_middle::ty::print::{Print, Printer};
|
||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
|
||||
use rustc_middle::ty::{self, FloatTy, Instance, IntTy, Ty, TyCtxt, TypeFoldable, UintTy};
|
||||
use rustc_target::abi::Integer;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use std::fmt::Write;
|
||||
@ -553,11 +555,9 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
|
||||
ty::Uint(_) | ty::Bool | ty::Char => {
|
||||
ct.try_eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty)
|
||||
}
|
||||
ty::Int(_) => {
|
||||
let param_env = ty::ParamEnv::reveal_all();
|
||||
ct.try_eval_bits(self.tcx, param_env, ct.ty).and_then(|b| {
|
||||
let sz = self.tcx.layout_of(param_env.and(ct.ty)).ok()?.size;
|
||||
let val = sz.sign_extend(b) as i128;
|
||||
ty::Int(ity) => {
|
||||
ct.try_eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty).and_then(|b| {
|
||||
let val = Integer::from_int_ty(&self.tcx, *ity).size().sign_extend(b) as i128;
|
||||
if val < 0 {
|
||||
neg = true;
|
||||
}
|
||||
|
@ -1243,6 +1243,20 @@ impl<'a, T> Cursor<'a, T> {
|
||||
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> {
|
||||
@ -1506,6 +1520,135 @@ impl<'a, T> CursorMut<'a, T> {
|
||||
self.index = 0;
|
||||
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.
|
||||
|
@ -428,3 +428,50 @@ fn test_cursor_mut_insert() {
|
||||
check_links(&m);
|
||||
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);
|
||||
}
|
||||
|
@ -737,14 +737,13 @@ impl<T: Clone> Bound<&T> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(bound_cloned)]
|
||||
/// use std::ops::Bound::*;
|
||||
/// use std::ops::RangeBounds;
|
||||
///
|
||||
/// assert_eq!((1..12).start_bound(), 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> {
|
||||
match self {
|
||||
Bound::Unbounded => Bound::Unbounded,
|
||||
|
@ -4,7 +4,6 @@
|
||||
#![feature(array_map)]
|
||||
#![feature(array_windows)]
|
||||
#![feature(bool_to_option)]
|
||||
#![feature(bound_cloned)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(cell_update)]
|
||||
#![feature(cfg_panic)]
|
||||
|
@ -31,7 +31,6 @@
|
||||
#![feature(restricted_std)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(bound_cloned)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
#[unstable(feature = "proc_macro_internals", issue = "27812")]
|
||||
|
@ -465,6 +465,7 @@ impl<'a> Builder<'a> {
|
||||
doc::Std,
|
||||
doc::Rustc,
|
||||
doc::Rustdoc,
|
||||
doc::Rustfmt,
|
||||
doc::ErrorIndex,
|
||||
doc::Nomicon,
|
||||
doc::Reference,
|
||||
|
@ -593,84 +593,97 @@ impl Step for Rustc {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Rustdoc {
|
||||
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;
|
||||
macro_rules! tool_doc {
|
||||
($tool: ident, $should_run: literal, $path: literal, [$($krate: literal),+ $(,)?] $(, binary=$bin:expr)?) => {
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct $tool {
|
||||
stage: u32,
|
||||
target: TargetSelection,
|
||||
}
|
||||
|
||||
// Build rustc docs so that we generate relative links.
|
||||
builder.ensure(Rustc { stage, target });
|
||||
impl Step for $tool {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
// Build rustdoc.
|
||||
builder.ensure(tool::Rustdoc { compiler });
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
run.krate($should_run)
|
||||
}
|
||||
|
||||
// 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));
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
run.builder.ensure($tool { stage: run.builder.top_stage, target: run.target });
|
||||
}
|
||||
|
||||
// Build cargo command.
|
||||
let mut cargo = prepare_tool_cargo(
|
||||
builder,
|
||||
compiler,
|
||||
Mode::ToolRustc,
|
||||
target,
|
||||
"doc",
|
||||
"src/tools/rustdoc",
|
||||
SourceType::InTree,
|
||||
&[],
|
||||
);
|
||||
/// 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{} {} ({})", stage, stringify!($tool).to_lowercase(), target));
|
||||
|
||||
cargo.arg("-Zskip-rustdoc-fingerprint");
|
||||
// Only include compiler crates, no dependencies of those, such as `libc`.
|
||||
cargo.arg("--no-deps");
|
||||
cargo.arg("-p").arg("rustdoc");
|
||||
cargo.arg("-p").arg("rustdoc-json-types");
|
||||
// This is the intended out directory for compiler documentation.
|
||||
let out = builder.compiler_doc_out(target);
|
||||
t!(fs::create_dir_all(&out));
|
||||
|
||||
cargo.rustdocflag("--document-private-items");
|
||||
cargo.rustdocflag("--enable-index-page");
|
||||
cargo.rustdocflag("--show-type-layout");
|
||||
cargo.rustdocflag("-Zunstable-options");
|
||||
builder.run(&mut cargo.into());
|
||||
let compiler = builder.compiler(stage, builder.config.build);
|
||||
|
||||
if !builder.config.compiler_docs {
|
||||
builder.info("\tskipping - compiler/tool docs disabled");
|
||||
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)]
|
||||
pub struct ErrorIndex {
|
||||
pub target: TargetSelection,
|
||||
|
@ -1,12 +1,12 @@
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::sync::{self, Lrc};
|
||||
use rustc_driver::abort_on_err;
|
||||
use rustc_errors::emitter::{Emitter, EmitterWriter};
|
||||
use rustc_errors::json::JsonEmitter;
|
||||
use rustc_feature::UnstableFeatures;
|
||||
use rustc_hir::def::Namespace::TypeNS;
|
||||
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::{
|
||||
intravisit::{self, NestedVisitorMap, Visitor},
|
||||
@ -23,7 +23,7 @@ use rustc_session::DiagnosticOutput;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::source_map;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::mem;
|
||||
@ -300,16 +300,41 @@ crate fn create_config(
|
||||
}
|
||||
|
||||
crate fn create_resolver<'a>(
|
||||
externs: config::Externs,
|
||||
queries: &Queries<'a>,
|
||||
sess: &Session,
|
||||
) -> Rc<RefCell<interface::BoxedResolver>> {
|
||||
let (krate, resolver, _) = &*abort_on_err(queries.expansion(), sess).peek();
|
||||
let resolver = resolver.clone();
|
||||
let extern_names: Vec<String> = externs
|
||||
.iter()
|
||||
.filter(|(_, entry)| entry.add_prelude)
|
||||
.map(|(name, _)| name)
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
let mut loader = crate::passes::collect_intra_doc_links::IntraLinkCrateLoader::new(resolver);
|
||||
ast::visit::walk_crate(&mut loader, krate);
|
||||
let (_, resolver, _) = &*abort_on_err(queries.expansion(), sess).peek();
|
||||
|
||||
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(
|
||||
|
@ -31,7 +31,6 @@ extern crate tracing;
|
||||
// Dependencies listed in Cargo.toml do not need `extern crate`.
|
||||
|
||||
extern crate rustc_ast;
|
||||
extern crate rustc_ast_lowering;
|
||||
extern crate rustc_ast_pretty;
|
||||
extern crate rustc_attr;
|
||||
extern crate rustc_data_structures;
|
||||
@ -714,6 +713,7 @@ fn main_options(options: config::Options) -> MainResult {
|
||||
let default_passes = options.default_passes;
|
||||
let output_format = options.output_format;
|
||||
// FIXME: fix this clone (especially render_options)
|
||||
let externs = options.externs.clone();
|
||||
let manual_passes = options.manual_passes.clone();
|
||||
let render_options = options.render_options.clone();
|
||||
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
|
||||
// cloned for the analysis passes to use. Suboptimal, but necessary in the
|
||||
// current architecture.
|
||||
let resolver = core::create_resolver(queries, &sess);
|
||||
let resolver = core::create_resolver(externs, queries, &sess);
|
||||
|
||||
if sess.has_errors() {
|
||||
sess.fatal("Compilation failed, aborting rustdoc");
|
||||
|
@ -37,9 +37,6 @@ use crate::html::markdown::{markdown_links, MarkdownLink};
|
||||
use crate::lint::{BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS};
|
||||
use crate::passes::Pass;
|
||||
|
||||
mod early;
|
||||
crate use early::IntraLinkCrateLoader;
|
||||
|
||||
crate const COLLECT_INTRA_DOC_LINKS: Pass = Pass {
|
||||
name: "collect-intra-doc-links",
|
||||
run: collect_intra_doc_links,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -30,7 +30,7 @@ crate use self::unindent_comments::UNINDENT_COMMENTS;
|
||||
mod 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;
|
||||
|
||||
mod doc_test_lints;
|
||||
|
@ -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() {}
|
@ -1,3 +0,0 @@
|
||||
// check-pass
|
||||
// aux-crate:panic_item=panic-item.rs
|
||||
// @has unused_extern_crate/index.html
|
2
src/test/rustdoc/auxiliary/issue-66159-1.rs
Normal file
2
src/test/rustdoc/auxiliary/issue-66159-1.rs
Normal file
@ -0,0 +1,2 @@
|
||||
/// This will be referred to by the test docstring
|
||||
pub struct Something;
|
10
src/test/rustdoc/issue-66159.rs
Normal file
10
src/test/rustdoc/issue-66159.rs
Normal 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]
|
@ -1,6 +1,7 @@
|
||||
#![feature(rustc_private)]
|
||||
#![deny(rust_2018_idioms)]
|
||||
#![warn(unreachable_pub)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
#[macro_use]
|
||||
extern crate derive_new;
|
||||
|
Loading…
x
Reference in New Issue
Block a user