Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
cf26d82
chore: remove redundant words in comment
pudongair Mar 26, 2025
d81559a
Refactor `diy_float`
TDecking Mar 31, 2025
e5fb426
docs: Add example to `Iterator::take` with `by_ref`
ongardie Apr 14, 2025
0369ccb
Fix some grammar errors and hyperlinks in doc for `trait Allocator`
Lee-Janggun Apr 14, 2025
31cb737
simd_select_bitmask: the 'padding' bits in the mask are just ignored
RalfJung Apr 19, 2025
3a372e3
std: mention `remove_dir_all` can emit `DirectoryNotEmpty` when concu…
xizheyin Apr 20, 2025
2b8e9b5
Enable [behind-upstream] triagebot option
xizheyin Apr 25, 2025
451d73f
use repo name in push pr title
tshepang Apr 28, 2025
3d23917
Add an example of the example of an edition migration lint
ehuss Apr 28, 2025
b0e675b
Add documentation on how to migration the edition of the standard lib…
ehuss Apr 28, 2025
0aae3ca
Update mdbook to 0.4.48
ehuss Apr 28, 2025
5050037
Add documentation on how to stabilize the compiler edition
ehuss Apr 28, 2025
5ce6fa7
Merge pull request #2361 from ehuss/update-mdbook
JohnTitor Apr 29, 2025
c466cd0
Update compiler-src.md
smanilov Apr 29, 2025
a2b3f11
Filter out LoongArch features not supported by the current LLVM version
heiher Apr 29, 2025
74b55b4
Add comment to remind filtering unsupported features when adding new …
heiher Apr 29, 2025
e2fb99c
Introduce a normalization chapter
BoxyUwU Apr 29, 2025
fcec80a
Merge pull request #2266 from BoxyUwU/normalization
lcnr Apr 29, 2025
7f1ae9b
Fix footnotes
BoxyUwU Apr 29, 2025
0f9146b
Merge pull request #2365 from BoxyUwU/norm_footnotes
BoxyUwU Apr 29, 2025
c7eeeb1
Merge PR #2360: Add docs about stabilizing an edition
traviscross Apr 29, 2025
029a2c4
Merge pull request #2363 from smanilov/patch-1
tshepang Apr 29, 2025
48bbf5a
for a more friendly output
tshepang Apr 29, 2025
7135a9f
Merge pull request #2366 from rust-lang/tshepang-patch-1
jieyouxu Apr 30, 2025
b1c8693
Merge pull request #2359 from rust-lang/tshepang-repo-name
jieyouxu Apr 30, 2025
b02178b
Merge pull request #2352 from xizheyin/enable-behind-upstream
jieyouxu Apr 30, 2025
482ad5c
Remove redundant min-llvm-version annotations for LoongArch tests
heiher May 1, 2025
3e0cbbb
adds 'with' to help clarify how to build a new compiler
martinomburajr May 1, 2025
27eb274
Preparing for merge from rustc
invalid-email-address May 1, 2025
560de7e
Merge from rustc
invalid-email-address May 1, 2025
9a3a212
adds commas
martinomburajr May 1, 2025
9ce6c52
Merge pull request #2368 from martinomburajr/master
tshepang May 1, 2025
bf06eaf
Merge pull request #2367 from rust-lang/rustc-pull
tshepang May 1, 2025
3e969d4
Move core::fmt::Arguments::new_v1* to rt.rs.
m-ou-se May 1, 2025
36c6633
Clean up "const" situation in format_args!().
m-ou-se May 1, 2025
714ea10
rustdoc: Fix doctest heuristic for main fn wrapping
fmease Apr 29, 2025
ce50b4f
Bless mir opt tests.
m-ou-se May 1, 2025
86c6e79
Bless pretty tests.
m-ou-se May 1, 2025
5d30814
allow `#[rustc_std_internal_symbol]` in combination with `#[naked]`
folkertdev May 1, 2025
bc68d3a
Improve error output in case `nodejs` or `npm` is not installed for r…
GuillaumeGomez May 1, 2025
c02964f
Rollup merge of #138703 - pudongair:master, r=workingjubilee
GuillaumeGomez May 1, 2025
bd68c36
Rollup merge of #139186 - TDecking:float, r=workingjubilee
GuillaumeGomez May 1, 2025
931735a
Rollup merge of #139780 - ongardie:iterator-take-by_ref-example, r=wo…
GuillaumeGomez May 1, 2025
b867d20
Rollup merge of #139802 - Lee-Janggun:fix-allocate-hyperlink, r=worki…
GuillaumeGomez May 1, 2025
5a25a7a
Rollup merge of #140034 - RalfJung:simd_select_bitmask-padding, r=wor…
GuillaumeGomez May 1, 2025
5170e21
Rollup merge of #140062 - xizheyin:issue-139958, r=workingjubilee
GuillaumeGomez May 1, 2025
96faee4
Rollup merge of #140420 - fmease:rustdoc-fix-doctest-heur, r=Guillaum…
GuillaumeGomez May 1, 2025
9d7d782
Rollup merge of #140460 - heiher:issue-140455, r=Urgau
GuillaumeGomez May 1, 2025
786a53d
Rollup merge of #140538 - tshepang:rust-push, r=jieyouxu
GuillaumeGomez May 1, 2025
6cb75d8
Rollup merge of #140544 - m-ou-se:format-args-const-cleanup, r=fee1-dead
GuillaumeGomez May 1, 2025
84ac890
Rollup merge of #140552 - folkertdev:naked-function-rustc_std_interna…
GuillaumeGomez May 1, 2025
d42e3ac
Rollup merge of #140556 - GuillaumeGomez:improve-rustdoc-gui-tool-err…
GuillaumeGomez May 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
rustdoc: Fix doctest heuristic for main fn wrapping
  • Loading branch information
fmease committed May 1, 2025
commit 714ea10ea41e97310a1b3d90fed4cfb3e2dd6b73
65 changes: 28 additions & 37 deletions src/librustdoc/doctest/make.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,6 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn

let filename = FileName::anon_source_code(&wrapped_source);

// Any errors in parsing should also appear when the doctest is compiled for real, so just
// send all the errors that librustc_ast emits directly into a `Sink` instead of stderr.
let sm = Arc::new(SourceMap::new(FilePathMapping::empty()));
let fallback_bundle = rustc_errors::fallback_fluent_bundle(
rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
Expand All @@ -311,7 +309,8 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
info.supports_color =
HumanEmitter::new(stderr_destination(ColorConfig::Auto), fallback_bundle.clone())
.supports_color();

// Any errors in parsing should also appear when the doctest is compiled for real, so just
// send all the errors that the parser emits directly into a `Sink` instead of stderr.
let emitter = HumanEmitter::new(Box::new(io::sink()), fallback_bundle);

// FIXME(misdreavus): pass `-Z treat-err-as-bug` to the doctest parser
Expand Down Expand Up @@ -339,9 +338,6 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
*prev_span_hi = hi;
}

// Recurse through functions body. It is necessary because the doctest source code is
// wrapped in a function to limit the number of AST errors. If we don't recurse into
// functions, we would thing all top-level items (so basically nothing).
fn check_item(item: &ast::Item, info: &mut ParseSourceInfo, crate_name: &Option<&str>) -> bool {
let mut is_extern_crate = false;
if !info.has_global_allocator
Expand All @@ -351,8 +347,6 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
}
match item.kind {
ast::ItemKind::Fn(ref fn_item) if !info.has_main_fn => {
// We only push if it's the top item because otherwise, we would duplicate
// its content since the top-level item was already added.
if fn_item.ident.name == sym::main {
info.has_main_fn = true;
}
Expand Down Expand Up @@ -412,44 +406,41 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
let mut is_extern_crate = false;
match stmt.kind {
StmtKind::Item(ref item) => {
is_extern_crate = check_item(&item, &mut info, crate_name);
}
StmtKind::Expr(ref expr) => {
if matches!(expr.kind, ast::ExprKind::Err(_)) {
reset_error_count(&psess);
return Err(());
}
has_non_items = true;
is_extern_crate = check_item(item, &mut info, crate_name);
}
// We assume that the macro calls will expand to item(s) even though they could
// expand to statements and expressions. And the simple fact that we're trying
// to retrieve a `main` function inside it is a terrible idea.
// expand to statements and expressions.
StmtKind::MacCall(ref mac_call) => {
if info.has_main_fn {
continue;
}
let mut iter = mac_call.mac.args.tokens.iter();

while let Some(token) = iter.next() {
if let TokenTree::Token(token, _) = token
&& let TokenKind::Ident(name, _) = token.kind
&& name == kw::Fn
&& let Some(TokenTree::Token(fn_token, _)) = iter.peek()
&& let TokenKind::Ident(fn_name, _) = fn_token.kind
&& fn_name == sym::main
&& let Some(TokenTree::Delimited(_, _, Delimiter::Parenthesis, _)) = {
iter.next();
iter.peek()
if !info.has_main_fn {
// For backward compatibility, we look for the token sequence `fn main(…)`
// in the macro input (!) to crudely detect main functions "masked by a
// wrapper macro". For the record, this is a horrible heuristic!
// See <https://github.com/rust-lang/rust/issues/56898>.
let mut iter = mac_call.mac.args.tokens.iter();
while let Some(token) = iter.next() {
if let TokenTree::Token(token, _) = token
&& let TokenKind::Ident(kw::Fn, _) = token.kind
&& let Some(TokenTree::Token(ident, _)) = iter.peek()
&& let TokenKind::Ident(sym::main, _) = ident.kind
&& let Some(TokenTree::Delimited(.., Delimiter::Parenthesis, _)) = {
iter.next();
iter.peek()
}
{
info.has_main_fn = true;
break;
}
{
info.has_main_fn = true;
break;
}
}
}
_ => {
StmtKind::Expr(ref expr) => {
if matches!(expr.kind, ast::ExprKind::Err(_)) {
reset_error_count(&psess);
return Err(());
}
has_non_items = true;
}
StmtKind::Let(_) | StmtKind::Semi(_) | StmtKind::Empty => has_non_items = true,
}

// Weirdly enough, the `Stmt` span doesn't include its attributes, so we need to
Expand Down
1 change: 1 addition & 0 deletions tests/rustdoc-ui/doctest/auxiliary/items.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fn item() {}
1 change: 0 additions & 1 deletion tests/rustdoc-ui/doctest/auxiliary/macro-after-main.rs

This file was deleted.

16 changes: 0 additions & 16 deletions tests/rustdoc-ui/doctest/macro-after-main.rs

This file was deleted.

6 changes: 0 additions & 6 deletions tests/rustdoc-ui/doctest/macro-after-main.stdout

This file was deleted.

60 changes: 60 additions & 0 deletions tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

running 4 tests
test $DIR/main-alongside-macro-calls.rs - (line 19) ... ok
test $DIR/main-alongside-macro-calls.rs - (line 24) ... ok
test $DIR/main-alongside-macro-calls.rs - (line 28) ... FAILED
test $DIR/main-alongside-macro-calls.rs - (line 33) ... FAILED

failures:

---- $DIR/main-alongside-macro-calls.rs - (line 28) stdout ----
error: macros that expand to items must be delimited with braces or followed by a semicolon
--> $DIR/main-alongside-macro-calls.rs:30:1
|
LL | println!();
| ^^^^^^^^^^
|
= note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

error: macro expansion ignores `{` and any tokens following
--> $SRC_DIR/std/src/macros.rs:LL:COL
|
::: $DIR/main-alongside-macro-calls.rs:30:1
|
LL | println!();
| ---------- caused by the macro expansion here
|
= note: the usage of `print!` is likely invalid in item context

error: aborting due to 2 previous errors

Couldn't compile the test.
---- $DIR/main-alongside-macro-calls.rs - (line 33) stdout ----
error: macros that expand to items must be delimited with braces or followed by a semicolon
--> $DIR/main-alongside-macro-calls.rs:34:1
|
LL | println!();
| ^^^^^^^^^^
|
= note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

error: macro expansion ignores `{` and any tokens following
--> $SRC_DIR/std/src/macros.rs:LL:COL
|
::: $DIR/main-alongside-macro-calls.rs:34:1
|
LL | println!();
| ---------- caused by the macro expansion here
|
= note: the usage of `print!` is likely invalid in item context

error: aborting due to 2 previous errors

Couldn't compile the test.

failures:
$DIR/main-alongside-macro-calls.rs - (line 28)
$DIR/main-alongside-macro-calls.rs - (line 33)

test result: FAILED. 2 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

running 4 tests
test $DIR/main-alongside-macro-calls.rs - (line 19) ... ok
test $DIR/main-alongside-macro-calls.rs - (line 24) ... ok
test $DIR/main-alongside-macro-calls.rs - (line 28) - compile fail ... ok
test $DIR/main-alongside-macro-calls.rs - (line 33) - compile fail ... ok

test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME

44 changes: 44 additions & 0 deletions tests/rustdoc-ui/doctest/main-alongside-macro-calls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// This test ensures that if there is are any macro calls alongside a `main` function,
// it will indeed consider the `main` function as the program entry point and *won't*
// generate its own `main` function to wrap everything even though macro calls are
// valid in statement contexts, too, and could just as well expand to statements or
// expressions (we don't perform any macro expansion to find `main`, see also
// <https://github.com/rust-lang/rust/issues/57415>).
//
// See <./main-alongside-stmts.rs> for comparison.
//
//@ compile-flags:--test --test-args --test-threads=1
//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
//@ revisions: pass fail
//@[pass] check-pass
//@[fail] failure-status: 101

// Regression test for <https://github.com/rust-lang/rust/pull/140220#issuecomment-2831872920>:

//! ```
//! fn main() {}
//! include!("./auxiliary/items.rs");
//! ```
//!
//! ```
//! include!("./auxiliary/items.rs");
//! fn main() {}
//! ```

// Regression test for <https://github.com/rust-lang/rust/issues/140412>:
// We test the "same" thing twice: Once via `compile_fail` to more closely mirror the reported
// regression and once without it to make sure that it leads to the expected rustc errors,
// namely `println!(…)` not being valid in item contexts.

#![cfg_attr(pass, doc = " ```compile_fail")]
#![cfg_attr(fail, doc = " ```")]
//! fn main() {}
//! println!();
//! ```
//!
#![cfg_attr(pass, doc = " ```compile_fail")]
#![cfg_attr(fail, doc = " ```")]
//! println!();
//! fn main() {}
//! ```
33 changes: 33 additions & 0 deletions tests/rustdoc-ui/doctest/main-alongside-stmts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// This test ensures that if there is are any statements alongside a `main` function,
// it will not consider the `main` function as the program entry point but instead
// will generate its own `main` function to wrap everything as it needs to reside in a
// module where only *items* are permitted syntactically.
//
// See <./main-alongside-macro-calls.rs> for comparison.
//
// This is a regression test for:
// * <https://github.com/rust-lang/rust/issues/140162>
// * <https://github.com/rust-lang/rust/issues/139651>
//
//@ compile-flags:--test --test-args --test-threads=1
//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
//@ check-pass

//! ```
//! # if cfg!(miri) { return; }
//! use std::ops::Deref;
//!
//! fn main() {
//! assert!(false);
//! }
//! ```
//!
//! ```
//! let x = 2;
//! assert_eq!(x, 2);
//!
//! fn main() {
//! assert!(false);
//! }
//! ```
7 changes: 7 additions & 0 deletions tests/rustdoc-ui/doctest/main-alongside-stmts.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

running 2 tests
test $DIR/main-alongside-stmts.rs - (line 17) ... ok
test $DIR/main-alongside-stmts.rs - (line 26) ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME

22 changes: 0 additions & 22 deletions tests/rustdoc-ui/doctest/test-main-alongside-exprs.rs

This file was deleted.

6 changes: 0 additions & 6 deletions tests/rustdoc-ui/doctest/test-main-alongside-exprs.stdout

This file was deleted.

Loading