mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 11:48:30 +00:00
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 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;
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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)]
|
||||||
|
@ -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")]
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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(
|
||||||
|
@ -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");
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
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;
|
||||||
|
@ -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)]
|
#![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;
|
||||||
|
Loading…
Reference in New Issue
Block a user