about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustdoc/core.rs77
-rw-r--r--src/librustdoc/html/render.rs91
-rw-r--r--src/librustdoc/lib.rs62
-rw-r--r--src/librustdoc/markdown.rs51
-rw-r--r--src/librustdoc/test.rs59
5 files changed, 136 insertions, 204 deletions
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index d6b0127e44d..0bd6f6bf8a2 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -28,7 +28,6 @@ use rustc_target::spec::TargetTriple;
 
 use syntax::ast::{self, Ident, NodeId};
 use syntax::source_map;
-use syntax::edition::Edition;
 use syntax::feature_gate::UnstableFeatures;
 use syntax::json::JsonEmitter;
 use syntax::ptr::P;
@@ -43,9 +42,9 @@ use std::mem;
 use rustc_data_structures::sync::{self, Lrc};
 use std::rc::Rc;
 use std::sync::Arc;
-use std::path::PathBuf;
 
 use visit_ast::RustdocVisitor;
+use config::{Options as RustdocOptions, RenderOptions};
 use clean;
 use clean::{get_path_for_type, Clean, MAX_DEF_ID, AttributesExt};
 use html::render::RenderInfo;
@@ -320,32 +319,33 @@ pub fn new_handler(error_format: ErrorOutputType,
     )
 }
 
-pub fn run_core(search_paths: SearchPaths,
-                cfgs: Vec<String>,
-                externs: config::Externs,
-                input: Input,
-                triple: Option<TargetTriple>,
-                maybe_sysroot: Option<PathBuf>,
-                allow_warnings: bool,
-                crate_name: Option<String>,
-                force_unstable_if_unmarked: bool,
-                edition: Edition,
-                cg: CodegenOptions,
-                error_format: ErrorOutputType,
-                cmd_lints: Vec<(String, lint::Level)>,
-                lint_cap: Option<lint::Level>,
-                describe_lints: bool,
-                mut manual_passes: Vec<String>,
-                mut default_passes: passes::DefaultPassOption,
-                treat_err_as_bug: bool,
-                ui_testing: bool,
-) -> (clean::Crate, RenderInfo, Vec<String>) {
+pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOptions, Vec<String>) {
     // Parse, resolve, and typecheck the given crate.
 
-    let cpath = match input {
-        Input::File(ref p) => Some(p.clone()),
-        _ => None
-    };
+    let RustdocOptions {
+        input,
+        crate_name,
+        error_format,
+        libs,
+        externs,
+        cfgs,
+        codegen_options,
+        debugging_options,
+        target,
+        edition,
+        maybe_sysroot,
+        lint_opts,
+        describe_lints,
+        lint_cap,
+        mut default_passes,
+        mut manual_passes,
+        display_warnings,
+        render_options,
+        ..
+    } = options;
+
+    let cpath = Some(input.clone());
+    let input = Input::File(input);
 
     let intra_link_resolution_failure_name = lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE.name;
     let warnings_lint_name = lint::builtin::WARNINGS.name;
@@ -359,7 +359,7 @@ pub fn run_core(search_paths: SearchPaths,
                                      missing_docs.to_owned(),
                                      missing_doc_example.to_owned()];
 
-    whitelisted_lints.extend(cmd_lints.iter().map(|(lint, _)| lint).cloned());
+    whitelisted_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned());
 
     let lints = lint::builtin::HardwiredLints.get_lints()
                     .into_iter()
@@ -372,33 +372,28 @@ pub fn run_core(search_paths: SearchPaths,
                             Some((lint.name_lower(), lint::Allow))
                         }
                     })
