Skip to content

Conversation

@BoxyUwU
Copy link
Member

@BoxyUwU BoxyUwU commented Oct 10, 2025

based on #147565

make coerce-lubs order independent

cc #73154 #97206

lub currently equates binders and then just returns the lhs without ever leak checking to ensure the binders are actually equal. this can lead to coerce-lub operations being order dependent, i.e. that a coerce-lub b has differing behaviour to b coerce-lub a.

we also cannot rely on borrow checking actually checking the constraints from equating the binders as lub is a hir-typeck coercion concept that is not relevant once MIR has been built. In the MIR we can simply subtype all the types of match arms with the final type of the match.

it is a forwards compatibility hazard to have coerce-lub be order dependent as it results in an effectively arbitrary inference choice which may or may not actually be correct or compatible with hypothetical future behaviours of lub that actually try to compute a proper lub'd type.

on stable we attempt to make coerce-lubs order independent with two checks:

  • Leak check for fndef->fnptr coercions
  • Leak check for fnptr->fnptr coercions

on stable we do this regardless of whether the coercion is occuring as part of a coerce-lub or not.

under this PR we have the following checks:

  • Leak check for fnptr/fndef->fnptr coercions
  • Leak check for closure->fnptr coercions performed as part of a coerce-lub
  • Leak check closure/fndef<->closure/fndef coerce-lubs that coerce both sides to fnptrs
  • Leak check the fallback lub operation when a coerce-lub does not actually coerce

this is theoretically breaking in two cases:

  1. the new leak checks are in dead code where borrowck doesn't emit any errors
  2. people have written matches/if-elses/array-exprs that rely on the arbitrary inference choice of the first signature encountered

the second case actually is encountered by a few crates in practice which has been somewhat mitigated by the next change.

improving binder lub

this PR also implements a slight improvement to lub operations on higher ranked types to avoid some regressions: #147565 (comment)

when lubbing two higher ranked types, if one of the binders is empty then we now instantiate the other binder with inference variables and lub the instantiated type with the empty-binder type.

