Skip to content

Conversation

@Kivooeo
Copy link
Member

@Kivooeo Kivooeo commented Oct 6, 2025

Fixes #147255

The problem original was from that stmt.span was from expansion and it span was bigger than right part which is block.span, so it causes empty span and panic later on, I decided to add checks for both of them to be on the safe side

r? @fmease (you were in discussion on this issue so I decided to assign you, feel free to reroll)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 6, 2025
@rustbot
Copy link
Collaborator

rustbot commented Oct 6, 2025

fmease is not on the review rotation at the moment.
They may take a while to respond.

@chenyukang
Copy link
Member

these errors are recurring, how can we implement a long-term fix.
i remember we had a try, but it was blocked by performance regression.

@Kivooeo
Copy link
Member Author

Kivooeo commented Oct 7, 2025

This should not affect performance. As for a long-term fix, I’m not sure we can implement one, since it may occur in unexpected places. We can probably fix issues like this only gradually over time

@Kivooeo
Copy link
Member Author

Kivooeo commented Oct 7, 2025

For example this ICE was since 1.86, which is pretty old, but I have no idea what has changed after 1.85 that could break this

@chenyukang
Copy link
Member

This should not affect performance. As for a long-term fix, I’m not sure we can implement one, since it may occur in unexpected places. We can probably fix issues like this only gradually over time

i'm referring this one which have perf regression: #109082

i have a revisit on that PR, seems it was fixing a different issue (but general in similar kind).

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Oct 14, 2025
Add check if span is from macro expansion

The same thing I did in rust-lang#147416, actually the same bug but in another place, I'm not really sure how this method is good for fixing such ICEs, but, it does work and not conflicting with any existing tests, so I guess, it's fine

Fixes rust-lang#147408

r? compiler
jdonszelmann added a commit to jdonszelmann/rust that referenced this pull request Oct 14, 2025
Add check if span is from macro expansion

The same thing I did in rust-lang#147416, actually the same bug but in another place, I'm not really sure how this method is good for fixing such ICEs, but, it does work and not conflicting with any existing tests, so I guess, it's fine

Fixes rust-lang#147408

r? compiler
return;
};
if block.expr.is_some() {
if block.expr.is_some() || block.span.from_expansion() {
Copy link
Member

Choose a reason for hiding this comment

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

Using .from_expansion() is always a "heavy hammer" (see also #147577 (comment)) since it leads to us flat out suppressing diagnostics once macros are in the vicinity even if they don't pose any problem.

In #147255 (comment), you wrote that tail_expr.span and stmt.span were identical. However, that seems a bit surprising to me because "usually" (i.e.., when no macros are involved), the stmt span should include the ; while the expr span should not. Consider:

fn main() {
    let s = {
        "hello"    ;
    };
    println!("{}", s);
}

Using a nightly/master rustc (output trimmed by me):

error[E0277]: `()` doesn't implement `std::fmt::Display`
 --> src/main.rs:5:20
  |
3 |         "hello"    ;
  |                ----- help: remove this semicolon
4 |     };

As you probably already know with stmt.span.with_lo(tail_expr.span.hi()) later on we try to "diff" the stmt span (which includes the semicolon) with the inner expr one (which can include whitespace as seen above for demo purposes).

I mean I have no reason to doubt that what you wrote in #147255 (comment) is accurate. If they indeed the same span if a macro is involved, then I would consider that a bug / unfortunate decision in macro expansion (it would ignore the SyntaxContext of the ; when marking or concatenating Spans maybe)?

If they were different, we could then simply tail_expr.span.find_ancestor_in_same_ctxt(stmt.span) and use that inside stmt.span.with_lo(_).

Copy link
Member

@fmease fmease Nov 6, 2025

Choose a reason for hiding this comment

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

Using .from_expansion() is always a "heavy hammer" (see also #147577 (comment)) since it leads to us flat out suppressing diagnostics once macros are in the vicinity even if they don't pose any problem.

E.g., it means that under your PR we would suppress the semicolon suggestion in the following case I'm pretty sure:

fn main() {
    macro_rules! generate {
        () => {{
            "txt";
        }}
    }

    let s = generate!();
    println!("{}", s);
}

Even though the suggestion would be perfectly fine and correct as s seen on nightly/master:

error[E0277]: `()` doesn't implement `std::fmt::Display`
 --> src/main.rs:9:20
  |
4 |             "txt";
  |                  - help: remove this semicolon

Copy link
Member

@fmease fmease Nov 6, 2025

Choose a reason for hiding this comment

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

If they indeed the same span if a macro is involved,

Yeah, it looks like you're absolutely right. For fn main() { ""; } the expr.span ("") and stmt.span ("";) are obv. different but for macro_rules! s { () = { "" } } fn main() { s!(); }, stmt.span (s!();) and expr.span (s!()) are the same! Unbelievable.

I wonder if that's intentional (simplicity of implementation) or a bug we can easily fix.

Copy link
Member

@fmease fmease Nov 6, 2025

Choose a reason for hiding this comment

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

I wonder if that's intentional (simplicity of implementation) or a bug we can easily fix.

IMO, this is the real fix. Remember, at a high-level we're simply trying to compute the "span of the semicolon" by diffing two spans but that sadly doesn't work correctly because the stmt&expr span are the same if the expr is a macro call, as a result the span is empty (as you've already come to realize) and the suggestion is also empty (since it's a removal).

So, the debug assert from the linked issue uncovered a real bug which is its purpose.

Copy link
Member Author

Choose a reason for hiding this comment

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

I wonder if we can just do this instead (or something similar for empty span) #147255 (comment)

Maybe even under some FIXME comment with link to this

Because as you pointed correctly, current approach does suppress a semicolon suggestion in macro which is incorrect

Copy link
Member

Choose a reason for hiding this comment

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

(Please my earlier comments for more context)

Please remove the two .from_expansion() calls and instead do the following in order to get rid of the false negative I've mentioned in #147416 (the generate example).

- if self.predicate_must_hold_modulo_regions(&new_obligation) {
+ if self.predicate_must_hold_modulo_regions(&new_obligation)
+     // [NOTE or FIXME re. expr & stmt having the same span if expr comes from an expansion]
+     && stmt.span.eq_ctxt(tail_expr.span)
+ {
      err.span_suggestion_short(
          stmt.span.with_lo(tail_expr.span.hi()),
          "remove this semicolon",
          "",
          Applicability::MachineApplicable,
      );

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 6, 2025
@rustbot
Copy link
Collaborator

rustbot commented Nov 6, 2025

⚠️ Warning ⚠️

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

Labels

S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ICE] thread 'rustc' panicked at compiler/rustc_errors/src/diagnostic.rs:1025:9

4 participants