From 8f935fbb5b7e8ea5a320082cb9e28095aa0b5759 Mon Sep 17 00:00:00 2001 From: kennytm Date: Wed, 19 Jul 2017 16:09:22 +0800 Subject: [PATCH] Strip out function implementation when documenting. This prevents compilation failure we want to document a platform-specific module. Every function is replaced by `loop {}` using the same construct as `--unpretty everybody_loops`. Note also a workaround to #43636 is included: `const fn` will retain their bodies, since the standard library has quite a number of them. --- src/librustc_driver/pretty.rs | 62 ++++++++++++++++++----------------- src/librustdoc/core.rs | 3 ++ src/librustdoc/test.rs | 4 +++ 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 269363fdd2f98..ef6a4b2092901 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -44,6 +44,7 @@ use std::io::{self, Write}; use std::option; use std::path::Path; use std::str::FromStr; +use std::mem; use rustc::hir::map as hir_map; use rustc::hir::map::blocks; @@ -618,52 +619,53 @@ impl UserIdentifiedItem { } } -struct ReplaceBodyWithLoop { +// Note: Also used by librustdoc, see PR #43348. Consider moving this struct elsewhere. +pub struct ReplaceBodyWithLoop { within_static_or_const: bool, } impl ReplaceBodyWithLoop { - fn new() -> ReplaceBodyWithLoop { + pub fn new() -> ReplaceBodyWithLoop { ReplaceBodyWithLoop { within_static_or_const: false } } + + fn run R>(&mut self, is_const: bool, action: F) -> R { + let old_const = mem::replace(&mut self.within_static_or_const, is_const); + let ret = action(self); + self.within_static_or_const = old_const; + ret + } } impl fold::Folder for ReplaceBodyWithLoop { fn fold_item_kind(&mut self, i: ast::ItemKind) -> ast::ItemKind { - match i { - ast::ItemKind::Static(..) | - ast::ItemKind::Const(..) => { - self.within_static_or_const = true; - let ret = fold::noop_fold_item_kind(i, self); - self.within_static_or_const = false; - return ret; - } - _ => fold::noop_fold_item_kind(i, self), - } + let is_const = match i { + ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => true, + ast::ItemKind::Fn(_, _, ref constness, _, _, _) => + constness.node == ast::Constness::Const, + _ => false, + }; + self.run(is_const, |s| fold::noop_fold_item_kind(i, s)) } fn fold_trait_item(&mut self, i: ast::TraitItem) -> SmallVector { - match i.node { - ast::TraitItemKind::Const(..) => { - self.within_static_or_const = true; - let ret = fold::noop_fold_trait_item(i, self); - self.within_static_or_const = false; - return ret; - } - _ => fold::noop_fold_trait_item(i, self), - } + let is_const = match i.node { + ast::TraitItemKind::Const(..) => true, + ast::TraitItemKind::Method(ast::MethodSig { ref constness, .. }, _) => + constness.node == ast::Constness::Const, + _ => false, + }; + self.run(is_const, |s| fold::noop_fold_trait_item(i, s)) } fn fold_impl_item(&mut self, i: ast::ImplItem) -> SmallVector { - match i.node { - ast::ImplItemKind::Const(..) => { - self.within_static_or_const = true; - let ret = fold::noop_fold_impl_item(i, self); - self.within_static_or_const = false; - return ret; - } - _ => fold::noop_fold_impl_item(i, self), - } + let is_const = match i.node { + ast::ImplItemKind::Const(..) => true, + ast::ImplItemKind::Method(ast::MethodSig { ref constness, .. }, _) => + constness.node == ast::Constness::Const, + _ => false, + }; + self.run(is_const, |s| fold::noop_fold_impl_item(i, s)) } fn fold_block(&mut self, b: P) -> P { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index e101e29fc6fbb..9bb7e4e3a09d5 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -10,6 +10,7 @@ use rustc_lint; use rustc_driver::{driver, target_features, abort_on_err}; +use rustc_driver::pretty::ReplaceBodyWithLoop; use rustc::dep_graph::DepGraph; use rustc::session::{self, config}; use rustc::hir::def_id::DefId; @@ -26,6 +27,7 @@ use rustc_metadata::cstore::CStore; use syntax::{ast, codemap}; use syntax::feature_gate::UnstableFeatures; +use syntax::fold::Folder; use errors; use errors::emitter::ColorConfig; @@ -158,6 +160,7 @@ pub fn run_core(search_paths: SearchPaths, let krate = panictry!(driver::phase_1_parse_input(&driver::CompileController::basic(), &sess, &input)); + let krate = ReplaceBodyWithLoop::new().fold_crate(krate); let name = link::find_crate_name(Some(&sess), &krate.attrs, &input); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index b1e92b5190f37..8e24a3b587920 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -32,6 +32,7 @@ use rustc_back::dynamic_lib::DynamicLibrary; use rustc_back::tempdir::TempDir; use rustc_driver::{self, driver, Compilation}; use rustc_driver::driver::phase_2_configure_and_expand; +use rustc_driver::pretty::ReplaceBodyWithLoop; use rustc_metadata::cstore::CStore; use rustc_resolve::MakeGlobMap; use rustc_trans; @@ -39,6 +40,7 @@ use rustc_trans::back::link; use syntax::ast; use syntax::codemap::CodeMap; use syntax::feature_gate::UnstableFeatures; +use syntax::fold::Folder; use syntax_pos::{BytePos, DUMMY_SP, Pos, Span}; use errors; use errors::emitter::ColorConfig; @@ -72,6 +74,7 @@ pub fn run(input: &str, crate_types: vec![config::CrateTypeDylib], externs: externs.clone(), unstable_features: UnstableFeatures::from_environment(), + lint_cap: Some(::rustc::lint::Level::Allow), actually_rustdoc: true, ..config::basic_options().clone() }; @@ -94,6 +97,7 @@ pub fn run(input: &str, let krate = panictry!(driver::phase_1_parse_input(&driver::CompileController::basic(), &sess, &input)); + let krate = ReplaceBodyWithLoop::new().fold_crate(krate); let driver::ExpansionResult { defs, mut hir_forest, .. } = { phase_2_configure_and_expand( &sess, &cstore, krate, None, "rustdoc-test", None, MakeGlobMap::No, |_| Ok(())