concretely:

  • for<'a> fn(&'a ()) lub fn(&'static ())
  • only the lhs has bound vars so: fn(&'?a ()) lub fn(&'static ())
  • '?a eq 'static passes leak check

whereas the previous behaviour was:

  • for<'a> fn(&'a ()) lub fn(&'static ())
  • lubbing binders is hard so just equate with invariance: fn(&'!a ()) eq fn(&'static ())
  • '!a eq 'static fails leak check

this change is just theoretically incorrect :3

@rustbot rustbot added 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. labels Oct 10, 2025
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@BoxyUwU BoxyUwU force-pushed the coercion_cleanup branch 2 times, most recently from bce0933 to eb6434f Compare October 29, 2025 18:00
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@BoxyUwU BoxyUwU force-pushed the coercion_cleanup branch 2 times, most recently from 797201d to 3ecd1a8 Compare October 30, 2025 14:42
@rust-log-analyzer

This comment has been minimized.

@BoxyUwU BoxyUwU force-pushed the coercion_cleanup branch 3 times, most recently from 6179239 to 2958ef0 Compare October 30, 2025 15:19
@rust-log-analyzer

This comment has been minimized.

@craterbot
Copy link
Collaborator

🎉 Experiment pr-147565-1 is completed!
📊 6 regressed and 0 fixed (1696 total)
📊 95 spurious results on the retry-regessed-list.txt, consider a retry1 if this is a significant amount.
📰 Open the summary report.

⚠️ If you notice any spurious failure please add them to the denylist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

Footnotes

  1. re-run the experiment with crates=https://crater-reports.s3.amazonaws.com/pr-147565-1/retry-regressed-list.txt

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Nov 5, 2025
@BoxyUwU
Copy link
Member Author

BoxyUwU commented Nov 6, 2025

r? lcnr

@BoxyUwU BoxyUwU marked this pull request as ready for review November 6, 2025 12:59
@rustbot
Copy link
Collaborator

rustbot commented Nov 6, 2025

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

This PR changes rustc_public

cc @oli-obk, @celinval, @ouz-a

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

Some changes occurred to constck

cc @fee1-dead

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

changes to the core type system

cc @compiler-errors, @lcnr

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

This PR changes a file inside tests/crashes. If a crash was fixed, please move into the corresponding ui subdir and add 'Fixes #' to the PR description to autoclose the issue upon merge.

@rustbot
Copy link
Collaborator

rustbot commented Nov 6, 2025

This PR was rebased onto a different master 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.

@BoxyUwU BoxyUwU changed the title coercions reviews/misc whatevers leak check lubs in coercion, and handle safety correctly in coerce-lubs Nov 6, 2025
@BoxyUwU BoxyUwU changed the title leak check lubs in coercion, and handle safety correctly in coerce-lubs make coerce-lub order independent Nov 6, 2025
@rust-log-analyzer
Copy link
Collaborator

The job aarch64-gnu-llvm-20-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
test [ui] tests/ui/coercion/issue-73886.rs ... ok
test [ui] tests/ui/coercion/issue-88097.rs#current ... ok
test [ui] tests/ui/coercion/issue-88097.rs#next ... ok
test [ui] tests/ui/coercion/issue-3794.rs ... ok
test [ui] tests/ui/coercion/leak_check_fndef_lub.rs ... ok
test [ui] tests/ui/coercion/leak_check_fndef_lub_deadcode_breakage.rs ... ok
test [ui] tests/ui/coercion/leak_check_lub_fallback.rs ... FAILED
test [ui] tests/ui/coercion/leak_check_single_to_fnptr.rs#deadcode ... ok
test [ui] tests/ui/coercion/leak_check_lub_to_fnptr.rs#deadcode ... FAILED
test [ui] tests/ui/coercion/leak_check_lub_to_fnptr.rs#livecode ... FAILED
test [ui] tests/ui/coercion/lub_coercion_handles_safety.rs ... ignored, only executed when the architecture is x86_64
test [ui] tests/ui/coercion/issue-39823.rs ... ok
test [ui] tests/ui/coercion/leak_check_single_to_fnptr.rs#livecode ... ok
test [ui] tests/ui/coercion/lub_closures_before_fnptr_coercion.rs ... ok
test [ui] tests/ui/coercion/mut-trait-object-coercion-8398.rs ... ok
test [ui] tests/ui/coercion/mut-mut-wont-coerce.rs ... ok
test [ui] tests/ui/coercion/method-return-trait-object-14399.rs ... ok
test [ui] tests/ui/coercion/no_local_for_coerced_const-issue-143671.rs ... ok
test [ui] tests/ui/coercion/pin-dyn-dispatch-sound.rs ... ok
---
test [ui] tests/ui/zero-sized/zero-sized-btreemap-insert.rs ... ok

failures:

---- [ui] tests/ui/coercion/leak_check_lub_fallback.rs stdout ----

error: ui test did not emit an error
note: by default, ui tests are expected not to compile.
hint: use check-pass, build-pass, or run-pass directive to change this behavior.
status: exit status: 0
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/coercion/leak_check_lub_fallback.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/coercion/leak_check_lub_fallback" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers"
stdout: none
stderr: none

---- [ui] tests/ui/coercion/leak_check_lub_fallback.rs stdout end ----
---- [ui] tests/ui/coercion/leak_check_lub_to_fnptr.rs#deadcode stdout ----
Saved the actual stderr to `/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/coercion/leak_check_lub_to_fnptr.deadcode/leak_check_lub_to_fnptr.deadcode.stderr`
diff of stderr:

50                  found fn item `for<'a> fn(&'static (), &'a ()) {lub_with_fnptr_leak_checking::rhs_fndef}`
51 
52 error[E0308]: `if` and `else` have incompatible types
-   --> $DIR/leak_check_lub_to_fnptr.rs:47:15
-    |
- LL |     let rhs_closure = |_: &'static (), _: &()| {};
-    |                       ------------------------ the found closure
- LL |     lub!(lhs, rhs_closure);
-    |          ---  ^^^^^^^^^^^ one type is more general than the other
-    |          |
-    |          expected because of this
-    |
-    = note: expected fn pointer `for<'a> fn(&'a (), &())`
-                  found closure `{closure@$DIR/leak_check_lub_to_fnptr.rs:46:23: 46:47}`
-    = note: closure has signature: `for<'a> fn(&'static (), &'a ())`
- 
- error[E0308]: `if` and `else` have incompatible types
67   --> $DIR/leak_check_lub_to_fnptr.rs:59:23
68    |
69 LL |     let lhs_closure = |_: &(), _: &'static (), _: &()| {};

123    = note: expected fn item `for<'a> fn(&'static (), &'static (), &'a ()) {order_dependence_fndefs::rhs_fndef}`
124               found fn item `for<'a, 'b> fn(&'a (), &'static (), &'b ()) {order_dependence_fndefs::lhs_fndef}`
125 
- error: aborting due to 9 previous errors
+ error: aborting due to 8 previous errors
127 
128 For more information about this error, try `rustc --explain E0308`.
129 


The actual stderr differed from the expected stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args coercion/leak_check_lub_to_fnptr.rs`

error in revision `deadcode`: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--cfg" "deadcode" "--check-cfg" "cfg(test,FALSE,livecode,deadcode)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/coercion/leak_check_lub_to_fnptr.deadcode" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers"
stdout: none
--- stderr -------------------------------
error[E0308]: `if` and `else` have incompatible types
##[error]  --> /checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:21:21
   |
LL |     lub!(lhs_fnptr, rhs_fnptr);
   |          ---------  ^^^^^^^^^ one type is more general than the other
   |          |
   |          expected because of this
   |
   = note: expected fn pointer `for<'a> fn(&'a (), &())`
              found fn pointer `for<'a> fn(&(), &'a ())`

error[E0308]: `if` and `else` have incompatible types
##[error]  --> /checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:27:21
   |
LL |     lub!(lhs_fndef, rhs_fndef);
   |          ---------  ^^^^^^^^^ one type is more general than the other
   |          |
   |          expected because of this
   |
   = note: expected fn item `for<'a> fn(&'a (), &'static ()) {lub_to_fnptr_leak_checking::lhs_fndef}`
              found fn item `for<'a> fn(&'static (), &'a ()) {lub_to_fnptr_leak_checking::rhs_fndef}`

error[E0308]: `if` and `else` have incompatible types
##[error]  --> /checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:33:23
   |
LL |     let lhs_closure = |_: &(), _: &'static ()| {};
   |                       ------------------------ the expected closure
LL |     let rhs_closure = |_: &'static (), _: &()| {};
   |                       ------------------------ the found closure
LL |     lub!(lhs_closure, rhs_closure);
   |          -----------  ^^^^^^^^^^^ one type is more general than the other
   |          |
   |          expected because of this
   |
   = note: expected closure `{closure@/checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:31:23: 31:47}`
              found closure `{closure@/checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:32:23: 32:47}`
   = note: closure has signature: `for<'a> fn(&'static (), &'a ())`
   = note: no two closures, even if identical, have the same type
   = help: consider boxing your closure and/or using it as a trait object

error[E0308]: `if` and `else` have incompatible types
##[error]  --> /checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:42:15
   |
LL |     lub!(lhs, rhs_fndef);
   |          ---  ^^^^^^^^^ one type is more general than the other
   |          |
   |          expected because of this
   |
   = note: expected fn pointer `for<'a> fn(&'a (), &())`
                 found fn item `for<'a> fn(&'static (), &'a ()) {lub_with_fnptr_leak_checking::rhs_fndef}`

error[E0308]: `if` and `else` have incompatible types
##[error]  --> /checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:59:23
   |
