Skip to content

Fix an ICE observed with an explicit tail-call in a default trait method#145270

Merged
rust-bors[bot] merged 1 commit intorust-lang:mainfrom
jakubadamw:issue-144985
Apr 20, 2026
Merged

Fix an ICE observed with an explicit tail-call in a default trait method#145270
rust-bors[bot] merged 1 commit intorust-lang:mainfrom
jakubadamw:issue-144985

Conversation

@jakubadamw
Copy link
Copy Markdown
Contributor

@jakubadamw jakubadamw commented Aug 11, 2025

View all comments

tracking issue: #112788

Right now, explicit tail-calls cannot be used in functions that hold the #[track_caller] attribute. This check is performed on a resolved concrete instance of a function, which would be absent for a tail-call performed from the body of a default trait method. This PR fixes the issue by checking for the relevant attribute in default trait methods separately, without expecting a specific resolved instance.

Closes #144985.

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Aug 11, 2025

r? @lcnr

rustbot has assigned @lcnr.
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

@rustbot rustbot added F-explicit_tail_calls `#![feature(explicit_tail_calls)]` 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 Aug 11, 2025
@jakubadamw jakubadamw changed the title Fix an ICE observed with an explicit tail call in a default trait method Fix an ICE observed with an explicit tail-call in a default trait method Aug 11, 2025
@rust-log-analyzer

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@compiler-errors compiler-errors left a comment

Choose a reason for hiding this comment

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

I don't think this is the right approach. Frankly, using caller_ty seems a bit unnecessary throughout check_tail_calls, though that's preexisting.

I think it's better if we refactor check_tail_calls to no longer rely at all on caller_ty and instead just have a body def id which corresponds to the item that has the THIR. We shouldn't need substs either -- those are always identity.

Then we shouldn't need to use Instance::expect_resolve at all here.

@jakubadamw
Copy link
Copy Markdown
Contributor Author

I don't think this is the right approach. Frankly, using caller_ty seems a bit unnecessary throughout check_tail_calls, though that's preexisting.

I think it's better if we refactor check_tail_calls to no longer rely at all on caller_ty and instead just have a body def id which corresponds to the item that has the THIR. We shouldn't need substs either -- those are always identity.

Then we shouldn't need to use Instance::expect_resolve at all here.

Thank you for your feedback! I addressed it. There's a test failing in LLVM codegen, but this may be a pre-existing issue.

@rust-log-analyzer

This comment has been minimized.

@compiler-errors
Copy link
Copy Markdown
Contributor

compiler-errors commented Aug 12, 2025

Unfortunately, that's a legitimate bug.

I think the problem with #[track_caller] is deeper than this -- specifically, I think we actually need to disallow calling #[track_caller] functions altogether (which I think we can only check for during monomorphization), or at least we need to be adjusting such calls to a "reify shim" when monomorphizing those tail calls, though I think that ends up leading to us pushing a stack frame which seems not good.

I'm gonna mark this as blocked on #145321 (edit: actually #144755)

@rustbot blocked


As a side-note, please make sure your commits are squashed. It's not a requirement that you have 1 commit per PR, but this PR definitely shouldn't need 4 commits for a single change like this :)

@rustbot rustbot added S-blocked Status: Blocked on something else such as an RFC or other implementation work. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 12, 2025
@lcnr
Copy link
Copy Markdown
Contributor

lcnr commented Aug 13, 2025

r? compiler-errors

@rustbot rustbot assigned compiler-errors and unassigned lcnr Aug 13, 2025
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Aug 13, 2025

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

@jakubadamw
Copy link
Copy Markdown
Contributor Author

jakubadamw commented Aug 14, 2025

I think the problem with #[track_caller] is deeper than this -- specifically, I think we actually need to disallow calling #[track_caller] functions altogether (which I think we can only check for during monomorphization), or at least we need to be adjusting such calls to a "reify shim" when monomorphizing those tail calls, though I think that ends up leading to us pushing a stack frame which seems not good.

I'm gonna mark this as blocked on #145321 (edit: actually #144755)

@compiler-errors, thanks for elaborating on this!

