Skip to content

Fix ICE when const closure appears inside a non-const trait method#154957

Merged
rust-bors[bot] merged 1 commit intorust-lang:mainfrom
lapla-cogito:issue_153891
Apr 23, 2026
Merged

Fix ICE when const closure appears inside a non-const trait method#154957
rust-bors[bot] merged 1 commit intorust-lang:mainfrom
lapla-cogito:issue_153891

Conversation

@lapla-cogito
Copy link
Copy Markdown
Contributor

@lapla-cogito lapla-cogito commented Apr 7, 2026

Fixes #153891

hir_body_const_context() unconditionally delegated to the parent's const context for const closures, returning None when the parent had no const context. This caused mir_const_qualif() to hit a span_bug!, since mir_promoted() had already decided to call it based on the closure's own syntactic constness. Fall back to ConstContext::ConstFn when the parent's const context is None, so that the const closure body is still properly const-checked rather than triggering an ICE.

Examining another attempt at this issue (which has already been closed), I thought that its approach represents a workaround fix to avoid inconsistencies in the caller of mir_promoted(), whereas I think the correct behavior is for hir_body_const_context() itself to return the proper value.

@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 Apr 7, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 7, 2026

r? @dingxiangfei2009

rustbot has assigned @dingxiangfei2009.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 69 candidates
  • Random selection from 10 candidates

Copy link
Copy Markdown
Contributor Author

@lapla-cogito lapla-cogito left a comment

Choose a reason for hiding this comment

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

I'm starting to think it would be better to explain why this patch includes two tests. These are both reproduction cases from the original issue, but I added both because the paths for determining parent constness differ until hir_body_const_context() returns None.

View changes since this review

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 21, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@oli-obk
Copy link
Copy Markdown
Contributor

oli-obk commented Apr 22, 2026

Yea, it's def a better fix than what the other PRs attempted. I tried finding a way that rejects this earlier, but it doesn't seem obvious to me how to do it robustly.

Your fix feels like it carries a risk because we are ignoring a buggy situation, but maybe that can be alleviated by asserting that an error has already been reported

@lapla-cogito
Copy link
Copy Markdown
Contributor Author

lapla-cogito commented Apr 22, 2026

Your fix feels like it carries a risk because we are ignoring a buggy situation, but maybe that can be alleviated by asserting that an error has already been reported

I see, in that case, would using span_delayed_bug() be appropriate?

edit: like

BodyOwnerKind::Closure if self.is_const_fn(def_id) => {
    if let Some(ctx) = self.hir_body_const_context(self.local_parent(local_def_id)) {
        return Some(ctx);
    }
    self.dcx().span_delayed_bug(
        self.def_span(def_id),
        "msg",
    );
    return Some(ConstContext::ConstFn);
}

@oli-obk
Copy link
Copy Markdown
Contributor

oli-obk commented Apr 22, 2026

That works, but in this case we can even just be an assert that errors were reported. We have like 2 of them in rustc, and I'm on mobile, so I can't find the function rn, but there is a function for getting an ErrorReported if any errors were emitted

@lapla-cogito
Copy link
Copy Markdown
Contributor Author

there is a function for getting an ErrorReported if any errors were emitted

Maybe you mean DiagCtxtHandle::has_errors(). I’ve just pushed a version that uses it.

Copy link
Copy Markdown
Contributor

@oli-obk oli-obk left a comment

Choose a reason for hiding this comment

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

@bors r+ rollup

Thanks! this is exactly what I was looking for

View changes since this review

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented Apr 23, 2026

📌 Commit 9be8fca has been approved by oli-obk

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 23, 2026
rust-bors Bot pushed a commit that referenced this pull request Apr 23, 2026
Rollup of 7 pull requests

Successful merges:

 - #155469 (Account for titlecase in casing lints)
 - #155644 (delegation: support self ty propagation for functions in free to trait reuse)
 - #154957 (Fix ICE when const closure appears inside a non-const trait method)
 - #155442 (Change keyword order for `impl` restrictions)
 - #155561 (Use singular wording for single _ placeholders in type suggestions)
 - #155637 (Fix E0191 suggestion for empty dyn trait args)
 - #155661 (Remove `AttributeLintKind` variants - part 6)
@rust-bors rust-bors Bot merged commit 0595fcd into rust-lang:main Apr 23, 2026
11 checks passed
@rustbot rustbot added this to the 1.97.0 milestone Apr 23, 2026
rust-timer added a commit that referenced this pull request Apr 23, 2026
Rollup merge of #154957 - lapla-cogito:issue_153891, r=oli-obk

Fix ICE when const closure appears inside a non-const trait method

Fixes #153891

`hir_body_const_context()` unconditionally delegated to the parent's const context for const closures, returning `None` when the parent had no const context. This caused `mir_const_qualif()` to hit a `span_bug!`, since `mir_promoted()` had already decided to call it based on the closure's own syntactic constness. Fall back to `ConstContext::ConstFn` when the parent's const context is `None`, so that the const closure body is still properly const-checked rather than triggering an ICE.

Examining [another attempt](https://github.com/rust-lang/rust/pull/153900/changes) at this issue (which has already been closed), I thought that its approach represents a workaround fix to avoid inconsistencies in the caller of `mir_promoted()`, whereas I think the correct behavior is for `hir_body_const_context()` itself to return the proper value.
@lapla-cogito lapla-cogito deleted the issue_153891 branch April 23, 2026 22:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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]: mir_const_qualif should only be called on const fns and const items

4 participants