Mehdi Akiki
Rust Failure Atlas / Language and diagnostics

RFA-640 · Case file with fixtures · Case 612 of 694 · Compiler evidence

An Unterminated Block Comment Can Hide the Rest of a Source File

Fix the earliest unmatched comment boundary before chasing downstream syntax errors. Prefer line comments for short notes and test any generator that nests or splices comment text.

Reviewed
Rust
Rust 1.98.1, edition 2024
Targets
all Rust targets
Profiles
dev, release, test

Direct answer

What this Rust failure means

Why it happens
A hand edit or generated fragment broke lexical nesting, hiding the remainder of the source before parsing and type checking.
First discriminating check
Repair the earliest unmatched comment boundary, count nested delimiters, and compile generated output with delimiter-heavy fixtures.

A block comment begins with /* and must eventually close with */. Without that closing boundary, the lexer cannot see the intended functions, braces, or modules which follow. The failing fixture leaves a migration note open and receives E0758.

Repair the first lexical boundary

An unterminated token often creates many later errors because the compiler is no longer reading the same token stream the author sees. I start at the first E0758 location and inspect the surrounding delimiters rather than fixing a reported missing brace near the end of the file.

The official E0758 explanation covers ordinary and documentation block comments. The Reference documents comments, including nested block comments.

The repaired fixture closes the note before executable code resumes. This small change restores the token structure.

Rust block comments can nest

Unlike in several languages, Rust block comments support nesting. That is convenient when temporarily surrounding code already containing block comments. It also means every nested /* needs a corresponding */.

I count depth from the opening reported by rustc. Editor bracket or syntax highlighting helps, but generated text and pasted documentation can confuse highlighting too. Reducing the region to a minimal fixture confirms which delimiter is unmatched.

For short notes I prefer //. Line comments cannot consume the next function by missing a closing delimiter. For API docs I use /// or //! according to the intended target so rustdoc owns the structure.

Commenting out code is a weak configuration system

Large block comments around old implementations accumulate stale syntax and nested delimiters. Version control already preserves removed code. I delete dead paths or put genuine build variants behind reviewed cfg conditions and tests.

cfg is not free either: disabled code may be parsed in some contexts and can rot if CI never selects it. Every supported configuration should have a build job. Temporary local experimentation should not become a permanent commented archive.

Comments explain why a constraint or decision exists. They should not duplicate code line by line. A migration note belongs near the compatibility boundary and ideally links to a test or issue that will tell us when it can be removed.

Generated source needs delimiter-safe composition

A generator which inserts arbitrary user text inside /* ... */ must handle nested delimiters correctly. Escaping comments through string replacement is fragile, especially when inputs can contain Rust source.

I prefer generating line comments one line at a time, emitting documentation through token-aware APIs, or keeping metadata in strings where literal escaping rules are explicit. Procedural macros receive token streams after lexical analysis, while build scripts that concatenate .rs files must create valid source themselves.

Generated-code tests include inputs containing /*, */, quotes, raw-string fences, and non-ASCII text. I compile the output rather than only snapshotting it, because a visually plausible snapshot may still tokenize differently.

Security and operations can be affected

If a closing delimiter disappears around authorization or feature code, compilation normally fails safely. More subtle generation bugs can comment out only a branch while leaving a valid program. Tests must verify behaviour, not only successful compilation.

I do not place secrets in comments. They remain in source history and may be embedded in generated artefacts or diagnostics. Structured configuration and secret stores are the correct channels.

The Reference’s input format helps separate decoding and token concerns from later parsing. When source arrives through tooling, I preserve UTF-8 and inspect the actual generated bytes if locations seem impossible.

My E0758 checklist

  • Where is the earliest unmatched /* or /*! reported?
  • Are nested openings and closings balanced from that point?
  • Are later parser errors only consequences of the hidden source tail?
  • Would //, ///, or //! better fit this comment’s scope?
  • Is commented-out code better removed or represented by tested configuration?
  • Did a template or generator insert delimiter-like user text?
  • Do generated-source tests compile hostile delimiter inputs?
  • After the repair, do behaviour tests prove no branch was unintentionally commented out?

The core principle is that comments participate in lexical structure even though they produce no runtime value. E0758 identifies a source boundary that never ended. I repair it first, then make comments and generators less able to hide meaningful code accidentally.