LL |     let lhs_closure = |_: &(), _: &'static (), _: &()| {};
   |                       -------------------------------- the expected closure
LL |     let rhs_closure = |_: &'static (), _: &'static (), _: &()| {};
   |                       ---------------------------------------- the found closure
LL |
LL |     lub!(lhs_closure, rhs_closure);
   |          -----------  ^^^^^^^^^^^ one type is more general than the other
   |          |
   |          expected because of this
   |
   = note: expected closure `{closure@/checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:56:23: 56:55}`
              found closure `{closure@/checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:57:23: 57:63}`
   = note: closure has signature: `for<'a> fn(&'static (), &'static (), &'a ())`
   = note: no two closures, even if identical, have the same type
   = help: consider boxing your closure and/or using it as a trait object

error[E0308]: `if` and `else` have incompatible types
##[error]  --> /checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:61:23
   |
LL |     let lhs_closure = |_: &(), _: &'static (), _: &()| {};
   |                       -------------------------------- the found closure
LL |     let rhs_closure = |_: &'static (), _: &'static (), _: &()| {};
   |                       ---------------------------------------- the expected closure
...
LL |     lub!(rhs_closure, lhs_closure);
   |          -----------  ^^^^^^^^^^^ one type is more general than the other
   |          |
   |          expected because of this
   |
   = note: expected closure `{closure@/checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:57:23: 57:63}`
              found closure `{closure@/checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:56:23: 56:55}`
   = note: closure has signature: `for<'a, 'b> fn(&'a (), &'static (), &'b ())`
   = note: no two closures, even if identical, have the same type
   = help: consider boxing your closure and/or using it as a trait object

error[E0308]: `if` and `else` have incompatible types
##[error]  --> /checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:73:21
   |
LL |     lub!(lhs_fndef, rhs_fndef);
   |          ---------  ^^^^^^^^^ one type is more general than the other
   |          |
   |          expected because of this
   |
   = note: expected fn item `for<'a, 'b> fn(&'a (), &'static (), &'b ()) {order_dependence_fndefs::lhs_fndef}`
              found fn item `for<'a> fn(&'static (), &'static (), &'a ()) {order_dependence_fndefs::rhs_fndef}`

error[E0308]: `if` and `else` have incompatible types
##[error]  --> /checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:75:21
   |
LL |     lub!(rhs_fndef, lhs_fndef);
   |          ---------  ^^^^^^^^^ one type is more general than the other
   |          |
   |          expected because of this
   |
   = note: expected fn item `for<'a> fn(&'static (), &'static (), &'a ()) {order_dependence_fndefs::rhs_fndef}`
              found fn item `for<'a, 'b> fn(&'a (), &'static (), &'b ()) {order_dependence_fndefs::lhs_fndef}`

error: aborting due to 8 previous errors

For more information about this error, try `rustc --explain E0308`.
------------------------------------------

---- [ui] tests/ui/coercion/leak_check_lub_to_fnptr.rs#deadcode stdout end ----
---- [ui] tests/ui/coercion/leak_check_lub_to_fnptr.rs#livecode stdout ----
Saved the actual stderr to `/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/coercion/leak_check_lub_to_fnptr.livecode/leak_check_lub_to_fnptr.livecode.stderr`
diff of stderr:

50                  found fn item `for<'a> fn(&'static (), &'a ()) {lub_with_fnptr_leak_checking::rhs_fndef}`
51 
52 error[E0308]: `if` and `else` have incompatible types
-   --> $DIR/leak_check_lub_to_fnptr.rs:47:15
-    |
- LL |     let rhs_closure = |_: &'static (), _: &()| {};
-    |                       ------------------------ the found closure
- LL |     lub!(lhs, rhs_closure);
-    |          ---  ^^^^^^^^^^^ one type is more general than the other
-    |          |
-    |          expected because of this
-    |
-    = note: expected fn pointer `for<'a> fn(&'a (), &())`
-                  found closure `{closure@$DIR/leak_check_lub_to_fnptr.rs:46:23: 46:47}`
-    = note: closure has signature: `for<'a> fn(&'static (), &'a ())`
- 
- error[E0308]: `if` and `else` have incompatible types
67   --> $DIR/leak_check_lub_to_fnptr.rs:59:23
68    |
69 LL |     let lhs_closure = |_: &(), _: &'static (), _: &()| {};

