Skip to content

Fix #2640: Handle hidden crate attributes in fn main wrapping#3041

Open
cobyfrombrooklyn-bot wants to merge 1 commit intorust-lang:masterfrom
cobyfrombrooklyn-bot:fix-issue-2640
Open

Fix #2640: Handle hidden crate attributes in fn main wrapping#3041
cobyfrombrooklyn-bot wants to merge 1 commit intorust-lang:masterfrom
cobyfrombrooklyn-bot:fix-issue-2640

Conversation

@cobyfrombrooklyn-bot
Copy link

Problem

When a playground code block contains a hidden crate-level attribute (e.g. # #![feature(rustc_attrs)]) and no explicit fn main, the attribute gets placed inside the generated fn main() instead of before it. This causes the playground "play" button to produce compilation errors.

As @ehuss identified, the issue is in the regex used by partition_rust_source — it doesn't account for the # hidden line prefix, so # #![feature(...)] isn't recognized as a crate-level attribute.

Fix

Updated the HEADER_RE regex in partition_rust_source to optionally match the # (hash-space) hidden line prefix before crate-level inner attributes (#![...]).

Before: ^[ \t]*\#!\[
After: ^[ \t]*(?:\#\x20)?[ \t]*\#!\[

Test

  • 3 unit tests for wrap_rust_main (basic wrapping, hidden feature attr, already-has-main)
  • 1 unit test addition to partition_rust_source for hidden prefix case
  • 1 integration test (playground_hidden_feature_attr) with a code block using # #![feature(rustc_attrs)]
  • Full test suite passes on macOS ARM (Apple Silicon): 119 tests, 0 failures

The partition_rust_source regex did not account for lines with the hidden
line prefix (`# `), so `# #![feature(...)]` was not recognized as a
crate-level attribute. This caused wrap_rust_main to place the attribute
inside fn main() instead of before it, breaking playground execution for
code blocks with hidden feature attributes and no explicit fn main.

Updated the HEADER_RE regex to optionally match the `# ` hidden line
prefix before crate-level inner attributes.

Added unit tests for wrap_rust_main and partition_rust_source covering
the hidden prefix case, plus an integration test with a playground code
block using a hidden feature attribute.
@rustbot rustbot added the S-waiting-on-review Status: waiting on a review label Feb 26, 2026
(
(?:
^[ \t]*\#!\[.* (?:\r?\n)?
^[ \t]*(?:\#\x20)?[ \t]*\#!\[.* (?:\r?\n)?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this have \x20? This doesn't seem to have the same understanding of hidden lines as the rest of the code does.

Also, this seems to not also update the blank lines rule.

I would expect the following to work:

Input Output Hidden
#!feature(x) #!feature(x) Not hidden
##!feature(x) #!feature(x) Not hidden
# #![feature(x) #!feature(x) Hidden
# #![feature(x)
#
# #![feature(y)]
#![feature(x)

#![feature(y)]
Hidden

Perhaps it would be best to extract the hide-lines logic from hide_lines_rust so that there could be an iterator over the rust source lines that indicates if a line is hidden or not, and then these different parts could reuse that logic. rustdoc does something like this here with an enum that represents whether a line is hidden.

@ehuss
Copy link
Contributor

ehuss commented Feb 27, 2026

BTW, pull requests that fix an issue should use one of GitHub's keywords in the description (like Fixes #2640) so that the issue gets linked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: waiting on a review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants