Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 973ec11

Browse files
committed
Auto merge of #140592 - cuviper:beta-next, r=cuviper
[beta] backports - Don't allow flattened format_args in const. #139624 - set subsections_via_symbols for ld64 helper sections #139752 - Fix detection of `main` function if there are expressions around it #140220 - rustdoc: Fix doctest heuristic for main fn wrapping #140420 - extend the list of registered dylibs on `test::prepare_cargo_test` #140563 r? cuviper
2 parents 9d6fe3d + 260fcc6 commit 973ec11

File tree

16 files changed

+274
-62
lines changed

16 files changed

+274
-62
lines changed

‎compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2011,6 +2011,12 @@ fn add_linked_symbol_object(
20112011
file.set_mangling(object::write::Mangling::None);
20122012
}
20132013

2014+
if file.format() == object::BinaryFormat::MachO {
2015+
// Divide up the sections into sub-sections via symbols for dead code stripping.
2016+
// Without this flag, unused `#[no_mangle]` or `#[used]` cannot be discard on MachO targets.
2017+
file.set_subsections_via_symbols();
2018+
}
2019+
20142020
// ld64 requires a relocation to load undefined symbols, see below.
20152021
// Not strictly needed if linking with lld, but might as well do it there too.
20162022
let ld64_section_helper = if file.format() == object::BinaryFormat::MachO {

‎library/core/src/fmt/rt.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,15 @@ impl Argument<'_> {
205205
/// let f = format_args!("{}", "a");
206206
/// println!("{f}");
207207
/// ```
208+
///
209+
/// This function should _not_ be const, to make sure we don't accept
210+
/// format_args!() and panic!() with arguments in const, even when not evaluated:
211+
///
212+
/// ```compile_fail,E0015
213+
/// const _: () = if false { panic!("a {}", "a") };
214+
/// ```
208215
#[inline]
209-
pub constfn none() -> [Self; 0] {
216+
pub fn none() -> [Self; 0] {
210217
[]
211218
}
212219
}

‎src/bootstrap/src/core/build_steps/test.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2570,9 +2570,9 @@ fn prepare_cargo_test(
25702570
// We skip everything on Miri as then this overwrites the libdir set up
25712571
// by `Cargo::new` and that actually makes things go wrong.
25722572
if builder.kind != Kind::Miri {
2573-
let mut dylib_path = dylib_path();
2574-
dylib_path.insert(0,PathBuf::from(&*builder.sysroot_target_libdir(compiler, target)));
2575-
cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
2573+
let mut dylib_paths = builder.rustc_lib_paths(compiler);
2574+
dylib_paths.push(PathBuf::from(&builder.sysroot_target_libdir(compiler, target)));
2575+
helpers::add_dylib_path(dylib_paths,&mut cargo);
25762576
}
25772577

25782578
if builder.remote_tested(target) {

‎src/librustdoc/doctest/make.rs

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,6 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
301301

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

304-
// Any errors in parsing should also appear when the doctest is compiled for real, so just
305-
// send all the errors that librustc_ast emits directly into a `Sink` instead of stderr.
306304
let sm = Arc::new(SourceMap::new(FilePathMapping::empty()));
307305
let fallback_bundle = rustc_errors::fallback_fluent_bundle(
308306
rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
@@ -311,7 +309,8 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
311309
info.supports_color =
312310
HumanEmitter::new(stderr_destination(ColorConfig::Auto), fallback_bundle.clone())
313311
.supports_color();
314-
312+
// Any errors in parsing should also appear when the doctest is compiled for real, so just
313+
// send all the errors that the parser emits directly into a `Sink` instead of stderr.
315314
let emitter = HumanEmitter::new(Box::new(io::sink()), fallback_bundle);
316315

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

342-
// Recurse through functions body. It is necessary because the doctest source code is
343-
// wrapped in a function to limit the number of AST errors. If we don't recurse into
344-
// functions, we would thing all top-level items (so basically nothing).
345341
fn check_item(item: &ast::Item, info: &mut ParseSourceInfo, crate_name: &Option<&str>) -> bool {
346342
let mut is_extern_crate = false;
347343
if !info.has_global_allocator
@@ -351,8 +347,6 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
351347
}
352348
match item.kind {
353349
ast::ItemKind::Fn(_) if !info.has_main_fn => {
354-
// We only push if it's the top item because otherwise, we would duplicate
355-
// its content since the top-level item was already added.
356350
if item.ident.name == sym::main {
357351
info.has_main_fn = true;
358352
}
@@ -411,37 +405,46 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
411405
push_to_s(&mut info.crate_attrs, source, attr.span, &mut prev_span_hi);
412406
}
413407
}
408+
let mut has_non_items = false;
414409
for stmt in &body.stmts {
415410
let mut is_extern_crate = false;
416411
match stmt.kind {
417412
StmtKind::Item(ref item) => {
418-
is_extern_crate = check_item(&item, &mut info, crate_name);
419-
}
420-
StmtKind::Expr(ref expr) if matches!(expr.kind, ast::ExprKind::Err(_)) => {
421-
reset_error_count(&psess);
422-
return Err(());
413+
is_extern_crate = check_item(item, &mut info, crate_name);
423414
}
424-
StmtKind::MacCall(ref mac_call) if !info.has_main_fn => {
425-
let mut iter = mac_call.mac.args.tokens.iter();
426-
427-
while let Some(token) = iter.next() {
428-
if let TokenTree::Token(token, _) = token
429-
&& let TokenKind::Ident(name, _) = token.kind
430-
&& name == kw::Fn
431-
&& let Some(TokenTree::Token(fn_token, _)) = iter.peek()
432-
&& let TokenKind::Ident(fn_name, _) = fn_token.kind
433-
&& fn_name == sym::main
434-
&& let Some(TokenTree::Delimited(_, _, Delimiter::Parenthesis, _)) = {
435-
iter.next();
436-
iter.peek()
415+
// We assume that the macro calls will expand to item(s) even though they could
416+
// expand to statements and expressions.
417+
StmtKind::MacCall(ref mac_call) => {
418+
if !info.has_main_fn {
419+
// For backward compatibility, we look for the token sequence `fn main(...)`
420+
// in the macro input (!) to crudely detect main functions "masked by a
421+
// wrapper macro". For the record, this is a horrible heuristic!
422+
// See <https://github.com/rust-lang/rust/issues/56898>.
423+
let mut iter = mac_call.mac.args.tokens.iter();
424+
while let Some(token) = iter.next() {
425+
if let TokenTree::Token(token, _) = token
426+
&& let TokenKind::Ident(kw::Fn, _) = token.kind
427+
&& let Some(TokenTree::Token(ident, _)) = iter.peek()
428+
&& let TokenKind::Ident(sym::main, _) = ident.kind
429+
&& let Some(TokenTree::Delimited(.., Delimiter::Parenthesis, _)) = {
430+
iter.next();
431+
iter.peek()
432+
}
433+
{
434+
info.has_main_fn = true;
435+
break;
437436
}
438-
{
439-
info.has_main_fn = true;
440-
break;
441437
}
442438
}
443439
}
444-
_ => {}
440+
StmtKind::Expr(ref expr) => {
441+
if matches!(expr.kind, ast::ExprKind::Err(_)) {
442+
reset_error_count(&psess);
443+
return Err(());
444+
}
445+
has_non_items = true;
446+
}
447+
StmtKind::Let(_) | StmtKind::Semi(_) | StmtKind::Empty => has_non_items = true,
445448
}
446449

447450
// Weirdly enough, the `Stmt` span doesn't include its attributes, so we need to
@@ -466,6 +469,11 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
466469
push_to_s(&mut info.crates, source, span, &mut prev_span_hi);
467470
}
468471
}
472+
if has_non_items {
473+
// FIXME: if `info.has_main_fn` is `true`, emit a warning here to mention that
474+
// this code will not be called.
475+
info.has_main_fn = false;
476+
}
469477
Ok(info)
470478
}
471479
Err(e) => {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn item() {}

‎tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
//@ compile-flags:--test
55
//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
66
//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
7-
//@ failure-status: 101
7+
//@ check-pass
88

99
/// <https://github.com/rust-lang/rust/issues/91014>
1010
///
1111
/// ```rust
12-
/// struct S {}; // unexpected semicolon after struct def
12+
/// struct S {};
1313
///
1414
/// fn main() {
1515
/// assert_eq!(0, 1);
Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,6 @@
11

22
running 1 test
3-
test $DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11) ... FAILED
3+
test $DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11) ... ok
44

5-
failures:
6-
7-
---- $DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11) stdout ----
8-
error: expected item, found `;`
9-
--> $DIR/failed-doctest-extra-semicolon-on-item.rs:12:12
10-
|
11-
LL | struct S {}; // unexpected semicolon after struct def
12-
| ^
13-
|
14-
= help: braced struct declarations are not followed by a semicolon
15-
help: remove this semicolon
16-
|
17-
LL - struct S {}; // unexpected semicolon after struct def
18-
LL + struct S {} // unexpected semicolon after struct def
19-
|
20-
21-
error: aborting due to 1 previous error
22-
23-
Couldn't compile the test.
24-
25-
failures:
26-
$DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11)
27-
28-
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
5+
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
296

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
2+
running 4 tests
3+
test $DIR/main-alongside-macro-calls.rs - (line 19) ... ok
4+
test $DIR/main-alongside-macro-calls.rs - (line 24) ... ok
5+
test $DIR/main-alongside-macro-calls.rs - (line 28) ... FAILED
6+
test $DIR/main-alongside-macro-calls.rs - (line 33) ... FAILED
7+
8+
failures:
9+
10+
---- $DIR/main-alongside-macro-calls.rs - (line 28) stdout ----
11+
error: macros that expand to items must be delimited with braces or followed by a semicolon
12+
--> $DIR/main-alongside-macro-calls.rs:30:1
13+
|
14+
LL | println!();
15+
| ^^^^^^^^^^
16+
|
17+
= note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
18+
19+
error: macro expansion ignores `{` and any tokens following
20+
--> $SRC_DIR/std/src/macros.rs:LL:COL
21+
|
22+
::: $DIR/main-alongside-macro-calls.rs:30:1
23+
|
24+
LL | println!();
25+
| ---------- caused by the macro expansion here
26+
|
27+
= note: the usage of `print!` is likely invalid in item context
28+
29+
error: aborting due to 2 previous errors
30+
31+
Couldn't compile the test.
32+
---- $DIR/main-alongside-macro-calls.rs - (line 33) stdout ----
33+
error: macros that expand to items must be delimited with braces or followed by a semicolon
34+
--> $DIR/main-alongside-macro-calls.rs:34:1
35+
|
36+
LL | println!();
37+
| ^^^^^^^^^^
38+
|
39+
= note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
40+
41+
error: macro expansion ignores `{` and any tokens following
42+
--> $SRC_DIR/std/src/macros.rs:LL:COL
43+
|
44+
::: $DIR/main-alongside-macro-calls.rs:34:1
45+
|
46+
LL | println!();
47+
| ---------- caused by the macro expansion here
48+
|
49+
= note: the usage of `print!` is likely invalid in item context
50+
51+
error: aborting due to 2 previous errors
52+
53+
Couldn't compile the test.
54+
55+
failures:
56+
$DIR/main-alongside-macro-calls.rs - (line 28)
57+
$DIR/main-alongside-macro-calls.rs - (line 33)
58+
59+
test result: FAILED. 2 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
60+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
running 4 tests
3+
test $DIR/main-alongside-macro-calls.rs - (line 19) ... ok
4+
test $DIR/main-alongside-macro-calls.rs - (line 24) ... ok
5+
test $DIR/main-alongside-macro-calls.rs - (line 28) - compile fail ... ok
6+
test $DIR/main-alongside-macro-calls.rs - (line 33) - compile fail ... ok
7+
8+
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
9+
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// This test ensures that if there is are any macro calls alongside a `main` function,
2+
// it will indeed consider the `main` function as the program entry point and *won't*
3+
// generate its own `main` function to wrap everything even though macro calls are
4+
// valid in statement contexts, too, and could just as well expand to statements or
5+
// expressions (we don't perform any macro expansion to find `main`, see also
6+
// <https://github.com/rust-lang/rust/issues/57415>).
7+
//
8+
// See <./main-alongside-stmts.rs> for comparison.
9+
//
10+
//@ compile-flags:--test --test-args --test-threads=1
11+
//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
12+
//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
13+
//@ revisions: pass fail
14+
//@[pass] check-pass
15+
//@[fail] failure-status: 101
16+
17+
// Regression test for <https://github.com/rust-lang/rust/pull/140220#issuecomment-2831872920>:
18+
19+
//! ```
20+
//! fn main() {}
21+
//! include!("./auxiliary/items.rs");
22+
//! ```
23+
//!
24+
//! ```
25+
//! include!("./auxiliary/items.rs");
26+
//! fn main() {}
27+
//! ```
28+
29+
// Regression test for <https://github.com/rust-lang/rust/issues/140412>:
30+
// We test the "same" thing twice: Once via `compile_fail` to more closely mirror the reported
31+
// regression and once without it to make sure that it leads to the expected rustc errors,
32+
// namely `println!(...)` not being valid in item contexts.
33+
34+
#![cfg_attr(pass, doc = " ```compile_fail")]
35+
#![cfg_attr(fail, doc = " ```")]
36+
//! fn main() {}
37+
//! println!();
38+
//! ```
39+
//!
40+
#![cfg_attr(pass, doc = " ```compile_fail")]
41+
#![cfg_attr(fail, doc = " ```")]
42+
//! println!();
43+
//! fn main() {}
44+
//! ```

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /