Skip to content

Commit

Permalink
Strip out function implementation when documenting.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kennytm committed Aug 10, 2017
1 parent 57e720d commit 8f935fb
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 30 deletions.
62 changes: 32 additions & 30 deletions src/librustc_driver/pretty.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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, F: FnOnce(&mut Self) -> 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<ast::TraitItem> {
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<ast::ImplItem> {
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<ast::Block>) -> P<ast::Block> {
Expand Down
3 changes: 3 additions & 0 deletions src/librustdoc/core.rs
Expand Up @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -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);

Expand Down
4 changes: 4 additions & 0 deletions src/librustdoc/test.rs
Expand Up @@ -32,13 +32,15 @@ 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;
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;
Expand Down Expand Up @@ -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()
};
Expand All @@ -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(())
Expand Down

0 comments on commit 8f935fb

Please sign in to comment.