Skip to content

Support field-wise CoerceShared reborrows#157101

Draft
P8L1 wants to merge 1 commit into
rust-lang:mainfrom
P8L1:fix-reborrow-coerceshared-field-relations
Draft

Support field-wise CoerceShared reborrows#157101
P8L1 wants to merge 1 commit into
rust-lang:mainfrom
P8L1:fix-reborrow-coerceshared-field-relations

Conversation

@P8L1
Copy link
Copy Markdown
Contributor

@P8L1 P8L1 commented May 29, 2026

This PR extends generic shared reborrows so that CoerceShared validates and lowers source-to-target structs field by field, rather than relying on a same-layout, transmute-like copy.

The core change is a shared rustc_middle::ty::reborrow helper that computes the field correspondence used by CoerceShared validation, borrow checking, const-eval, and codegen.

The correspondence rules are:

  • Named structs match non-PhantomData data fields by name.
  • Tuple structs match non-PhantomData data fields by position.
  • PhantomData fields are ignored.
  • Every target data field must correspond to a source data field.

CoerceShared impl validation now checks each corresponding field relation. A field relation is accepted when the field is:

  • Copy-compatible,
  • recursively CoerceShared-compatible, or
  • a mutable-reference-to-shared-reference reborrow.

The validation also rejects mismatched field styles, missing source fields, mismatched reborrow lifetimes, and inaccessible fields with targeted diagnostics.

Borrowck now adds shared generic reborrow constraints recursively through the validated field relations, while still issuing the loan for the original source place as a whole. This ensures source-only fields remain protected for the inferred target lifetime when the target omits fields from the source.

Const-eval and codegen now lower shared generic reborrows recursively into the target fields instead of treating the operation as a transmute-like copy. This covers nested CoerceShared fields and layout-changing source/target pairs.

Fixes

Fixes #156566.
Fixes #156309.
Fixes #156315.

PR scope

I did not split these into smaller PRs because the issues mostly share the same root cause: CoerceShared needed a field-by-field validation and lowering model. So when making this, I just decided to write it in a way that will fix the issues anyway.

Tracking

#145612

@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 May 29, 2026
@P8L1
Copy link
Copy Markdown
Contributor Author

P8L1 commented May 29, 2026

@rustbot label +F-reborrow

@rustbot rustbot added the F-reborrow `#![feature(reborrow)]`; see #145612 label May 29, 2026
@P8L1
Copy link
Copy Markdown
Contributor Author

P8L1 commented May 29, 2026

Note: I want to self review my logic and fix findings if there are any, will be moving this from Draft to Open sometime next week

@P8L1
Copy link
Copy Markdown
Contributor Author

P8L1 commented May 29, 2026

@bors squash

@rust-bors

This comment has been minimized.

* Implement field-wise CoerceShared validation for reborrow
* Support target-driven CoerceShared field relations
* Test omitted CoerceShared source field soundness
* Address CoerceShared field relation review
* Test foreign CoerceShared private tuple field
@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 29, 2026

🔨 5 commits were squashed into b8e47e8.

@rust-bors rust-bors Bot force-pushed the fix-reborrow-coerceshared-field-relations branch from 9713677 to b8e47e8 Compare May 29, 2026 09:36
@rust-log-analyzer
Copy link
Copy Markdown
Collaborator

The job tidy failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
[TIMING:end] tool::Tidy { compiler: Compiler { stage: 0, host: x86_64-unknown-linux-gnu, forced_compiler: false }, target: x86_64-unknown-linux-gnu } -- 0.000
fmt check
fmt: checked 6870 files
tidy check
tidy [ui_tests (tests)]: issue-number-only test names are not descriptive, consider renaming file `tests/ui/reborrow/issue-156309.rs` to `{reason}-issue-156309.rs`
tidy [ui_tests (tests)]: issue-number-only test names are not descriptive, consider renaming file `tests/ui/reborrow/issue-156315.rs` to `{reason}-issue-156315.rs`
tidy [ui_tests (tests)]: issue-number-only test names are not descriptive, consider renaming file `tests/ui/reborrow/issue-156315-corrected.rs` to `{reason}-issue-156315.rs`
tidy [ui_tests (tests)]: issue-number-only test names are not descriptive, consider renaming file `tests/ui/reborrow/issue-156309-corrected.rs` to `{reason}-issue-156309.rs`
tidy [ui_tests (tests)]: FAIL
tidy [rustdoc_json (src)]: `rustdoc-json-types` modified, checking format version
tidy: Skipping binary file check, read-only filesystem
removing old virtual environment
creating virtual environment at '/checkout/obj/build/venv' using 'python3.10' and 'venv'
creating virtual environment at '/checkout/obj/build/venv' using 'python3.10' and 'virtualenv'
---
linting javascript files
Running eslint on rustdoc JS files
info: ES-Check: there were no ES version matching errors!  🎉
typechecking javascript files
tidy: The following check failed: ui_tests (tests)
Command `/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-tools-bin/rust-tidy --root-path=/checkout --cargo-path=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo --output-dir=/checkout/obj/build --concurrency=4 --npm-path=/node/bin/yarn --ci=true --extra-checks=py,cpp,js,spellcheck` failed with exit code 1
Created at: src/bootstrap/src/core/build_steps/tool.rs:1618:23
Executed at: src/bootstrap/src/core/build_steps/test.rs:1417:29