123    = note: expected fn item `for<'a> fn(&'static (), &'static (), &'a ()) {order_dependence_fndefs::rhs_fndef}`
124               found fn item `for<'a, 'b> fn(&'a (), &'static (), &'b ()) {order_dependence_fndefs::lhs_fndef}`
125 
- error: aborting due to 9 previous errors
+ error: aborting due to 8 previous errors
127 
128 For more information about this error, try `rustc --explain E0308`.
129 


The actual stderr differed from the expected stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args coercion/leak_check_lub_to_fnptr.rs`

error in revision `livecode`: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--cfg" "livecode" "--check-cfg" "cfg(test,FALSE,livecode,deadcode)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/coercion/leak_check_lub_to_fnptr.livecode" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers"
stdout: none
--- stderr -------------------------------
error[E0308]: `if` and `else` have incompatible types
##[error]  --> /checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:21:21
   |
LL |     lub!(lhs_fnptr, rhs_fnptr);
   |          ---------  ^^^^^^^^^ one type is more general than the other
   |          |
   |          expected because of this
   |
   = note: expected fn pointer `for<'a> fn(&'a (), &())`
              found fn pointer `for<'a> fn(&(), &'a ())`

error[E0308]: `if` and `else` have incompatible types
##[error]  --> /checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:27:21
   |
LL |     lub!(lhs_fndef, rhs_fndef);
   |          ---------  ^^^^^^^^^ one type is more general than the other
   |          |
   |          expected because of this
   |
   = note: expected fn item `for<'a> fn(&'a (), &'static ()) {lub_to_fnptr_leak_checking::lhs_fndef}`
              found fn item `for<'a> fn(&'static (), &'a ()) {lub_to_fnptr_leak_checking::rhs_fndef}`

error[E0308]: `if` and `else` have incompatible types
##[error]  --> /checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:33:23
   |
LL |     let lhs_closure = |_: &(), _: &'static ()| {};
   |                       ------------------------ the expected closure
LL |     let rhs_closure = |_: &'static (), _: &()| {};
   |                       ------------------------ the found closure
LL |     lub!(lhs_closure, rhs_closure);
   |          -----------  ^^^^^^^^^^^ one type is more general than the other
   |          |
   |          expected because of this
   |
   = note: expected closure `{closure@/checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:31:23: 31:47}`
              found closure `{closure@/checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:32:23: 32:47}`
   = note: closure has signature: `for<'a> fn(&'static (), &'a ())`
   = note: no two closures, even if identical, have the same type
   = help: consider boxing your closure and/or using it as a trait object

error[E0308]: `if` and `else` have incompatible types
##[error]  --> /checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:42:15
   |
LL |     lub!(lhs, rhs_fndef);
   |          ---  ^^^^^^^^^ one type is more general than the other
   |          |
   |          expected because of this
   |
   = note: expected fn pointer `for<'a> fn(&'a (), &())`
                 found fn item `for<'a> fn(&'static (), &'a ()) {lub_with_fnptr_leak_checking::rhs_fndef}`

error[E0308]: `if` and `else` have incompatible types
##[error]  --> /checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:59:23
   |
LL |     let lhs_closure = |_: &(), _: &'static (), _: &()| {};
   |                       -------------------------------- the expected closure
LL |     let rhs_closure = |_: &'static (), _: &'static (), _: &()| {};
   |                       ---------------------------------------- the found closure
