Skip to content

Commit 1a89e16

Browse files
authored
Rollup merge of rust-lang#62855 - Aaron1011:feature/rustdoc-reexport-final, r=petrochenkov
Improve Rustdoc's handling of procedural macros Fixes rust-lang#58700 Fixes rust-lang#58696 Fixes rust-lang#49553 Fixes rust-lang#52210 This commit removes the special rustdoc handling for proc macros, as we can now retrieve their span and attributes just like any other item. A new command-line option is added to rustdoc: `--crate-type`. This takes the same options as rustc's `--crate-type` option. However, all values other than `proc-macro` are treated the same. This allows Rustdoc to enable 'proc macro mode' when handling a proc macro crate. In compiletest, a new 'rustdoc-flags' option is added. This allows us to pass in the '--proc-macro-crate' flag in the absence of Cargo. I've opened [an additional PR to Cargo](rust-lang/cargo#7159) to support passing in this flag. These two PRS can be merged in any order - the Cargo changes will not take effect until the 'cargo' submodule is updated in this repository.
2 parents 5ade61a + 1498608 commit 1a89e16

File tree

13 files changed

+95
-56
lines changed

13 files changed

+95
-56
lines changed

src/librustc/session/config.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -1719,13 +1719,7 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
17191719
static, framework, or dylib (the default).",
17201720
"[KIND=]NAME",
17211721
),
1722-
opt::multi_s(
1723-
"",
1724-
"crate-type",
1725-
"Comma separated list of types of crates
1726-
for the compiler to emit",
1727-
"[bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]",
1728-
),
1722+
make_crate_type_option(),
17291723
opt::opt_s(
17301724
"",
17311725
"crate-name",
@@ -2506,6 +2500,16 @@ pub fn build_session_options_and_crate_config(
25062500
)
25072501
}
25082502

2503+
pub fn make_crate_type_option() -> RustcOptGroup {
2504+
opt::multi_s(
2505+
"",
2506+
"crate-type",
2507+
"Comma separated list of types of crates
2508+
for the compiler to emit",
2509+
"[bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]",
2510+
)
2511+
}
2512+
25092513
pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateType>, String> {
25102514
let mut crate_types: Vec<CrateType> = Vec::new();
25112515
for unparsed_crate_type in &list_list {

src/librustc_interface/passes.rs

+16-21
Original file line numberDiff line numberDiff line change
@@ -473,27 +473,22 @@ fn configure_and_expand_inner<'a>(
473473
ast_validation::check_crate(sess, &krate)
474474
});
475475

476-
// If we're in rustdoc we're always compiling as an rlib, but that'll trip a
477-
// bunch of checks in the `modify` function below. For now just skip this
478-
// step entirely if we're rustdoc as it's not too useful anyway.
479-
if !sess.opts.actually_rustdoc {
480-
krate = time(sess, "maybe creating a macro crate", || {
481-
let crate_types = sess.crate_types.borrow();
482-
let num_crate_types = crate_types.len();
483-
let is_proc_macro_crate = crate_types.contains(&config::CrateType::ProcMacro);
484-
let is_test_crate = sess.opts.test;
485-
syntax_ext::proc_macro_harness::inject(
486-
&sess.parse_sess,
487-
&mut resolver,
488-
krate,
489-
is_proc_macro_crate,
490-
has_proc_macro_decls,
491-
is_test_crate,
492-
num_crate_types,
493-
sess.diagnostic(),
494-
)
495-
});
496-
}
476+
krate = time(sess, "maybe creating a macro crate", || {
477+
let crate_types = sess.crate_types.borrow();
478+
let num_crate_types = crate_types.len();
479+
let is_proc_macro_crate = crate_types.contains(&config::CrateType::ProcMacro);
480+
let is_test_crate = sess.opts.test;
481+
syntax_ext::proc_macro_harness::inject(
482+
&sess.parse_sess,
483+
&mut resolver,
484+
krate,
485+
is_proc_macro_crate,
486+
has_proc_macro_decls,
487+
is_test_crate,
488+
num_crate_types,
489+
sess.diagnostic(),
490+
)
491+
});
497492

498493
// Done with macro expansion!
499494

src/librustdoc/clean/inline.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::clean::{
2020
self,
2121
GetDefId,
2222
ToSource,
23+
TypeKind
2324
};
2425

2526
use super::Clean;
@@ -107,15 +108,16 @@ pub fn try_inline(
107108
record_extern_fqn(cx, did, clean::TypeKind::Const);
108109
clean::ConstantItem(build_const(cx, did))
109110
}
110-
// FIXME: proc-macros don't propagate attributes or spans across crates, so they look empty
111-
Res::Def(DefKind::Macro(MacroKind::Bang), did) => {
111+
Res::Def(DefKind::Macro(kind), did) => {
112112
let mac = build_macro(cx, did, name);
113-
if let clean::MacroItem(..) = mac {
114-
record_extern_fqn(cx, did, clean::TypeKind::Macro);
115-
mac
116-
} else {
117-
return None;
118-
}
113+
114+
let type_kind = match kind {
115+
MacroKind::Bang => TypeKind::Macro,
116+
MacroKind::Attr => TypeKind::Attr,
117+
MacroKind::Derive => TypeKind::Derive
118+
};
119+
record_extern_fqn(cx, did, type_kind);
120+
mac
119121
}
120122
_ => return None,
121123
};

src/librustdoc/config.rs

+14
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use errors;
66
use getopts;
77
use rustc::lint::Level;
88
use rustc::session;
9+
use rustc::session::config::{CrateType, parse_crate_types_from_list};
910
use rustc::session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs};
1011
use rustc::session::config::{nightly_options, build_codegen_options, build_debugging_options,
1112
get_cmd_lint_options, ExternEntry};
@@ -32,6 +33,8 @@ pub struct Options {
3233
pub input: PathBuf,
3334
/// The name of the crate being documented.
3435
pub crate_name: Option<String>,
36+
/// Whether or not this is a proc-macro crate
37+
pub proc_macro_crate: bool,
3538
/// How to format errors and warnings.
3639
pub error_format: ErrorOutputType,
3740
/// Library search paths to hand to the compiler.
@@ -111,6 +114,7 @@ impl fmt::Debug for Options {
111114
f.debug_struct("Options")
112115
.field("input", &self.input)
113116
.field("crate_name", &self.crate_name)
117+
.field("proc_macro_crate", &self.proc_macro_crate)
114118
.field("error_format", &self.error_format)
115119
.field("libs", &self.libs)
116120
.field("externs", &FmtExterns(&self.externs))
@@ -431,7 +435,16 @@ impl Options {
431435
};
432436
let manual_passes = matches.opt_strs("passes");
433437

438+
let crate_types = match parse_crate_types_from_list(matches.opt_strs("crate-type")) {
439+
Ok(types) => types,
440+
Err(e) =>{
441+
diag.struct_err(&format!("unknown crate type: {}", e)).emit();
442+
return Err(1);
443+
}
444+
};
445+
434446
let crate_name = matches.opt_str("crate-name");
447+
let proc_macro_crate = crate_types.contains(&CrateType::ProcMacro);
435448
let playground_url = matches.opt_str("playground-url");
436449
let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from);
437450
let display_warnings = matches.opt_present("display-warnings");
@@ -454,6 +467,7 @@ impl Options {
454467
Ok(Options {
455468
input,
456469
crate_name,
470+
proc_macro_crate,
457471
error_format,
458472
libs,
459473
externs,

src/librustdoc/core.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
228228
let RustdocOptions {
229229
input,
230230
crate_name,
231+
proc_macro_crate,
231232
error_format,
232233
libs,
233234
externs,
@@ -293,11 +294,16 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
293294
}).collect();
294295

295296
let host_triple = TargetTriple::from_triple(config::host_triple());
297+
let crate_types = if proc_macro_crate {
298+
vec![config::CrateType::ProcMacro]
299+
} else {
300+
vec![config::CrateType::Rlib]
301+
};
296302
// plays with error output here!
297303
let sessopts = config::Options {
298304
maybe_sysroot,
299305
search_paths: libs,
300-
crate_types: vec![config::CrateType::Rlib],
306+
crate_types,
301307
lint_opts: if !display_warnings {
302308
lint_opts
303309
} else {

src/librustdoc/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use std::panic;
4646
use std::process;
4747

4848
use rustc::session::{early_warn, early_error};
49-
use rustc::session::config::{ErrorOutputType, RustcOptGroup};
49+
use rustc::session::config::{ErrorOutputType, RustcOptGroup, make_crate_type_option};
5050

5151
#[macro_use]
5252
mod externalfiles;
@@ -132,6 +132,7 @@ fn opts() -> Vec<RustcOptGroup> {
132132
stable("crate-name", |o| {
133133
o.optopt("", "crate-name", "specify the name of this crate", "NAME")
134134
}),
135+
make_crate_type_option(),
135136
stable("L", |o| {
136137
o.optmulti("L", "library-path", "directory to add to crate search path",
137138
"DIR")

src/librustdoc/test.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,16 @@ pub struct TestOptions {
4343
pub fn run(options: Options) -> i32 {
4444
let input = config::Input::File(options.input.clone());
4545

46+
let crate_types = if options.proc_macro_crate {
47+
vec![config::CrateType::ProcMacro]
48+
} else {
49+
vec![config::CrateType::Dylib]
50+
};
51+
4652
let sessopts = config::Options {
4753
maybe_sysroot: options.maybe_sysroot.clone(),
4854
search_paths: options.libs.clone(),
49-
crate_types: vec![config::CrateType::Dylib],
55+
crate_types,
5056
cg: options.codegen_options.clone(),
5157
externs: options.externs.clone(),
5258
unstable_features: UnstableFeatures::from_environment(),

src/test/rustdoc-ui/failed-doctest-output.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// adapted to use that, and that normalize line can go away
44

55
// compile-flags:--test
6+
// rustc-env:RUST_BACKTRACE=0
67
// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR"
78
// failure-status: 101
89

src/test/rustdoc-ui/failed-doctest-output.stdout

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11

22
running 2 tests
3-
test $DIR/failed-doctest-output.rs - OtherStruct (line 20) ... FAILED
4-
test $DIR/failed-doctest-output.rs - SomeStruct (line 10) ... FAILED
3+
test $DIR/failed-doctest-output.rs - OtherStruct (line 21) ... FAILED
4+
test $DIR/failed-doctest-output.rs - SomeStruct (line 11) ... FAILED
55

66
failures:
77

8-
---- $DIR/failed-doctest-output.rs - OtherStruct (line 20) stdout ----
8+
---- $DIR/failed-doctest-output.rs - OtherStruct (line 21) stdout ----
99
error[E0425]: cannot find value `no` in this scope
10-
--> $DIR/failed-doctest-output.rs:21:1
10+
--> $DIR/failed-doctest-output.rs:22:1
1111
|
1212
3 | no
1313
| ^^ not found in this scope
@@ -16,7 +16,7 @@ error: aborting due to previous error
1616

1717
For more information about this error, try `rustc --explain E0425`.
1818
Couldn't compile the test.
19-
---- $DIR/failed-doctest-output.rs - SomeStruct (line 10) stdout ----
19+
---- $DIR/failed-doctest-output.rs - SomeStruct (line 11) stdout ----
2020
Test executable failed (exit code 101).
2121

2222
stdout:
@@ -32,8 +32,8 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
3232

3333

3434
failures:
35-
$DIR/failed-doctest-output.rs - OtherStruct (line 20)
36-
$DIR/failed-doctest-output.rs - SomeStruct (line 10)
35+
$DIR/failed-doctest-output.rs - OtherStruct (line 21)
36+
$DIR/failed-doctest-output.rs - SomeStruct (line 11)
3737

3838
test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out
3939

src/test/rustdoc/inline_cross/auxiliary/proc_macro.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// force-host
22
// no-prefer-dynamic
3+
// compile-flags: --crate-type proc-macro
34

45
#![crate_type="proc-macro"]
56
#![crate_name="some_macros"]
@@ -25,3 +26,9 @@ pub fn some_proc_attr(_attr: TokenStream, item: TokenStream) -> TokenStream {
2526
pub fn some_derive(_item: TokenStream) -> TokenStream {
2627
TokenStream::new()
2728
}
29+
30+
/// Doc comment from the original crate
31+
#[proc_macro]
32+
pub fn reexported_macro(_input: TokenStream) -> TokenStream {
33+
TokenStream::new()
34+
}
+10-9
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
// aux-build:proc_macro.rs
22
// build-aux-docs
33

4-
// FIXME: if/when proc-macros start exporting their doc attributes across crates, we can turn on
5-
// cross-crate inlining for them
6-
74
extern crate some_macros;
85

96
// @has proc_macro/index.html
10-
// @has - '//a/@href' '../some_macros/macro.some_proc_macro.html'
11-
// @has - '//a/@href' '../some_macros/attr.some_proc_attr.html'
12-
// @has - '//a/@href' '../some_macros/derive.SomeDerive.html'
13-
// @!has proc_macro/macro.some_proc_macro.html
14-
// @!has proc_macro/attr.some_proc_attr.html
15-
// @!has proc_macro/derive.SomeDerive.html
7+
// @has - '//a/@href' 'macro.some_proc_macro.html'
8+
// @has - '//a/@href' 'attr.some_proc_attr.html'
9+
// @has - '//a/@href' 'derive.SomeDerive.html'
10+
// @has proc_macro/macro.some_proc_macro.html
11+
// @has proc_macro/attr.some_proc_attr.html
12+
// @has proc_macro/derive.SomeDerive.html
1613
pub use some_macros::{some_proc_macro, some_proc_attr, SomeDerive};
14+
15+
// @has proc_macro/macro.reexported_macro.html
16+
// @has - 'Doc comment from the original crate'
17+
pub use some_macros::reexported_macro;

src/test/rustdoc/proc-macro.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// force-host
22
// no-prefer-dynamic
3+
// compile-flags: --crate-type proc-macro --document-private-items
34

45
#![crate_type="proc-macro"]
56
#![crate_name="some_macros"]
@@ -58,7 +59,7 @@ pub fn some_derive(_item: TokenStream) -> TokenStream {
5859
}
5960

6061
// @has some_macros/foo/index.html
61-
pub mod foo {
62+
mod foo {
6263
// @has - '//code' 'pub use some_proc_macro;'
6364
// @has - '//a/@href' '../../some_macros/macro.some_proc_macro.html'
6465
pub use some_proc_macro;

src/test/rustdoc/rustc-macro-crate.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// force-host
22
// no-prefer-dynamic
3+
// compile-flags: --crate-type proc-macro
34

45
#![crate_type = "proc-macro"]
56

0 commit comments

Comments
 (0)