--- BACKTRACE vvv
   0: <bootstrap::utils::exec::DeferredCommand>::finish_process
             at /checkout/src/bootstrap/src/utils/exec.rs:939:17
   1: <bootstrap::utils::exec::DeferredCommand>::wait_for_output::<&bootstrap::utils::exec::ExecutionContext>
             at /checkout/src/bootstrap/src/utils/exec.rs:831:21
   2: <bootstrap::utils::exec::ExecutionContext>::run
             at /checkout/src/bootstrap/src/utils/exec.rs:741:45
   3: <bootstrap::utils::exec::BootstrapCommand>::run::<&bootstrap::core::builder::Builder>
             at /checkout/src/bootstrap/src/utils/exec.rs:339:27
   4: <bootstrap::core::build_steps::test::Tidy as bootstrap::core::builder::Step>::run
             at /checkout/src/bootstrap/src/core/build_steps/test.rs:1417:29
   5: <bootstrap::core::builder::Builder>::ensure::<bootstrap::core::build_steps::test::Tidy>
             at /checkout/src/bootstrap/src/core/builder/mod.rs:1595:36
   6: <bootstrap::core::build_steps::test::Tidy as bootstrap::core::builder::Step>::make_run
             at /checkout/src/bootstrap/src/core/build_steps/test.rs:1339:21
   7: <bootstrap::core::builder::StepDescription>::maybe_run
             at /checkout/src/bootstrap/src/core/builder/mod.rs:476:13
   8: bootstrap::core::builder::cli_paths::match_paths_to_steps_and_run
             at /checkout/src/bootstrap/src/core/builder/cli_paths.rs:232:18
   9: <bootstrap::core::builder::Builder>::run_step_descriptions
             at /checkout/src/bootstrap/src/core/builder/mod.rs:1138:9
  10: <bootstrap::core::builder::Builder>::execute_cli
             at /checkout/src/bootstrap/src/core/builder/mod.rs:1117:14
  11: <bootstrap::Build>::build
             at /checkout/src/bootstrap/src/lib.rs:803:25
  12: bootstrap::main
             at /checkout/src/bootstrap/src/bin/main.rs:130:11
  13: <fn() as core::ops::function::FnOnce<()>>::call_once
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/core/src/ops/function.rs:250:5
  14: std::sys::backtrace::__rust_begin_short_backtrace::<fn(), ()>
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/std/src/sys/backtrace.rs:166:18
  15: std::rt::lang_start::<()>::{closure#0}
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/std/src/rt.rs:206:18
  16: <&dyn core::ops::function::Fn<(), Output = i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe as core::ops::function::FnOnce<()>>::call_once
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/core/src/ops/function.rs:287:21
  17: std::panicking::catch_unwind::do_call::<&dyn core::ops::function::Fn<(), Output = i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe, i32>
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/std/src/panicking.rs:581:40
  18: std::panicking::catch_unwind::<i32, &dyn core::ops::function::Fn<(), Output = i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe>
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/std/src/panicking.rs:544:19
  19: std::panic::catch_unwind::<&dyn core::ops::function::Fn<(), Output = i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe, i32>
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/std/src/panic.rs:359:14
  20: std::rt::lang_start_internal::{closure#0}
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/std/src/rt.rs:175:24
  21: std::panicking::catch_unwind::do_call::<std::rt::lang_start_internal::{closure#0}, isize>
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/std/src/panicking.rs:581:40
---
  28: __libc_start_main
  29: _start


Command has failed. Rerun with -v to see more details.
Bootstrap failed while executing `test src/tools/tidy tidyselftest --extra-checks=py,cpp,js,spellcheck`
Build completed unsuccessfully in 0:02:48
  local time: Fri May 29 09:43:45 UTC 2026
  network time: Fri, 29 May 2026 09:43:45 GMT
##[error]Process completed with exit code 1.

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

Labels

F-reborrow `#![feature(reborrow)]`; see #145612 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

3 participants