LL |
LL |     lub!(lhs_closure, rhs_closure);
   |          -----------  ^^^^^^^^^^^ one type is more general than the other
   |          |
   |          expected because of this
   |
   = note: expected closure `{closure@/checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:56:23: 56:55}`
              found closure `{closure@/checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:57:23: 57:63}`
   = note: closure has signature: `for<'a> fn(&'static (), &'static (), &'a ())`
   = note: no two closures, even if identical, have the same type
   = help: consider boxing your closure and/or using it as a trait object

error[E0308]: `if` and `else` have incompatible types
##[error]  --> /checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:61:23
   |
LL |     let lhs_closure = |_: &(), _: &'static (), _: &()| {};
   |                       -------------------------------- the found closure
LL |     let rhs_closure = |_: &'static (), _: &'static (), _: &()| {};
   |                       ---------------------------------------- the expected closure
...
LL |     lub!(rhs_closure, lhs_closure);
   |          -----------  ^^^^^^^^^^^ one type is more general than the other
   |          |
   |          expected because of this
   |
   = note: expected closure `{closure@/checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:57:23: 57:63}`
              found closure `{closure@/checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:56:23: 56:55}`
   = note: closure has signature: `for<'a, 'b> fn(&'a (), &'static (), &'b ())`
   = note: no two closures, even if identical, have the same type
   = help: consider boxing your closure and/or using it as a trait object

error[E0308]: `if` and `else` have incompatible types
##[error]  --> /checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:73:21
   |
LL |     lub!(lhs_fndef, rhs_fndef);
   |          ---------  ^^^^^^^^^ one type is more general than the other
   |          |
   |          expected because of this
   |
   = note: expected fn item `for<'a, 'b> fn(&'a (), &'static (), &'b ()) {order_dependence_fndefs::lhs_fndef}`
              found fn item `for<'a> fn(&'static (), &'static (), &'a ()) {order_dependence_fndefs::rhs_fndef}`

error[E0308]: `if` and `else` have incompatible types
##[error]  --> /checkout/tests/ui/coercion/leak_check_lub_to_fnptr.rs:75:21
   |
LL |     lub!(rhs_fndef, lhs_fndef);
   |          ---------  ^^^^^^^^^ one type is more general than the other
   |          |
   |          expected because of this
   |
   = note: expected fn item `for<'a> fn(&'static (), &'static (), &'a ()) {order_dependence_fndefs::rhs_fndef}`
              found fn item `for<'a, 'b> fn(&'a (), &'static (), &'b ()) {order_dependence_fndefs::lhs_fndef}`

error: aborting due to 8 previous errors

For more information about this error, try `rustc --explain E0308`.
------------------------------------------

---- [ui] tests/ui/coercion/leak_check_lub_to_fnptr.rs#livecode stdout end ----

failures:
    [ui] tests/ui/coercion/leak_check_lub_fallback.rs
    [ui] tests/ui/coercion/leak_check_lub_to_fnptr.rs#deadcode
    [ui] tests/ui/coercion/leak_check_lub_to_fnptr.rs#livecode

test result: FAILED. 19700 passed; 3 failed; 325 ignored; 0 measured; 21 filtered out; finished in 601.20s

Some tests failed in compiletest suite=ui mode=ui host=aarch64-unknown-linux-gnu target=aarch64-unknown-linux-gnu
Bootstrap failed while executing `--stage 2 test --skip compiler --skip src`

@BoxyUwU BoxyUwU added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. 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 Nov 7, 2025
@BoxyUwU
Copy link
Member Author

BoxyUwU commented Nov 7, 2025

blocked on deciding what to do about breakage :)

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

Labels

I-lang-radar Items that are on lang's radar and will need eventual work or consideration. perf-regression Performance regression. S-blocked Status: Blocked on something else such as an RFC or other implementation work. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-clippy Relevant to the Clippy team. T-types Relevant to the types team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants