From a981be75cc45d0640acf1c86fc17166e8bdf953e Mon Sep 17 00:00:00 2001 From: Ian Wahbe Date: Tue, 29 Jun 2021 15:24:01 +0200 Subject: [PATCH 1/8] add head/tail methods to linked list mutable cursor --- library/alloc/src/collections/linked_list.rs | 122 ++++++++++++++++++ .../src/collections/linked_list/tests.rs | 32 +++++ 2 files changed, 154 insertions(+) diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index 1a58ad51f78..a21eedf02f1 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -1506,6 +1506,128 @@ 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); + } + + /// 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 { + // 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, which is expected. + if self.list.head == self.current { + self.move_next(); + } + // We always need to change the index since `head` comes before any + // other element. + self.index.checked_sub(1).unwrap_or(0); + 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 new back element. + /// + /// This operation should compute in O(1) time. + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn pop_back(&mut self) -> Option { + if self.list.is_empty() { + None + } else { + if self.list.tail == self.current { + self.move_prev() + } + // We don't need to change the index since `current` points to a + // node before `tail`. + 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. diff --git a/library/alloc/src/collections/linked_list/tests.rs b/library/alloc/src/collections/linked_list/tests.rs index ad643a7bdf1..429685260fd 100644 --- a/library/alloc/src/collections/linked_list/tests.rs +++ b/library/alloc/src/collections/linked_list/tests.rs @@ -428,3 +428,35 @@ fn test_cursor_mut_insert() { check_links(&m); assert_eq!(m.iter().cloned().collect::>(), &[200, 201, 202, 203, 1, 100, 101]); } + +#[test] +fn test_cursor_push_front_back() { + let mut ll: LinkedList = 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); + assert_eq!(ll, (0..12).collect()); + check_links(&ll); +} + +#[test] +fn test_cursor_pop_front_back() { + let mut ll: LinkedList = 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)); + drop(c); + assert_eq!(ll, (2..6).collect()); + check_links(&ll); +} From e77acf7d27f7690f6cdb18d2ce68a37cbabd884c Mon Sep 17 00:00:00 2001 From: Ian Wahbe Date: Tue, 29 Jun 2021 15:35:14 +0200 Subject: [PATCH 2/8] Add non-mutable methods to `Cursor` --- library/alloc/src/collections/linked_list.rs | 14 ++++++++++++++ library/alloc/src/collections/linked_list/tests.rs | 3 +++ 2 files changed, 17 insertions(+) diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index a21eedf02f1..4eecf5703a4 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -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<&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<&T> { + self.list.back() + } } impl<'a, T> CursorMut<'a, T> { diff --git a/library/alloc/src/collections/linked_list/tests.rs b/library/alloc/src/collections/linked_list/tests.rs index 429685260fd..45349a7df12 100644 --- a/library/alloc/src/collections/linked_list/tests.rs +++ b/library/alloc/src/collections/linked_list/tests.rs @@ -456,6 +456,9 @@ fn test_cursor_pop_front_back() { 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)); drop(c); assert_eq!(ll, (2..6).collect()); check_links(&ll); From 81f3ab6bca611ce2661f622fd5bf11b684169e7a Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 29 Jun 2021 23:05:02 -0400 Subject: [PATCH 3/8] Use a macro for documenting rustdoc --- src/bootstrap/builder.rs | 1 + src/bootstrap/doc.rs | 143 ++++++++++++++++++++------------------- 2 files changed, 76 insertions(+), 68 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index b4c5a2abc9c..38705a56484 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -465,6 +465,7 @@ impl<'a> Builder<'a> { doc::Std, doc::Rustc, doc::Rustdoc, + // doc::Rustfmt, doc::ErrorIndex, doc::Nomicon, doc::Reference, diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 634332df863..7ba2ff073cd 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -593,84 +593,91 @@ 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),+ $(,)?]) => { + #[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 }); + + // Build the tool. + builder.ensure(tool::$tool { compiler }); + + // 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); + )+ + + 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"]); + #[derive(Ord, PartialOrd, Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct ErrorIndex { pub target: TargetSelection, From c99f1b9b7e67f96b51d873bd3ce2c09df0b34ef2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 1 Jul 2021 00:00:00 +0000 Subject: [PATCH 4/8] Skip layout query when computing integer type size during mangling --- compiler/rustc_symbol_mangling/src/v0.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 828f1ac0a79..1a9d04a75ec 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -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; } From 5f0c54db4e595a6a77048f2b0605138ffa49a326 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 27 May 2021 16:06:30 +0200 Subject: [PATCH 5/8] Revert "Don't load all extern crates unconditionally" --- src/librustdoc/core.rs | 41 +++++++++--- src/librustdoc/lib.rs | 4 +- .../passes/collect_intra_doc_links.rs | 3 - .../passes/collect_intra_doc_links/early.rs | 63 ------------------- src/librustdoc/passes/mod.rs | 2 +- src/test/rustdoc-ui/auxiliary/panic-item.rs | 17 ----- src/test/rustdoc-ui/unused-extern-crate.rs | 3 - src/test/rustdoc/auxiliary/issue-66159-1.rs | 2 + src/test/rustdoc/issue-66159.rs | 10 +++ 9 files changed, 48 insertions(+), 97 deletions(-) delete mode 100644 src/librustdoc/passes/collect_intra_doc_links/early.rs delete mode 100644 src/test/rustdoc-ui/auxiliary/panic-item.rs delete mode 100644 src/test/rustdoc-ui/unused-extern-crate.rs create mode 100644 src/test/rustdoc/auxiliary/issue-66159-1.rs create mode 100644 src/test/rustdoc/issue-66159.rs diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 71fcde8bca8..66f4f481292 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -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> { - let (krate, resolver, _) = &*abort_on_err(queries.expansion(), sess).peek(); - let resolver = resolver.clone(); + let extern_names: Vec = 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( diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index ee7a716655b..64a9905b33f 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -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"); diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index c7e2ce74019..1113d610128 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -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, diff --git a/src/librustdoc/passes/collect_intra_doc_links/early.rs b/src/librustdoc/passes/collect_intra_doc_links/early.rs deleted file mode 100644 index 7cba2523d1a..00000000000 --- a/src/librustdoc/passes/collect_intra_doc_links/early.rs +++ /dev/null @@ -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>, -} - -impl IntraLinkCrateLoader { - crate fn new(resolver: Rc>) -> 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); - } - } -} diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 0e86fe45640..390ab1694a0 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -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; diff --git a/src/test/rustdoc-ui/auxiliary/panic-item.rs b/src/test/rustdoc-ui/auxiliary/panic-item.rs deleted file mode 100644 index 17b26850d4d..00000000000 --- a/src/test/rustdoc-ui/auxiliary/panic-item.rs +++ /dev/null @@ -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() {} diff --git a/src/test/rustdoc-ui/unused-extern-crate.rs b/src/test/rustdoc-ui/unused-extern-crate.rs deleted file mode 100644 index f703a183790..00000000000 --- a/src/test/rustdoc-ui/unused-extern-crate.rs +++ /dev/null @@ -1,3 +0,0 @@ -// check-pass -// aux-crate:panic_item=panic-item.rs -// @has unused_extern_crate/index.html diff --git a/src/test/rustdoc/auxiliary/issue-66159-1.rs b/src/test/rustdoc/auxiliary/issue-66159-1.rs new file mode 100644 index 00000000000..2f3d069bd51 --- /dev/null +++ b/src/test/rustdoc/auxiliary/issue-66159-1.rs @@ -0,0 +1,2 @@ +/// This will be referred to by the test docstring +pub struct Something; diff --git a/src/test/rustdoc/issue-66159.rs b/src/test/rustdoc/issue-66159.rs new file mode 100644 index 00000000000..003d079a470 --- /dev/null +++ b/src/test/rustdoc/issue-66159.rs @@ -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] From c4ad273fe168cba92a298e35826b37f7177ce599 Mon Sep 17 00:00:00 2001 From: Ian Wahbe Date: Thu, 1 Jul 2021 21:08:01 +0200 Subject: [PATCH 6/8] Implement changes suggested by @Amanieu --- library/alloc/src/collections/linked_list.rs | 27 ++++++++++++------- .../src/collections/linked_list/tests.rs | 12 +++++++++ 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index 4eecf5703a4..ea216786ea2 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -1247,14 +1247,14 @@ impl<'a, T> Cursor<'a, T> { /// 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> { + 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<&T> { + pub fn back(&self) -> Option<&'a T> { self.list.back() } } @@ -1546,6 +1546,11 @@ impl<'a, T> CursorMut<'a, T> { // 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, @@ -1565,13 +1570,12 @@ impl<'a, T> CursorMut<'a, T> { // 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, which is expected. + // node at index 0, which is expected. if self.list.head == self.current { self.move_next(); + } else { + self.index -= 1; } - // We always need to change the index since `head` comes before any - // other element. - self.index.checked_sub(1).unwrap_or(0); self.list.pop_front() } } @@ -1579,7 +1583,7 @@ impl<'a, T> CursorMut<'a, T> { /// 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 new back element. + /// points to the "ghost" element. /// /// This operation should compute in O(1) time. #[unstable(feature = "linked_list_cursors", issue = "58533")] @@ -1588,10 +1592,13 @@ impl<'a, T> CursorMut<'a, T> { None } else { if self.list.tail == self.current { - self.move_prev() + // 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; } - // We don't need to change the index since `current` points to a - // node before `tail`. self.list.pop_back() } } diff --git a/library/alloc/src/collections/linked_list/tests.rs b/library/alloc/src/collections/linked_list/tests.rs index 45349a7df12..5a65ed7a962 100644 --- a/library/alloc/src/collections/linked_list/tests.rs +++ b/library/alloc/src/collections/linked_list/tests.rs @@ -442,6 +442,8 @@ fn test_cursor_push_front_back() { 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); } @@ -459,7 +461,17 @@ fn test_cursor_pop_front_back() { 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); } From 01cf0bde2773dc915fbe751d809cc46b873f71a1 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 30 Jun 2021 00:13:34 -0400 Subject: [PATCH 7/8] Document rustfmt on nightly-rustc The recursion_limit attribute avoids the following error: ``` error[E0275]: overflow evaluating the requirement `std::ptr::Unique: std::marker::Send` | = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`rustfmt_nightly`) ``` --- src/bootstrap/builder.rs | 2 +- src/bootstrap/doc.rs | 16 +++++++++++----- src/tools/rustfmt/src/lib.rs | 1 + 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 38705a56484..56ecc6e68a9 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -465,7 +465,7 @@ impl<'a> Builder<'a> { doc::Std, doc::Rustc, doc::Rustdoc, - // doc::Rustfmt, + doc::Rustfmt, doc::ErrorIndex, doc::Nomicon, doc::Reference, diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 7ba2ff073cd..8603361362c 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -594,7 +594,7 @@ impl Step for Rustc { } macro_rules! tool_doc { - ($tool: ident, $should_run: literal, $path: literal, [$($krate: literal),+ $(,)?]) => { + ($tool: ident, $should_run: literal, $path: literal, [$($krate: literal),+ $(,)?] $(, binary=$bin:expr)?) => { #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct $tool { stage: u32, @@ -639,9 +639,6 @@ macro_rules! tool_doc { // Build rustc docs so that we generate relative links. builder.ensure(Rustc { stage, target }); - // Build the tool. - builder.ensure(tool::$tool { compiler }); - // 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)); @@ -666,7 +663,9 @@ macro_rules! tool_doc { cargo.arg("-p").arg($krate); )+ - cargo.rustdocflag("--document-private-items"); + $(if !$bin { + cargo.rustdocflag("--document-private-items"); + })? cargo.rustdocflag("--enable-index-page"); cargo.rustdocflag("--show-type-layout"); cargo.rustdocflag("-Zunstable-options"); @@ -677,6 +676,13 @@ macro_rules! tool_doc { } 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 { diff --git a/src/tools/rustfmt/src/lib.rs b/src/tools/rustfmt/src/lib.rs index cde5d390cf2..ce8a45eea65 100644 --- a/src/tools/rustfmt/src/lib.rs +++ b/src/tools/rustfmt/src/lib.rs @@ -1,6 +1,7 @@ #![feature(rustc_private)] #![deny(rust_2018_idioms)] #![warn(unreachable_pub)] +#![recursion_limit = "256"] #[macro_use] extern crate derive_new; From f2b21e2d0b66c58ec2eb2e23c792e12b214c3be2 Mon Sep 17 00:00:00 2001 From: Aris Merchant <22333129+inquisitivecrystal@users.noreply.github.com> Date: Thu, 1 Jul 2021 17:05:08 -0700 Subject: [PATCH 8/8] Stabilize `Bound::cloned()` --- library/core/src/ops/range.rs | 3 +-- library/core/tests/lib.rs | 1 - library/proc_macro/src/lib.rs | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs index bb948376bc7..9bf0382312e 100644 --- a/library/core/src/ops/range.rs +++ b/library/core/src/ops/range.rs @@ -737,14 +737,13 @@ impl 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 { match self { Bound::Unbounded => Bound::Unbounded, diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 56af3848584..dee2478886d 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -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)] diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 7586229504c..9b155db6d7b 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -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")]