So, as I gather from #145321 and #144755, if this is a pre-existing issue, would it be okay for us to move forward with this PR if we change the relevant test to be check-pass rather than run-pass, and let the codegen issue be independently covered by #145321?

As a side-note, please make sure your commits are squashed. It's not a requirement that you have 1 commit per PR, but this PR definitely shouldn't need 4 commits for a single change like this :)

Sure. I tend to make a commit per a logical chunk of work, and then in the course of PR’s review, only add new commits to make it clear what new changes have been made. But, of course, I’ll adjust and squash this, if you can confirm that converting the test to check-pass would be a sensible change.

@bors
Copy link
Copy Markdown
Collaborator

bors commented Aug 15, 2025

☔ The latest upstream changes (presumably #145423) made this pull request unmergeable. Please resolve the merge conflicts.

@Dylan-DPC Dylan-DPC added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-blocked Status: Blocked on something else such as an RFC or other implementation work. labels Oct 14, 2025
@Dylan-DPC
Copy link
Copy Markdown
Member

unblocking as #144755 is resolved

@WaffleLapkin
Copy link
Copy Markdown
Member

@jakubadamw could you rebase this PR?

@folkertdev
Copy link
Copy Markdown
Contributor

@jakubadamw looks like you've opened some PRs here again, any chance you can rebase this? We'd like to move forward here, so if you're not able to that's also fine and we'll take it from here.

I tried to rebase locally but keep running into some weird linting errors, but maybe I'm missing something.

@folkertdev
Copy link
Copy Markdown
Contributor

Turns out the troublesome lint was not properly registered. I've got things working on this branch main...folkertdev:rust:tail-call-trait-method, feel free to take things from there, otherwise I'll force push at some point.

@rustbot

This comment has been minimized.

@jakubadamw
Copy link
Copy Markdown
Contributor Author

jakubadamw commented Apr 13, 2026

@WaffleLapkin, oops, my apologies, this one has slipped my attention/notifications. 🙂
@folkertdev, thank you for picking this up, I pushed the tree of your branch to this one. 🙂
@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 13, 2026
@rust-log-analyzer

This comment has been minimized.

@rustbot

This comment has been minimized.

Copy link
Copy Markdown
Member

@WaffleLapkin WaffleLapkin left a comment

Choose a reason for hiding this comment

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

}

fn foo(&self) -> usize {
#[allow(tail_call_track_caller)]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
#[allow(tail_call_track_caller)]
#[expect(tail_call_track_caller)]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Turns out this does not work

error: 2 diagnostics reported in JSON output but not expected in test file
tests/ui/explicit-tail-calls/default-trait-method.rs:17:18: WARN: this lint expectation is unfulfilled [unfulfilled_lint_expectations]
tests/ui/explicit-tail-calls/default-trait-method.rs:17:18: WARN: this lint expectation is unfulfilled [unfulfilled_lint_expectations]

I think that is because there is some inconsistency between which HIR id is used, I actually suspect that we can/should emit this lint earlier so that we have more HIR stuff available.

I suspect that's blocked on some of the other work moving tail call logic to earlier stages, and in any case doesn't seem that relevant to this PR.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actually, at least part of the issue is that the instance on Struct does not use track_caller, so the expect fails on that monomorphization anyway.

@folkertdev
Copy link
Copy Markdown
Contributor

Also you can after making that fix just squash everything together into one commit

@WaffleLapkin
Copy link
Copy Markdown
Member

@rustbot author

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

rustbot commented Apr 19, 2026

Reminder, once the PR becomes ready for a review, use @rustbot ready.

Copy link
Copy Markdown
Contributor

@folkertdev folkertdev left a comment

Choose a reason for hiding this comment

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

I'll just squash this and then we can get it merged

View changes since this review

}

fn foo(&self) -> usize {
#[allow(tail_call_track_caller)]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Turns out this does not work

error: 2 diagnostics reported in JSON output but not expected in test file
tests/ui/explicit-tail-calls/default-trait-method.rs:17:18: WARN: this lint expectation is unfulfilled [unfulfilled_lint_expectations]
tests/ui/explicit-tail-calls/default-trait-method.rs:17:18: WARN: this lint expectation is unfulfilled [unfulfilled_lint_expectations]

I think that is because there is some inconsistency between which HIR id is used, I actually suspect that we can/should emit this lint earlier so that we have more HIR stuff available.

I suspect that's blocked on some of the other work moving tail call logic to earlier stages, and in any case doesn't seem that relevant to this PR.

The logic determining whether the relevant function is marked as `#[track_caller]`
only worked with functions that could be resolved to a concrete instance, which default
trait methods cannot. We need to check the codegen attribute on the default method itself.

Co-authored-by: Folkert de Vries <folkert@folkertdev.nl>
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 20, 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.

@jakubadamw
Copy link
Copy Markdown
Contributor Author

@folkertdev, hey, apologies for not having been responsive, it was a very hectic week, and I didn't find the time. Thank you for doing the rebase for me!

@folkertdev
Copy link
Copy Markdown
Contributor

Thanks for your work here!

@bors r=WaffleLapkin

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented Apr 20, 2026

📌 Commit ac5734a has been approved by WaffleLapkin

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-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 20, 2026
rust-bors Bot pushed a commit that referenced this pull request Apr 20, 2026
…uwer

Rollup of 11 pull requests

Successful merges:

 - #154654 (Move `std::io::ErrorKind` to `core::io`)
 - #145270 (Fix an ICE observed with an explicit tail-call in a default trait method)
 - #154895 (borrowck: Apply `user_arg_index` nomenclature more broadly)
 - #155213 (resolve: Make sure visibilities of import declarations make sense)
 - #155346 (`single_use_lifetimes`: respect `anonymous_lifetime_in_impl_trait`)
 - #155517 (Add a test for Mach-O `#[link_section]` API inherited from LLVM)
 - #155549 (Remove some unnecessary lifetimes.)
 - #154248 (resolve :  mark repr_simd as internal)
 - #154772 (slightly optimize the `non-camel-case-types` lint)
 - #155541 (Add `#[rust_analyzer::prefer_underscore_import]` to the traits in `rustc_type_ir::inherent`)
 - #155544 (bootstrap: Make "detected modifications" for download-rustc less verbose)
@rust-bors rust-bors Bot merged commit 3530d82 into rust-lang:main Apr 20, 2026
11 checks passed
@rustbot rustbot added this to the 1.97.0 milestone Apr 20, 2026
rust-timer added a commit that referenced this pull request Apr 20, 2026
Rollup merge of #145270 - jakubadamw:issue-144985, r=WaffleLapkin

Fix an ICE observed with an explicit tail-call in a default trait method

Right now, explicit tail-calls cannot be used in functions that hold the `#[track_caller]` attribute. This check is performed on a resolved concrete instance of a function, which would be absent for a tail-call performed from the body of a default trait method. This PR fixes the issue by checking for the relevant attribute in default trait methods separately, without expecting a specific resolved instance.

Closes #144985.
github-actions Bot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Apr 21, 2026
…uwer

Rollup of 11 pull requests

Successful merges:

 - rust-lang/rust#154654 (Move `std::io::ErrorKind` to `core::io`)
 - rust-lang/rust#145270 (Fix an ICE observed with an explicit tail-call in a default trait method)
 - rust-lang/rust#154895 (borrowck: Apply `user_arg_index` nomenclature more broadly)
 - rust-lang/rust#155213 (resolve: Make sure visibilities of import declarations make sense)
 - rust-lang/rust#155346 (`single_use_lifetimes`: respect `anonymous_lifetime_in_impl_trait`)
 - rust-lang/rust#155517 (Add a test for Mach-O `#[link_section]` API inherited from LLVM)
 - rust-lang/rust#155549 (Remove some unnecessary lifetimes.)
 - rust-lang/rust#154248 (resolve :  mark repr_simd as internal)
 - rust-lang/rust#154772 (slightly optimize the `non-camel-case-types` lint)
 - rust-lang/rust#155541 (Add `#[rust_analyzer::prefer_underscore_import]` to the traits in `rustc_type_ir::inherent`)
 - rust-lang/rust#155544 (bootstrap: Make "detected modifications" for download-rustc less verbose)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

F-explicit_tail_calls `#![feature(explicit_tail_calls)]` 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 from explicit tail call in defaulted trait method

9 participants