diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index 9de46cef7455c..6efe6e608e8ad 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -34,6 +34,8 @@ pub struct TestProps { pub exec_env: Vec<(String,String)> , // Lines to check if they appear in the expected debugger output pub check_lines: Vec , + // Build documentation for all specified aux-builds as well + pub build_aux_docs: bool, // Flag to force a crate to be built with the host architecture pub force_host: bool, // Check stdout for error-pattern output as well as stderr @@ -59,6 +61,7 @@ pub fn load_props(testfile: &Path) -> TestProps { let mut run_flags = None; let mut pp_exact = None; let mut check_lines = Vec::new(); + let mut build_aux_docs = false; let mut force_host = false; let mut check_stdout = false; let mut no_prefer_dynamic = false; @@ -83,6 +86,10 @@ pub fn load_props(testfile: &Path) -> TestProps { pp_exact = parse_pp_exact(ln, testfile); } + if !build_aux_docs { + build_aux_docs = parse_build_aux_docs(ln); + } + if !force_host { force_host = parse_force_host(ln); } @@ -144,6 +151,7 @@ pub fn load_props(testfile: &Path) -> TestProps { aux_builds: aux_builds, exec_env: exec_env, check_lines: check_lines, + build_aux_docs: build_aux_docs, force_host: force_host, check_stdout: check_stdout, no_prefer_dynamic: no_prefer_dynamic, @@ -284,6 +292,10 @@ fn parse_force_host(line: &str) -> bool { parse_name_directive(line, "force-host") } +fn parse_build_aux_docs(line: &str) -> bool { + parse_name_directive(line, "build-aux-docs") +} + fn parse_check_stdout(line: &str) -> bool { parse_name_directive(line, "check-stdout") } diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 8042e2f966ca7..833ab553a132f 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -1149,11 +1149,20 @@ fn compile_test(config: &Config, props: &TestProps, } fn document(config: &Config, props: &TestProps, - testfile: &Path) -> (ProcRes, PathBuf) { + testfile: &Path, out_dir: &Path) -> ProcRes { + if props.build_aux_docs { + for rel_ab in &props.aux_builds { + let abs_ab = config.aux_base.join(rel_ab); + let aux_props = header::load_props(&abs_ab); + + let auxres = document(config, &aux_props, &abs_ab, out_dir); + if !auxres.status.success() { + return auxres; + } + } + } + let aux_dir = aux_output_dir_name(config, testfile); - let out_dir = output_base_name(config, testfile); - let _ = fs::remove_dir_all(&out_dir); - ensure_dir(&out_dir); let mut args = vec!["-L".to_owned(), aux_dir.to_str().unwrap().to_owned(), "-o".to_owned(), @@ -1164,7 +1173,7 @@ fn document(config: &Config, props: &TestProps, prog: config.rustdoc_path.to_str().unwrap().to_owned(), args: args, }; - (compose_and_run_compiler(config, props, testfile, args, None), out_dir) + compose_and_run_compiler(config, props, testfile, args, None) } fn exec_compiled_test(config: &Config, props: &TestProps, @@ -1723,7 +1732,11 @@ fn charset() -> &'static str { } fn run_rustdoc_test(config: &Config, props: &TestProps, testfile: &Path) { - let (proc_res, out_dir) = document(config, props, testfile); + let out_dir = output_base_name(config, testfile); + let _ = fs::remove_dir_all(&out_dir); + ensure_dir(&out_dir); + + let proc_res = document(config, props, testfile, &out_dir); if !proc_res.status.success() { fatal_proc_rec("rustdoc failed!", &proc_res); } diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 81375bd3a5a14..fba6dea4448b2 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -142,6 +142,7 @@ pub trait CrateStore<'tcx> : Any { fn item_type(&self, tcx: &ty::ctxt<'tcx>, def: DefId) -> ty::TypeScheme<'tcx>; fn item_path(&self, def: DefId) -> Vec; + fn extern_item_path(&self, def: DefId) -> Vec; fn item_name(&self, def: DefId) -> ast::Name; fn item_predicates(&self, tcx: &ty::ctxt<'tcx>, def: DefId) -> ty::GenericPredicates<'tcx>; @@ -295,6 +296,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { fn item_type(&self, tcx: &ty::ctxt<'tcx>, def: DefId) -> ty::TypeScheme<'tcx> { unimplemented!() } fn item_path(&self, def: DefId) -> Vec { unimplemented!() } + fn extern_item_path(&self, def: DefId) -> Vec { unimplemented!() } fn item_name(&self, def: DefId) -> ast::Name { unimplemented!() } fn item_predicates(&self, tcx: &ty::ctxt<'tcx>, def: DefId) -> ty::GenericPredicates<'tcx> { unimplemented!() } diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs index 3c97692ee56eb..822b11112f211 100644 --- a/src/librustc_metadata/csearch.rs +++ b/src/librustc_metadata/csearch.rs @@ -21,7 +21,7 @@ use middle::lang_items; use middle::ty::{self, Ty}; use middle::def_id::{DefId, DefIndex}; -use rustc::front::map as ast_map; +use rustc::front::map as hir_map; use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet}; use std::cell::RefCell; @@ -29,6 +29,7 @@ use std::rc::Rc; use std::path::PathBuf; use syntax::ast; use syntax::attr; +use syntax::parse::token; use rustc_back::svh::Svh; use rustc_back::target::Target; use rustc_front::hir; @@ -115,7 +116,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { decoder::get_method_arg_names(&cdata, did.index) } - fn item_path(&self, def: DefId) -> Vec { + fn item_path(&self, def: DefId) -> Vec { let cdata = self.get_crate_data(def.krate); let path = decoder::get_item_path(&*cdata, def.index); @@ -127,6 +128,17 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { }) } + fn extern_item_path(&self, def: DefId) -> Vec { + let cdata = self.get_crate_data(def.krate); + let path = decoder::get_item_path(&*cdata, def.index); + + let mut r = Vec::with_capacity(path.len() + 1); + let crate_name = hir_map::PathMod(token::intern(&cdata.name)); + r.push(crate_name); + r.push_all(&path); + r + } + fn item_name(&self, def: DefId) -> ast::Name { let cdata = self.get_crate_data(def.krate); decoder::get_item_name(&self.intr, &cdata, def.index) @@ -350,7 +362,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { decoder::get_reachable_ids(&*cdata) } - fn def_path(&self, def: DefId) -> ast_map::DefPath + fn def_path(&self, def: DefId) -> hir_map::DefPath { let cdata = self.get_crate_data(def.krate); let path = decoder::def_path(&*cdata, def.index); diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 40cd5e5bf2787..40e7146670907 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -138,7 +138,7 @@ pub fn load_attrs(cx: &DocContext, tcx: &ty::ctxt, pub fn record_extern_fqn(cx: &DocContext, did: DefId, kind: clean::TypeKind) { match cx.tcx_opt() { Some(tcx) => { - let fqn = tcx.sess.cstore.item_path(did); + let fqn = tcx.sess.cstore.extern_item_path(did); let fqn = fqn.into_iter().map(|i| i.to_string()).collect(); cx.external_paths.borrow_mut().as_mut().unwrap().insert(did, (fqn, kind)); } diff --git a/src/test/auxiliary/issue-30109-1.rs b/src/test/auxiliary/issue-30109-1.rs new file mode 100644 index 0000000000000..59f952a0b29d1 --- /dev/null +++ b/src/test/auxiliary/issue-30109-1.rs @@ -0,0 +1,11 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub struct Bar; diff --git a/src/test/rustdoc/issue-30109.rs b/src/test/rustdoc/issue-30109.rs new file mode 100644 index 0000000000000..2d33e9323d149 --- /dev/null +++ b/src/test/rustdoc/issue-30109.rs @@ -0,0 +1,24 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// build-aux-docs +// aux-build:issue-30109-1.rs +// ignore-cross-compile + +pub mod quux { + extern crate issue_30109_1 as bar; + use self::bar::Bar; + + pub trait Foo {} + + // @has issue_30109/quux/trait.Foo.html \ + // '//a/@href' '../issue_30109_1/struct.Bar.html' + impl Foo for Bar {} +}