Skip to content

Always make tuple elements a coercion site#147834

Merged
rust-bors[bot] merged 2 commits intorust-lang:mainfrom
WaffleLapkin:tuple-coerce
Mar 9, 2026
Merged

Always make tuple elements a coercion site#147834
rust-bors[bot] merged 2 commits intorust-lang:mainfrom
WaffleLapkin:tuple-coerce

Conversation

@WaffleLapkin
Copy link
Copy Markdown
Member

@WaffleLapkin WaffleLapkin commented Oct 17, 2025

View all comments

Previously we only used check_expr_coercible_to_type if we had an expectation (using check_expr_with_expectation(NoExpectation) otherwise). Normally that'd be fine, because without an expectation we can't insert a coercion anyway. However, for the case of never-to-any coercion specifically, we do insert it eagerly, so this prevents some code from compiling, for example:

((),) = (loop {},);

With this PR we are always using check_expr_coercible_to_type (using an infer var if there is no expectation), which allows slightly more code to compile.

Fixes #112856

r? BoxyUwU

@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 17, 2025
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Oct 17, 2025

BoxyUwU is currently at their maximum review capacity.
They may take a while to respond.

@WaffleLapkin WaffleLapkin added A-coercions Area: implicit and explicit `expr as Type` coercions F-never_type `#![feature(never_type)]` T-types Relevant to the types team, which will review and decide on the PR/issue. relnotes Marks issues that should be documented in the release notes of the next release. labels Oct 17, 2025

/// Returns a list of tuple type arguments, or `None` if `self` isn't a tuple.
#[inline]
pub fn tuple(self) -> Option<&'tcx List<Ty<'tcx>>> {
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
pub fn tuple(self) -> Option<&'tcx List<Ty<'tcx>>> {
pub fn opt_tuple_fields(self) -> Option<&'tcx List<Ty<'tcx>>> {

seems like it does the same thing as tuple_fields it just doesnt panic

Copy link
Copy Markdown
Member Author

@WaffleLapkin WaffleLapkin Oct 26, 2025

Choose a reason for hiding this comment

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

That is indeed the case, is there a problem with that? In the code I wrote I found this a lot more convenient than checking the type first.

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.

no it's fine I just found the differences in the names doesn't really reflect the differences in behaviour

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

If you have a better idea for the names I can rename them

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.

i suggested a different name already :P

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

🤦🏻

I swear I sleep at night sometimes

@BoxyUwU BoxyUwU added needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 25, 2025
@BoxyUwU
Copy link
Copy Markdown
Member

BoxyUwU commented Oct 25, 2025

@bors try @rust-timer queue

should crater this as it is theoretically breaking, though I don't actually expect any breakage here 🤔

@rust-timer

This comment has been minimized.

@rust-bors

This comment has been minimized.

rust-bors bot added a commit that referenced this pull request Oct 25, 2025
Always make tuple elements a coercion site
@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 25, 2025
@BoxyUwU BoxyUwU 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 Oct 25, 2025
@BoxyUwU
Copy link
Copy Markdown
Member

BoxyUwU commented Oct 25, 2025

When we stabilize the never type do we intend to change how NeverToAny coercions work? Will we continue unconditionally coercing ! to an inference variable, or will we stop doing that? Or in other words, is the stable behaviour here the behaviour we'd expect to have once never type is stabilized?

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors bot commented Oct 25, 2025

☀️ Try build successful (CI)
Build commit: f77b5bc (f77b5bc6c7c84df104f86b0dd01d9490e3923fa8, parent: 04ff05c9c0cfbca33115c5f1b8bb20a66a54b799)

@rust-timer

This comment has been minimized.

@rust-timer
Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (f77b5bc): comparison URL.

Overall result: ❌✅ regressions and improvements - please read the text below

Benchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf.

Next Steps: If you can justify the regressions found in this try perf run, please do so in sufficient writing along with @rustbot label: +perf-regression-triaged. If not, please fix the regressions and do another perf run. If its results are neutral or positive, the label will be automatically removed.

@bors rollup=never
@rustbot label: -S-waiting-on-perf +perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
0.1% [0.1%, 0.2%] 3
Regressions ❌
(secondary)
0.1% [0.0%, 0.1%] 3
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-0.0% [-0.0%, -0.0%] 1
All ❌✅ (primary) 0.1% [0.1%, 0.2%] 3

Max RSS (memory usage)

Results (primary 1.4%, secondary -1.2%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
1.4% [0.8%, 2.1%] 2
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-1.2% [-1.2%, -1.2%] 1
All ❌✅ (primary) 1.4% [0.8%, 2.1%] 2

Cycles

Results (primary -2.1%, secondary -3.8%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-2.1% [-2.1%, -2.1%] 1
Improvements ✅
(secondary)
-3.8% [-5.3%, -2.1%] 4
All ❌✅ (primary) -2.1% [-2.1%, -2.1%] 1

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 473.373s -> 475.58s (0.47%)
Artifact size: 390.48 MiB -> 390.48 MiB (-0.00%)

@rustbot rustbot added perf-regression Performance regression. and removed S-waiting-on-perf Status: Waiting on a perf run to be completed. labels Oct 25, 2025
@BoxyUwU
Copy link
Copy Markdown
Member

BoxyUwU commented Oct 25, 2025

@craterbot check

@craterbot
Copy link
Copy Markdown
Collaborator

👌 Experiment pr-147834 created and queued.
🤖 Automatically detected try build f77b5bc
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Oct 25, 2025
@WaffleLapkin
Copy link
Copy Markdown
Member Author

When we stabilize the never type do we intend to change how NeverToAny coercions work? Will we continue unconditionally coercing ! to an inference variable, or will we stop doing that? Or in other words, is the stable behaviour here the behaviour we'd expect to have once never type is stabilized?

I don't expect / haven't heard of any desire to make any changes with how we insert NeverToAny coercions.

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Mar 9, 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.

@WaffleLapkin
Copy link
Copy Markdown
Member Author

@bors r=BoxyUwU

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors bot commented Mar 9, 2026

📋 This PR cannot be approved because it currently has the following labels: final-comment-period, S-waiting-on-fcp.

@WaffleLapkin WaffleLapkin removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. S-waiting-on-fcp Status: PR is in FCP and is awaiting for FCP to complete. labels Mar 9, 2026
@WaffleLapkin
Copy link
Copy Markdown
Member Author

@bors r=BoxyUwU

The FCP was blocked for a while, everyone had enough time to raise concerns. Agreed with boxy that this doesn't have to wait any longer.

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors bot commented Mar 9, 2026

📌 Commit 3398ea2 has been approved by BoxyUwU

It is now in the queue for this repository.

@rust-bors rust-bors bot added the S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. label Mar 9, 2026
@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors bot commented Mar 9, 2026

⌛ Testing commit 3398ea2 with merge a138e0d...

Workflow: https://github.com/rust-lang/rust/actions/runs/22864686275

rust-bors bot pushed a commit that referenced this pull request Mar 9, 2026
Always make tuple elements a coercion site





Previously we only used `check_expr_coercible_to_type` if we had an expectation (using `check_expr_with_expectation(NoExpectation)` otherwise). Normally that'd be fine, because without an expectation we can't insert a coercion anyway. However, for the case of never-to-any coercion specifically, we _do_ insert it eagerly, so this prevents some code from compiling, for example:

```rust
((),) = (loop {},);
```

With this PR we are always using `check_expr_coercible_to_type` (using an infer var if there is no expectation), which allows slightly more code to compile.

Fixes #112856

r? BoxyUwU
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 9, 2026
Always make tuple elements a coercion site

Previously we only used `check_expr_coercible_to_type` if we had an expectation (using `check_expr_with_expectation(NoExpectation)` otherwise). Normally that'd be fine, because without an expectation we can't insert a coercion anyway. However, for the case of never-to-any coercion specifically, we _do_ insert it eagerly, so this prevents some code from compiling, for example:

```rust
((),) = (loop {},);
```

With this PR we are always using `check_expr_coercible_to_type` (using an infer var if there is no expectation), which allows slightly more code to compile.

Fixes rust-lang#112856

r? BoxyUwU
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 9, 2026
Always make tuple elements a coercion site

Previously we only used `check_expr_coercible_to_type` if we had an expectation (using `check_expr_with_expectation(NoExpectation)` otherwise). Normally that'd be fine, because without an expectation we can't insert a coercion anyway. However, for the case of never-to-any coercion specifically, we _do_ insert it eagerly, so this prevents some code from compiling, for example:

```rust
((),) = (loop {},);
```

With this PR we are always using `check_expr_coercible_to_type` (using an infer var if there is no expectation), which allows slightly more code to compile.

Fixes rust-lang#112856

r? BoxyUwU
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 9, 2026
Always make tuple elements a coercion site

Previously we only used `check_expr_coercible_to_type` if we had an expectation (using `check_expr_with_expectation(NoExpectation)` otherwise). Normally that'd be fine, because without an expectation we can't insert a coercion anyway. However, for the case of never-to-any coercion specifically, we _do_ insert it eagerly, so this prevents some code from compiling, for example:

```rust
((),) = (loop {},);
```

With this PR we are always using `check_expr_coercible_to_type` (using an infer var if there is no expectation), which allows slightly more code to compile.

Fixes rust-lang#112856

r? BoxyUwU
@JonathanBrouwer
Copy link
Copy Markdown
Contributor

@bors yield
Yielding to enclosing rollup

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors bot commented Mar 9, 2026

Auto build was cancelled. Cancelled workflows:

The next pull request likely to be tested is #153617.

rust-bors bot pushed a commit that referenced this pull request Mar 9, 2026
…uwer

Rollup of 4 pull requests

Successful merges:

 - #147834 (Always make tuple elements a coercion site)
 - #150446 (miri/const eval: support `MaybeDangling`)
 - #153053 (stop marking `deref_patterns` as an incomplete feature)
 - #153398 (fix ICE in `const_c_variadic` when passing ZSTs)
@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors bot commented Mar 9, 2026

⌛ Testing commit 3398ea2 with merge 82e4d00...

Workflow: https://github.com/rust-lang/rust/actions/runs/22865035946

rust-bors bot pushed a commit that referenced this pull request Mar 9, 2026
Always make tuple elements a coercion site





Previously we only used `check_expr_coercible_to_type` if we had an expectation (using `check_expr_with_expectation(NoExpectation)` otherwise). Normally that'd be fine, because without an expectation we can't insert a coercion anyway. However, for the case of never-to-any coercion specifically, we _do_ insert it eagerly, so this prevents some code from compiling, for example:

```rust
((),) = (loop {},);
```

With this PR we are always using `check_expr_coercible_to_type` (using an infer var if there is no expectation), which allows slightly more code to compile.

Fixes #112856

r? BoxyUwU
@JonathanBrouwer
Copy link
Copy Markdown
Contributor

@bors yield
Yielding to enclosing rollup

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors bot commented Mar 9, 2026

Auto build was cancelled. Cancelled workflows:

The next pull request likely to be tested is #153617.

rust-bors bot pushed a commit that referenced this pull request Mar 9, 2026
…uwer

Rollup of 4 pull requests

Successful merges:

 - #147834 (Always make tuple elements a coercion site)
 - #150446 (miri/const eval: support `MaybeDangling`)
 - #153053 (stop marking `deref_patterns` as an incomplete feature)
 - #153398 (fix ICE in `const_c_variadic` when passing ZSTs)
@rust-bors rust-bors bot merged commit 3f1ddd5 into rust-lang:main Mar 9, 2026
11 of 12 checks passed
@rustbot rustbot added this to the 1.96.0 milestone Mar 9, 2026
rust-timer added a commit that referenced this pull request Mar 9, 2026
Rollup merge of #147834 - WaffleLapkin:tuple-coerce, r=BoxyUwU

Always make tuple elements a coercion site

Previously we only used `check_expr_coercible_to_type` if we had an expectation (using `check_expr_with_expectation(NoExpectation)` otherwise). Normally that'd be fine, because without an expectation we can't insert a coercion anyway. However, for the case of never-to-any coercion specifically, we _do_ insert it eagerly, so this prevents some code from compiling, for example:

```rust
((),) = (loop {},);
```

With this PR we are always using `check_expr_coercible_to_type` (using an infer var if there is no expectation), which allows slightly more code to compile.

Fixes #112856

r? BoxyUwU
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Mar 10, 2026
…uwer

Rollup of 4 pull requests

Successful merges:

 - rust-lang/rust#147834 (Always make tuple elements a coercion site)
 - rust-lang/rust#150446 (miri/const eval: support `MaybeDangling`)
 - rust-lang/rust#153053 (stop marking `deref_patterns` as an incomplete feature)
 - rust-lang/rust#153398 (fix ICE in `const_c_variadic` when passing ZSTs)
@rust-rfcbot rust-rfcbot added finished-final-comment-period The final comment period is finished for this PR / Issue. to-announce Announce this issue on triage meeting labels Mar 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-coercions Area: implicit and explicit `expr as Type` coercions disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. F-never_type `#![feature(never_type)]` finished-final-comment-period The final comment period is finished for this PR / Issue. needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. perf-regression Performance regression. relnotes Marks issues that should be documented in the release notes of the next release. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-types Relevant to the types team, which will review and decide on the PR/issue. to-announce Announce this issue on triage meeting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tuple elements are not considered a coercion site

7 participants