fix(doctest): detect extern crate items in statement doctests

This partially reverts #91026, because rustdoc needs to detect the extern statements,
even when they appear inside implicit `main()`. It does not entirely revert it,
so the old bug is still fixed, by duplicating some of the logic from `parse_mod`
instead of trying to use it directly.

Fixes #91134
This commit is contained in:
Michael Howell 2021-11-22 19:47:58 -07:00
parent 214ad2f5b5
commit bff1645bdb
5 changed files with 38 additions and 8 deletions

View File

@ -1121,7 +1121,7 @@ pub(super) fn maybe_recover_from_bad_qpath_stage_2<T: RecoverQPath>(
Ok(P(T::recovered(Some(QSelf { ty, path_span, position: 0 }), path)))
}
pub(super) fn maybe_consume_incorrect_semicolon(&mut self, items: &[P<Item>]) -> bool {
pub fn maybe_consume_incorrect_semicolon(&mut self, items: &[P<Item>]) -> bool {
if self.eat(&token::Semi) {
let mut err = self.struct_span_err(self.prev_token.span, "expected item, found `;`");
err.span_suggestion_short(

View File

@ -1,4 +1,4 @@
use rustc_ast::{self as ast, token};
use rustc_ast as ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::Lrc;
use rustc_errors::{ColorConfig, ErrorReported, FatalError};
@ -537,6 +537,7 @@ fn drop(&mut self) {
use rustc_errors::emitter::{Emitter, EmitterWriter};
use rustc_errors::Handler;
use rustc_parse::maybe_new_parser_from_source_str;
use rustc_parse::parser::ForceCollect;
use rustc_session::parse::ParseSess;
use rustc_span::source_map::FilePathMapping;
@ -572,9 +573,9 @@ fn drop(&mut self) {
}
};
match parser.parse_mod(&token::Eof) {
Ok((_attrs, items, _span)) => {
for item in items {
loop {
match parser.parse_item(ForceCollect::No) {
Ok(Some(item)) => {
if !found_main {
if let ast::ItemKind::Fn(..) = item.kind {
if item.ident.name == sym::main {
@ -606,12 +607,18 @@ fn drop(&mut self) {
break;
}
}
}
Ok(None) => break,
Err(mut e) => {
e.cancel();
break;
}
}
// The supplied slice is only used for diagnostics,
// which are swallowed here anyway.
parser.maybe_consume_incorrect_semicolon(&[]);
}
// Reset errors so that they won't be reported as compiler bugs when dropping the
// handler. Any errors in the tests will be reported when the test file is compiled,
// Note that we still need to cancel the errors above otherwise `DiagnosticBuilder`

View File

@ -0,0 +1,3 @@
// no-prefer-dynamic
#![crate_type = "lib"]
pub fn empty() {}

View File

@ -0,0 +1,14 @@
// compile-flags: --test --crate-name=empty_fn --extern=empty_fn --test-args=--test-threads=1
// aux-build:empty-fn.rs
// check-pass
// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR"
// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME"
// edition:2021
/// <https://github.com/rust-lang/rust/issues/91134>
///
/// ```
/// extern crate empty_fn;
/// empty_fn::empty();
/// ```
pub struct Something;

View File

@ -0,0 +1,6 @@
running 1 test
test $DIR/issue-91134.rs - something (line 10) ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME