diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2018-02-21 16:29:47 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-02-21 16:29:47 +0100 |
| commit | f0343cbd1f6140bfc72e305cebf3db26eb4a2c55 (patch) | |
| tree | 4238c5e83219ddc5d7a727210345a305ad21de26 | |
| parent | aec653536c3db82d74bb1a274b7df9d9dc582ec4 (diff) | |
| parent | d8d4c583be96d9eb654891288829af9410b68e1c (diff) | |
| download | rust-f0343cbd1f6140bfc72e305cebf3db26eb4a2c55.tar.gz rust-f0343cbd1f6140bfc72e305cebf3db26eb4a2c55.zip | |
Rollup merge of #48106 - QuietMisdreavus:teleporting-crates, r=GuillaumeGomez
rustdoc: move manual "extern crate" statements outside automatic "fn main"s in doctests
Gated on https://github.com/rust-lang/rust/pull/48095 - I based the branch atop that so i could show off the change in one of its tests, the actual change in this PR is just the last commit
There are a handful of unfortunate assumptions in the way rustdoc processes `extern crate` statements in doctests:
1. In the absence of an `extern crate` statement in the test, if the test also uses the local crate name, it will automatically insert an `extern crate cratename;` statement into the test.
2. If the doctest *does* include an `extern crate` statement, rustdoc will not automatically insert one, on the assumption that doing so would introduce a duplicate import.
3. If a doctest does not have the substring `fn main` outside a comment, rustdoc will wrap the whole doctest in a generated `fn main` so it can be compiled.
In short, whenever you write a doctest like this...
```rust
//! extern crate my_crate;
//! my_crate::some_cool_thing();
```
...rustdoc will turn it into (something like) this:
```rust
fn main() {
extern crate my_crate;
my_crate::some_cool_thing();
}
```
This creates issues when compiled, because now `my_crate` isn't even properly in scope! This forces people who want to have multiple crates in their doctests (or an explicit `extern crate` statement) to also manually include their own `fn main`, so rustdoc doesn't put their imports in the wrong place.
This PR just taps into another processing step rustdoc does to doctests: Whenever you add an `#![inner_attribute]` to the beginning of a doctest, rustdoc will actually splice those out and put it before the generated `fn main`. Now, we can just do the same with `extern crate`s at the beginning, too, and get a much nicer experience.
Now, the above example will be converted into this:
```rust
extern crate my_crate;
fn main() {
my_crate::some_cool_thing();
}
```
| -rw-r--r-- | src/librustc_resolve/diagnostics.rs | 2 | ||||
| -rw-r--r-- | src/librustdoc/test.rs | 5 |
2 files changed, 5 insertions, 2 deletions
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 8a29155d12d..c1e6b4f5a17 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -325,6 +325,8 @@ Erroneous code example: extern crate core; struct core; + +fn main() {} ``` There are two possible solutions: diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 90b6746d91d..12c4076c9a5 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -414,7 +414,8 @@ fn partition_source(s: &str) -> (String, String) { for line in s.lines() { let trimline = line.trim(); let header = trimline.is_whitespace() || - trimline.starts_with("#!["); + trimline.starts_with("#![") || + trimline.starts_with("extern crate"); if !header || after_header { after_header = true; after.push_str(line); @@ -814,8 +815,8 @@ use asdf::qwop; assert_eq!(2+2, 4);"; let expected = "#![allow(unused)] -fn main() { extern crate asdf; +fn main() { use asdf::qwop; assert_eq!(2+2, 4); }".to_string(); |