-                    .chain(cmd_lints.into_iter())
+                    .chain(lint_opts.into_iter())
                     .collect::<Vec<_>>();
 
     let host_triple = TargetTriple::from_triple(config::host_triple());
     // plays with error output here!
     let sessopts = config::Options {
         maybe_sysroot,
-        search_paths,
+        search_paths: libs,
         crate_types: vec![config::CrateType::Rlib],
-        lint_opts: if !allow_warnings {
+        lint_opts: if !display_warnings {
             lints
         } else {
             vec![]
         },
         lint_cap: Some(lint_cap.unwrap_or_else(|| lint::Forbid)),
-        cg,
+        cg: codegen_options,
         externs,
-        target_triple: triple.unwrap_or(host_triple),
+        target_triple: target.unwrap_or(host_triple),
         // Ensure that rustdoc works even if rustc is feature-staged
         unstable_features: UnstableFeatures::Allow,
         actually_rustdoc: true,
-        debugging_opts: config::DebuggingOptions {
-            force_unstable_if_unmarked,
-            treat_err_as_bug,
-            ui_testing,
-            ..config::basic_debugging_options()
-        },
+        debugging_opts: debugging_options.clone(),
         error_format,
         edition,
         describe_lints,
@@ -408,8 +403,8 @@ pub fn run_core(search_paths: SearchPaths,
         let source_map = Lrc::new(source_map::SourceMap::new(sessopts.file_path_mapping()));
         let diagnostic_handler = new_handler(error_format,
                                              Some(source_map.clone()),
-                                             treat_err_as_bug,
-                                             ui_testing);
+                                             debugging_options.treat_err_as_bug,
+                                             debugging_options.ui_testing);
 
         let mut sess = session::build_session_(
             sessopts, cpath, diagnostic_handler, source_map,
@@ -621,7 +616,7 @@ pub fn run_core(search_paths: SearchPaths,
 
             ctxt.sess().abort_if_errors();
 
-            (krate, ctxt.renderinfo.into_inner(), passes)
+            (krate, ctxt.renderinfo.into_inner(), render_options, passes)
         }), &sess)
     })
 }
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 9b3c82b68dc..14512e8adf5 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -52,10 +52,7 @@ use std::str;
 use std::sync::Arc;
 use std::rc::Rc;
 
-use externalfiles::ExternalHtml;
-
 use errors;
-
 use serialize::json::{ToJson, Json, as_json};
 use syntax::ast;
 use syntax::ext::base::MacroKind;
@@ -69,7 +66,7 @@ use rustc::util::nodemap::{FxHashMap, FxHashSet};
 use rustc_data_structures::flock;
 
 use clean::{self, AttributesExt, GetDefId, SelfTy, Mutability};
-use config;
+use config::RenderOptions;
 use doctree;
 use fold::DocFolder;
 use html::escape::Escape;
@@ -109,8 +106,6 @@ struct Context {
     /// The map used to ensure all generated 'id=' attributes are unique.
     id_map: Rc<RefCell<IdMap>>,
     pub shared: Arc<SharedContext>,
-    pub enable_index_page: bool,
-    pub index_page: Option<PathBuf>,
 }
 
 struct SharedContext {
@@ -495,23 +490,25 @@ pub fn initial_ids() -> Vec<String> {
 
 /// Generates the documentation for `crate` into the directory `dst`
 pub fn run(mut krate: clean::Crate,
-           extern_urls: BTreeMap<String, String>,
-           external_html: &ExternalHtml,
-           playground_url: Option<String>,
-           dst: PathBuf,
-           resource_suffix: String,
+           options: RenderOptions,
            passes: FxHashSet<String>,
-           css_file_extension: Option<PathBuf>,
            renderinfo: RenderInfo,
-           sort_modules_alphabetically: bool,
-           themes: Vec<PathBuf>,
-           enable_minification: bool,
-           id_map: IdMap,
-           enable_index_page: bool,
-           index_page: Option<PathBuf>,
-           options: config::RenderOptions,
-           diag: &errors::Handler,
-) -> Result<(), Error> {
+           diag: &errors::Handler) -> Result<(), Error> {
+    // need to save a copy of the options for rendering the index page
+    let md_opts = options.clone();
+    let RenderOptions {
+        output,
+        external_html,
+        id_map,
+        playground_url,
+        sort_modules_alphabetically,
+        themes,
+        extension_css,
+        extern_html_root_urls,
+        resource_suffix,
+        ..
+    } = options;
+
     let src_root = match krate.src {
         FileName::Real(ref p) => match p.parent() {
             Some(p) => p.to_path_buf(),
@@ -528,10 +525,10 @@ pub fn run(mut krate: clean::Crate,
         layout: layout::Layout {
             logo: String::new(),
             favicon: String::new(),
-            external_html: external_html.clone(),
+            external_html,
             krate: krate.name.clone(),
         },
-        css_file_extension,
+        css_file_extension: extension_css,
         created_dirs: Default::default(),
         sort_modules_alphabetically,
         themes,
@@ -573,6 +570,7 @@ pub fn run(mut krate: clean::Crate,
             }
         }
     }
+    let dst = output;
     try_err!(fs::create_dir_all(&dst), &dst);
     krate = render_sources(&dst, &mut scx, krate)?;
     let cx = Context {
@@ -582,8 +580,6 @@ pub fn run(mut krate: clean::Crate,
         codes: ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()),
         id_map: Rc::new(RefCell::new(id_map)),
         shared: Arc::new(scx),
-        enable_index_page,
-        index_page,
     };
 
     // Crawl the crate to build various caches used for the output
@@ -637,7 +633,7 @@ pub fn run(mut krate: clean::Crate,
             },
             _ => PathBuf::new(),
         };
-        let extern_url = extern_urls.get(&e.name).map(|u| &**u);
+        let extern_url = extern_html_root_urls.get(&e.name).map(|u| &**u);
         cache.extern_locations.insert(n, (e.name.clone(), src_root,
                                           extern_location(e, extern_url, &cx.dst)));
 
@@ -678,7 +674,7 @@ pub fn run(mut krate: clean::Crate,
     CACHE_KEY.with(|v| *v.borrow_mut() = cache.clone());
     CURRENT_LOCATION_KEY.with(|s| s.borrow_mut().clear());
 
-    write_shared(&cx, &krate, &*cache, index, enable_minification, &options, diag)?;
+    write_shared(&cx, &krate, &*cache, index, &md_opts, diag)?;
 
     // And finally render the whole crate's documentation
     cx.krate(krate)
@@ -759,8 +755,7 @@ fn write_shared(
     krate: &clean::Crate,
     cache: &Cache,
     search_index: String,
-    enable_minification: bool,
-    options: &config::RenderOptions,
+    options: &RenderOptions,
     diag: &errors::Handler,
 ) -> Result<(), Error> {
     // Write out the shared files. Note that these are shared among all rustdoc
@@ -773,10 +768,10 @@ fn write_shared(
 
     write_minify(cx.dst.join(&format!("rustdoc{}.css", cx.shared.resource_suffix)),
                  include_str!("static/rustdoc.css"),
-                 enable_minification)?;
+                 options.enable_minification)?;
     write_minify(cx.dst.join(&format!("settings{}.css", cx.shared.resource_suffix)),
                  include_str!("static/settings.css"),
-                 enable_minification)?;
+                 options.enable_minification)?;
 
     // To avoid "light.css" to be overwritten, we'll first run over the received themes and only
     // then we'll run over the "official" styles.
@@ -800,11 +795,11 @@ fn write_shared(
           include_bytes!("static/wheel.svg"))?;
     write_minify(cx.dst.join(&format!("light{}.css", cx.shared.resource_suffix)),
                  include_str!("static/themes/light.css"),
-                 enable_minification)?;
+                 options.enable_minification)?;
     themes.insert("light".to_owned());
     write_minify(cx.dst.join(&format!("dark{}.css", cx.shared.resource_suffix)),
                  include_str!("static/themes/dark.css"),
-                 enable_minification)?;
+                 options.enable_minification)?;
     themes.insert("dark".to_owned());
 
     let mut themes: Vec<&String> = themes.iter().collect();
@@ -860,10 +855,10 @@ themePicker.onblur = handleThemeButtonsBlur;
 
     write_minify(cx.dst.join(&format!("main{}.js", cx.shared.resource_suffix)),
                  include_str!("static/main.js"),
-                 enable_minification)?;
+                 options.enable_minification)?;
     write_minify(cx.dst.join(&format!("settings{}.js", cx.shared.resource_suffix)),
                  include_str!("static/settings.js"),
-                 enable_minification)?;
+                 options.enable_minification)?;
 
     {
         let mut data = format!("var resourcesSuffix = \"{}\";\n",
@@ -871,24 +866,24 @@ themePicker.onblur = handleThemeButtonsBlur;
         data.push_str(include_str!("static/storage.js"));
         write_minify(cx.dst.join(&format!("storage{}.js", cx.shared.resource_suffix)),
                      &data,
-                     enable_minification)?;
+                     options.enable_minification)?;
     }
 
     if let Some(ref css) = cx.shared.css_file_extension {
         let out = cx.dst.join(&format!("theme{}.css", cx.shared.resource_suffix));
-        if !enable_minification {
+        if !options.enable_minification {
             try_err!(fs::copy(css, out), css);
         } else {
             let mut f = try_err!(File::open(css), css);
             let mut buffer = String::with_capacity(1000);
 
             try_err!(f.read_to_string(&mut buffer), css);
-            write_minify(out, &buffer, enable_minification)?;
+            write_minify(out, &buffer, options.enable_minification)?;
         }
     }
     write_minify(cx.dst.join(&format!("normalize{}.css", cx.shared.resource_suffix)),
                  include_str!("static/normalize.css"),
-                 enable_minification)?;
+                 options.enable_minification)?;
     write(cx.dst.join("FiraSans-Regular.woff"),
           include_bytes!("static/FiraSans-Regular.woff"))?;
     write(cx.dst.join("FiraSans-Medium.woff"),
@@ -984,21 +979,19 @@ themePicker.onblur = handleThemeButtonsBlur;
     let mut w = try_err!(File::create(&dst), &dst);
     try_err!(writeln!(&mut w, "var N = null;var searchIndex = {{}};"), &dst);
     for index in &all_indexes {
-        try_err!(write_minify_replacer(&mut w, &*index, enable_minification,
+        try_err!(write_minify_replacer(&mut w, &*index, options.enable_minification,
                                        &[(minifier::js::Keyword::Null, "N")]),
                  &dst);
     }
     try_err!(writeln!(&mut w, "initSearch(searchIndex);"), &dst);
 
-    if cx.enable_index_page == true {
-        if let Some(ref index_page) = cx.index_page {
-            ::markdown::render(index_page,
-                               cx.dst.clone(),
-                               &options.markdown_css.clone(),
-                               options.markdown_playground_url.clone()
-                                   .or_else(|| options.playground_url.clone()),
-                               &(*cx.shared).layout.external_html,
-                               !options.markdown_no_toc, diag);
+    if options.enable_index_page {
+        if let Some(index_page) = options.index_page.clone() {
+            let mut md_opts = options.clone();
+            md_opts.output = cx.dst.clone();
+            md_opts.external_html = (*cx.shared).layout.external_html.clone();
+
+            ::markdown::render(index_page, md_opts, diag);
         } else {
             let dst = cx.dst.join("index.html");
             let mut w = BufWriter::new(try_err!(File::create(&dst), &dst));
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 76de26e0cea..f0f36f0355e 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -370,24 +370,9 @@ fn main_args(args: &[String]) -> isize {
                                  options.debugging_options.ui_testing);
 
     match (options.should_test, options.markdown_input()) {
-        (true, true) => {
-            return markdown::test(&options.input, options.cfgs, options.libs, options.externs,
-                                  options.test_args, options.maybe_sysroot,
-                                  options.display_warnings, options.linker, options.edition,
-                                  options.codegen_options, &diag)
-        }
-        (true, false) => {
-            return test::run(&options.input, options.cfgs, options.libs, options.externs,
-                             options.test_args, options.crate_name, options.maybe_sysroot,
-                             options.display_warnings, options.linker, options.edition,
-                             options.codegen_options)
-        }
-        (false, true) => return markdown::render(&options.input, options.render_options.output,
-                                                 &options.render_options.markdown_css,
-                                                 options.render_options.markdown_playground_url
-                                                    .or(options.render_options.playground_url),
-                                                 &options.render_options.external_html,
-                                                 !options.render_options.markdown_no_toc, &diag),
+        (true, true) => return markdown::test(options, &diag),
+        (true, false) => return test::run(options),
+        (false, true) => return markdown::render(options.input, options.render_options, &diag),
         (false, false) => {}
     }
 
@@ -401,19 +386,7 @@ fn main_args(args: &[String]) -> isize {
         info!("going to format");
         let (error_format, treat_err_as_bug, ui_testing) = diag_opts;
         let diag = core::new_handler(error_format, None, treat_err_as_bug, ui_testing);
-        let html_opts = renderopts.clone();
-        html::render::run(krate, renderopts.extern_html_root_urls, &renderopts.external_html,
-                          renderopts.playground_url,
-                          renderopts.output,
-                          renderopts.resource_suffix,
-                          passes.into_iter().collect(),
-                          renderopts.extension_css,
-                          renderinfo,
-                          renderopts.sort_modules_alphabetically,
-                          renderopts.themes,
-                          renderopts.enable_minification, renderopts.id_map,
-                          renderopts.enable_index_page, renderopts.index_page,
-                          html_opts, &diag)
+        html::render::run(krate, renderopts, passes.into_iter().collect(), renderinfo, &diag)
             .expect("failed to generate documentation");
         0
     })
@@ -424,8 +397,7 @@ fn main_args(args: &[String]) -> isize {
 /// generated from the cleaned AST of the crate.
 ///
 /// This form of input will run all of the plug/cleaning passes
-fn rust_input<R, F>(options: config::Options,
-                    f: F) -> R
+fn rust_input<R, F>(options: config::Options, f: F) -> R
 where R: 'static + Send,
       F: 'static + Send + FnOnce(Output) -> R
 {
@@ -435,25 +407,9 @@ where R: 'static + Send,
     let (tx, rx) = channel();
 
     let result = rustc_driver::monitor(move || syntax::with_globals(move || {
-        use rustc::session::config::Input;
-
-        let paths = options.libs;
-        let cfgs = options.cfgs;
-        let triple = options.target;
-        let maybe_sysroot = options.maybe_sysroot;
-        let crate_name = options.crate_name;
-        let crate_version = options.crate_version;
-        let force_unstable_if_unmarked = options.debugging_options.force_unstable_if_unmarked;
-        let treat_err_as_bug = options.debugging_options.treat_err_as_bug;
-        let ui_testing = options.debugging_options.ui_testing;
-
-        let (mut krate, renderinfo, passes) =
-            core::run_core(paths, cfgs, options.externs, Input::File(options.input), triple, maybe_sysroot,
-                           options.display_warnings, crate_name.clone(),
-                           force_unstable_if_unmarked, options.edition, options.codegen_options, options.error_format,
-                           options.lint_opts, options.lint_cap, options.describe_lints,
-                           options.manual_passes, options.default_passes, treat_err_as_bug,
-                           ui_testing);
+        let crate_name = options.crate_name.clone();
+        let crate_version = options.crate_version.clone();
+        let (mut krate, renderinfo, renderopts, passes) = core::run_core(options);
 
         info!("finished with rustc");
 
@@ -488,7 +444,7 @@ where R: 'static + Send,
         tx.send(f(Output {
             krate: krate,
             renderinfo: renderinfo,
-            renderopts: options.render_options,
+            renderopts,
             passes: passes
         })).unwrap();
     }));
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index dde104a62a8..8008f8848d4 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -11,19 +11,17 @@
 use std::default::Default;
 use std::fs::File;
 use std::io::prelude::*;
-use std::path::{PathBuf, Path};
+use std::path::PathBuf;
 use std::cell::RefCell;
 
 use errors;
 use testing;
-use rustc::session::search_paths::SearchPaths;
-use rustc::session::config::{Externs, CodegenOptions};
 use syntax::source_map::DUMMY_SP;
 use syntax::feature_gate::UnstableFeatures;
-use syntax::edition::Edition;
 
-use externalfiles::{ExternalHtml, LoadStringError, load_string};
+use externalfiles::{LoadStringError, load_string};
 
+use config::{Options, RenderOptions};
 use html::escape::Escape;
 use html::markdown;
 use html::markdown::{ErrorCodes, IdMap, Markdown, MarkdownWithToc, find_testable_code};
@@ -50,23 +48,24 @@ fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) {
 
 /// Render `input` (e.g. "foo.md") into an HTML file in `output`
 /// (e.g. output = "bar" => "bar/foo.html").
-pub fn render(input: &Path, mut output: PathBuf, markdown_css: &[String],
-              playground_url: Option<String>, external_html: &ExternalHtml, include_toc: bool,
-              diag: &errors::Handler) -> isize {
+pub fn render(input: PathBuf, options: RenderOptions, diag: &errors::Handler) -> isize {
+    let mut output = options.output;
     output.push(input.file_stem().unwrap());
     output.set_extension("html");
 
     let mut css = String::new();
-    for name in markdown_css {
+    for name in &options.markdown_css {
         let s = format!("<link rel=\"stylesheet\" type=\"text/css\" href=\"{}\">\n", name);
         css.push_str(&s)
     }
 
-    let input_str = match load_string(input, diag) {
+    let input_str = match load_string(&input, diag) {
         Ok(s) => s,
         Err(LoadStringError::ReadFail) => return 1,
         Err(LoadStringError::BadUtf8) => return 2,
     };
+    let playground_url = options.markdown_playground_url
+                            .or(options.playground_url);
     if let Some(playground) = playground_url {
         markdown::PLAYGROUND.with(|s| { *s.borrow_mut() = Some((None, playground)); });
     }
@@ -88,7 +87,7 @@ pub fn render(input: &Path, mut output: PathBuf, markdown_css: &[String],
 
     let mut ids = IdMap::new();
     let error_codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
-    let text = if include_toc {
+    let text = if !options.markdown_no_toc {
         MarkdownWithToc(text, RefCell::new(&mut ids), error_codes).to_string()
     } else {
         Markdown(text, &[], RefCell::new(&mut ids), error_codes).to_string()
@@ -123,10 +122,10 @@ pub fn render(input: &Path, mut output: PathBuf, markdown_css: &[String],
 </html>"#,
         title = Escape(title),
         css = css,
-        in_header = external_html.in_header,
-        before_content = external_html.before_content,
+        in_header = options.external_html.in_header,
+        before_content = options.external_html.before_content,
         text = text,
-        after_content = external_html.after_content,
+        after_content = options.external_html.after_content,
     );
 
     match err {
@@ -139,11 +138,8 @@ pub fn render(input: &Path, mut output: PathBuf, markdown_css: &[String],
 }
 
 /// Run any tests/code examples in the markdown file `input`.
-pub fn test(input: &Path, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
-            mut test_args: Vec<String>, maybe_sysroot: Option<PathBuf>,
-            display_warnings: bool, linker: Option<PathBuf>, edition: Edition,
-            cg: CodegenOptions, diag: &errors::Handler) -> isize {
-    let input_str = match load_string(input, diag) {
+pub fn test(mut options: Options, diag: &errors::Handler) -> isize {
+    let input_str = match load_string(&options.input, diag) {
         Ok(s) => s,
         Err(LoadStringError::ReadFail) => return 1,
         Err(LoadStringError::BadUtf8) => return 2,
@@ -151,19 +147,20 @@ pub fn test(input: &Path, cfgs: Vec<String>, libs: SearchPaths, externs: Externs
 
     let mut opts = TestOptions::default();
     opts.no_crate_inject = true;
-    opts.display_warnings = display_warnings;
-    let mut collector = Collector::new(input.display().to_string(), cfgs, libs, cg, externs,
-                                       true, opts, maybe_sysroot, None,
-                                       Some(PathBuf::from(input)),
-                                       linker, edition);
+    opts.display_warnings = options.display_warnings;
+    let mut collector = Collector::new(options.input.display().to_string(), options.cfgs,
+                                       options.libs, options.codegen_options, options.externs,
+                                       true, opts, options.maybe_sysroot, None,
+                                       Some(options.input),
+                                       options.linker, options.edition);
     collector.set_position(DUMMY_SP);
     let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
     let res = find_testable_code(&input_str, &mut collector, codes);
     if let Err(err) = res {
         diag.span_warn(DUMMY_SP, &err.to_string());
     }
-    test_args.insert(0, "rustdoctest".to_string());
-    testing::test_main(&test_args, collector.tests,
-                       testing::Options::new().display_output(display_warnings));
+    options.test_args.insert(0, "rustdoctest".to_string());
+    testing::test_main(&options.test_args, collector.tests,
+                       testing::Options::new().display_output(options.display_warnings));
     0
 }
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 2e6e76b5a40..ebc26d73c45 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -12,7 +12,7 @@ use std::env;
 use std::ffi::OsString;
 use std::io::prelude::*;
 use std::io;
-use std::path::{Path, PathBuf};
+use std::path::PathBuf;
 use std::panic::{self, AssertUnwindSafe};
 use std::process::Command;
 use std::str;
@@ -42,6 +42,7 @@ use errors;
 use errors::emitter::ColorConfig;
 
 use clean::Attributes;
+use config::Options;
 use html::markdown::{self, ErrorCodes, LangString};
 
 #[derive(Clone, Default)]
@@ -55,34 +56,23 @@ pub struct TestOptions {
     pub attrs: Vec<String>,
 }
 
-pub fn run(input_path: &Path,
-           cfgs: Vec<String>,
-           libs: SearchPaths,
-           externs: Externs,
-           mut test_args: Vec<String>,
-           crate_name: Option<String>,
-           maybe_sysroot: Option<PathBuf>,
-           display_warnings: bool,
-           linker: Option<PathBuf>,
-           edition: Edition,
-           cg: CodegenOptions)
-           -> isize {
-    let input = config::Input::File(input_path.to_owned());
+pub fn run(mut options: Options) -> isize {
+    let input = config::Input::File(options.input.clone());
 
     let sessopts = config::Options {
-        maybe_sysroot: maybe_sysroot.clone().or_else(
+        maybe_sysroot: options.maybe_sysroot.clone().or_else(
             || Some(env::current_exe().unwrap().parent().unwrap().parent().unwrap().to_path_buf())),
-        search_paths: libs.clone(),
+        search_paths: options.libs.clone(),
         crate_types: vec![config::CrateType::Dylib],
-        cg: cg.clone(),
-        externs: externs.clone(),
+        cg: options.codegen_options.clone(),
+        externs: options.externs.clone(),
         unstable_features: UnstableFeatures::from_environment(),
         lint_cap: Some(::rustc::lint::Level::Allow),
         actually_rustdoc: true,
         debugging_opts: config::DebuggingOptions {
             ..config::basic_debugging_options()
         },
-        edition,
+        edition: options.edition,
         ..config::Options::default()
     };
     driver::spawn_thread_pool(sessopts, |sessopts| {
@@ -93,13 +83,14 @@ pub fn run(input_path: &Path,
                                             Some(source_map.clone()));
 
         let mut sess = session::build_session_(
-            sessopts, Some(input_path.to_owned()), handler, source_map.clone(),
+            sessopts, Some(options.input), handler, source_map.clone(),
         );
         let codegen_backend = rustc_driver::get_codegen_backend(&sess);
         let cstore = CStore::new(codegen_backend.metadata_loader());
         rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
 
-        let mut cfg = config::build_configuration(&sess, config::parse_cfgspecs(cfgs.clone()));
+        let mut cfg = config::build_configuration(&sess,
+                                                  config::parse_cfgspecs(options.cfgs.clone()));
         target_features::add_configuration(&mut cfg, &sess, &*codegen_backend);
         sess.parse_sess.config = cfg;
 
@@ -119,24 +110,24 @@ pub fn run(input_path: &Path,
             ).expect("phase_2_configure_and_expand aborted in rustdoc!")
         };
 
-        let crate_name = crate_name.unwrap_or_else(|| {
+        let crate_name = options.crate_name.unwrap_or_else(|| {
             ::rustc_codegen_utils::link::find_crate_name(None, &hir_forest.krate().attrs, &input)
         });
         let mut opts = scrape_test_config(hir_forest.krate());
-        opts.display_warnings |= display_warnings;
+        opts.display_warnings |= options.display_warnings;
         let mut collector = Collector::new(
             crate_name,
-            cfgs,
-            libs,
-            cg,
-            externs,
+            options.cfgs,
+            options.libs,
+            options.codegen_options,
+            options.externs,
             false,
             opts,
-            maybe_sysroot,
+            options.maybe_sysroot,
             Some(source_map),
-             None,
-            linker,
-            edition
+            None,
+            options.linker,
+            options.edition
         );
 
         {
@@ -153,11 +144,11 @@ pub fn run(input_path: &Path,
             });
         }
 
-        test_args.insert(0, "rustdoctest".to_string());
+        options.test_args.insert(0, "rustdoctest".to_string());
 
-        testing::test_main(&test_args,
+        testing::test_main(&options.test_args,
                         collector.tests.into_iter().collect(),
-                        testing::Options::new().display_output(display_warnings));
+                        testing::Options::new().display_output(options.display_warnings));
         0
     })
 }