Skip to content

Conversation

compiler-errors
Copy link
Member

@compiler-errors compiler-errors commented Aug 19, 2025

Fixes #141806

When we have an impossible where clause like dyn Trait<u8>: Sized, this may make a dyn-to-dyn cast like dyn Trait<()> -> dyn trait<u8> to successfully type check as if it were a wide-to-thin ptr cast (discarding metadata):

// Cast to thin pointer is OK
if dst_kind == PointerKind::Thin {
return Ok(CastKind::PtrPtrCast);
}

In borrowck, we are expecting that the only meaningful dyn-to-dyn cast to be a metadata-preserving wide-to-wide ptr cast, which requires that the principals of the dyn pointers are equal. Borrowck additionally assumes that these principals have already been proven equal modulo regions, and we thus ICE since Trait<u8> and Trait<()> do not unify:

// This checks (lifetime part of) vtable validity for pointer casts,
// which is irrelevant when there are aren't principal traits on
// both sides (aka only auto traits).
//
// Note that other checks (such as denying `dyn Send` -> `dyn
// Debug`) are in `rustc_hir_typeck`.
if let ty::Dynamic(src_tty, _src_lt, ty::Dyn) = *src_tail.kind()
&& let ty::Dynamic(dst_tty, dst_lt, ty::Dyn) = *dst_tail.kind()
&& src_tty.principal().is_some()
&& dst_tty.principal().is_some()
{
// Remove auto traits.
// Auto trait checks are handled in `rustc_hir_typeck` as FCW.
let src_obj = Ty::new_dynamic(
tcx,
tcx.mk_poly_existential_predicates(
&src_tty.without_auto_traits().collect::<Vec<_>>(),
),
// FIXME: Once we disallow casting `*const dyn Trait + 'short`
// to `*const dyn Trait + 'long`, then this can just be `src_lt`.
dst_lt,
ty::Dyn,
);
let dst_obj = Ty::new_dynamic(
tcx,
tcx.mk_poly_existential_predicates(
&dst_tty.without_auto_traits().collect::<Vec<_>>(),
),
dst_lt,
ty::Dyn,
);
debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj);
self.sub_types(
src_obj,
dst_obj,
location.to_locations(),
ConstraintCategory::Cast {
is_implicit_coercion: false,
unsize_to: None,
},
)
.unwrap();

This PR fixes this ICE by checking whether the RHS of the cast is considered to be Sized in the environment of the MIR typeck, and if so then skipping over this dyn->dyn principal compatibility check.

r? @lcnr perhaps?

@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 Aug 19, 2025
Copy link
Contributor

@lcnr lcnr left a comment

Choose a reason for hiding this comment

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

@rustbot
Copy link
Collaborator

rustbot commented Aug 23, 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.

@compiler-errors
Copy link
Member Author

@bors r=lcnr

@bors
Copy link
Collaborator

bors commented Aug 24, 2025

📌 Commit e0fb6eb has been approved by lcnr

It is now in the queue for this repository.

@bors bors 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 Aug 24, 2025
jhpratt added a commit to jhpratt/rust that referenced this pull request Aug 24, 2025
…=lcnr

Account for impossible bounds making seemingly unsatisfyable dyn-to-dyn casts

Fixes rust-lang#141806

When we have an impossible where clause like `dyn Trait<u8>: Sized`, this may make a dyn-to-dyn cast like `dyn Trait<()> -> dyn trait<u8>` to successfully type check as if it were a wide-to-thin ptr cast (discarding metadata):

https://github.com/rust-lang/rust/blob/16ad385579cebb6f7d53367c552661b6b51a4a02/compiler/rustc_hir_typeck/src/cast.rs#L862-L865

In borrowck, we are expecting that the only meaningful dyn-to-dyn cast to be a metadata-preserving wide-to-wide ptr cast, which requires that the principals of the dyn pointers are equal. Borrowck additionally assumes that these principals have already been proven equal *modulo regions*, and we thus ICE since `Trait<u8>` and `Trait<()>` do not unify:

https://github.com/rust-lang/rust/blob/16ad385579cebb6f7d53367c552661b6b51a4a02/compiler/rustc_borrowck/src/type_check/mod.rs#L1481-L1524

This PR fixes this ICE by checking whether the RHS of the cast is considered to be Sized in the environment of the MIR typeck, and if so then skipping over this dyn->dyn principal compatibility check.

r? `@lcnr` perhaps?
jhpratt added a commit to jhpratt/rust that referenced this pull request Aug 24, 2025
…=lcnr

Account for impossible bounds making seemingly unsatisfyable dyn-to-dyn casts

Fixes rust-lang#141806

When we have an impossible where clause like `dyn Trait<u8>: Sized`, this may make a dyn-to-dyn cast like `dyn Trait<()> -> dyn trait<u8>` to successfully type check as if it were a wide-to-thin ptr cast (discarding metadata):

https://github.com/rust-lang/rust/blob/16ad385579cebb6f7d53367c552661b6b51a4a02/compiler/rustc_hir_typeck/src/cast.rs#L862-L865

In borrowck, we are expecting that the only meaningful dyn-to-dyn cast to be a metadata-preserving wide-to-wide ptr cast, which requires that the principals of the dyn pointers are equal. Borrowck additionally assumes that these principals have already been proven equal *modulo regions*, and we thus ICE since `Trait<u8>` and `Trait<()>` do not unify:

https://github.com/rust-lang/rust/blob/16ad385579cebb6f7d53367c552661b6b51a4a02/compiler/rustc_borrowck/src/type_check/mod.rs#L1481-L1524

This PR fixes this ICE by checking whether the RHS of the cast is considered to be Sized in the environment of the MIR typeck, and if so then skipping over this dyn->dyn principal compatibility check.

r? ``@lcnr`` perhaps?
bors added a commit that referenced this pull request Aug 24, 2025
Rollup of 6 pull requests

Successful merges:

 - #135761 (Dial down detail of B-tree description)
 - #144373 (remove deprecated Error::description in impls)
 - #145620 (Account for impossible bounds making seemingly unsatisfyable dyn-to-dyn casts)
 - #145783 (add span to struct pattern rest (..))
 - #145817 (cg_llvm: Replace the `llvm::Bool` typedef with a proper newtype)
 - #145820 (raw-dylib-elf: set correct `DT_VERDEFNUM`)

r? `@ghost`
`@rustbot` modify labels: rollup
jhpratt added a commit to jhpratt/rust that referenced this pull request Aug 24, 2025
…=lcnr

Account for impossible bounds making seemingly unsatisfyable dyn-to-dyn casts

Fixes rust-lang#141806

When we have an impossible where clause like `dyn Trait<u8>: Sized`, this may make a dyn-to-dyn cast like `dyn Trait<()> -> dyn trait<u8>` to successfully type check as if it were a wide-to-thin ptr cast (discarding metadata):

https://github.com/rust-lang/rust/blob/16ad385579cebb6f7d53367c552661b6b51a4a02/compiler/rustc_hir_typeck/src/cast.rs#L862-L865

In borrowck, we are expecting that the only meaningful dyn-to-dyn cast to be a metadata-preserving wide-to-wide ptr cast, which requires that the principals of the dyn pointers are equal. Borrowck additionally assumes that these principals have already been proven equal *modulo regions*, and we thus ICE since `Trait<u8>` and `Trait<()>` do not unify:

https://github.com/rust-lang/rust/blob/16ad385579cebb6f7d53367c552661b6b51a4a02/compiler/rustc_borrowck/src/type_check/mod.rs#L1481-L1524

This PR fixes this ICE by checking whether the RHS of the cast is considered to be Sized in the environment of the MIR typeck, and if so then skipping over this dyn->dyn principal compatibility check.

r? ```@lcnr``` perhaps?
bors added a commit that referenced this pull request Aug 25, 2025
Rollup of 5 pull requests

Successful merges:

 - #135761 (Dial down detail of B-tree description)
 - #144373 (remove deprecated Error::description in impls)
 - #145620 (Account for impossible bounds making seemingly unsatisfyable dyn-to-dyn casts)
 - #145817 (cg_llvm: Replace the `llvm::Bool` typedef with a proper newtype)
 - #145820 (raw-dylib-elf: set correct `DT_VERDEFNUM`)

r? `@ghost`
`@rustbot` modify labels: rollup
Zalathar added a commit to Zalathar/rust that referenced this pull request Aug 25, 2025
…=lcnr

Account for impossible bounds making seemingly unsatisfyable dyn-to-dyn casts

Fixes rust-lang#141806

When we have an impossible where clause like `dyn Trait<u8>: Sized`, this may make a dyn-to-dyn cast like `dyn Trait<()> -> dyn trait<u8>` to successfully type check as if it were a wide-to-thin ptr cast (discarding metadata):

https://github.com/rust-lang/rust/blob/16ad385579cebb6f7d53367c552661b6b51a4a02/compiler/rustc_hir_typeck/src/cast.rs#L862-L865

In borrowck, we are expecting that the only meaningful dyn-to-dyn cast to be a metadata-preserving wide-to-wide ptr cast, which requires that the principals of the dyn pointers are equal. Borrowck additionally assumes that these principals have already been proven equal *modulo regions*, and we thus ICE since `Trait<u8>` and `Trait<()>` do not unify:

https://github.com/rust-lang/rust/blob/16ad385579cebb6f7d53367c552661b6b51a4a02/compiler/rustc_borrowck/src/type_check/mod.rs#L1481-L1524

This PR fixes this ICE by checking whether the RHS of the cast is considered to be Sized in the environment of the MIR typeck, and if so then skipping over this dyn->dyn principal compatibility check.

r? ````@lcnr```` perhaps?
@Zalathar
Copy link
Contributor

Tracking down a failure in rollup #145833.

@bors try jobs=dist-various-2

@rust-bors
Copy link

rust-bors bot commented Aug 25, 2025

⌛ Trying commit e0fb6eb with merge 933692e

To cancel the try build, run the command @bors try cancel.

rust-bors bot added a commit that referenced this pull request Aug 25, 2025
Account for impossible bounds making seemingly unsatisfyable dyn-to-dyn casts

try-job: dist-various-2
@compiler-errors
Copy link
Member Author

@bors try cancel

due to that other pr

@rust-bors
Copy link

rust-bors bot commented Aug 25, 2025

Try build cancelled. Cancelled workflows:

bors added a commit that referenced this pull request Aug 25, 2025
Rollup of 10 pull requests

Successful merges:

 - #135761 (Dial down detail of B-tree description)
 - #145620 (Account for impossible bounds making seemingly unsatisfyable dyn-to-dyn casts)
 - #145788 (Fix attribute target checking for macro calls)
 - #145794 (bootstrap.py: Improve CPU detection on NetBSD)
 - #145817 (cg_llvm: Replace the `llvm::Bool` typedef with a proper newtype)
 - #145820 (raw-dylib-elf: set correct `DT_VERDEFNUM`)
 - #145828 (Update `bitflags` to 2.9.3.)
 - #145830 (Remove the lifetime from `ExpTokenPair`/`SeqSep`.)
 - #145836 (Remove outdated bug comments)
 - #145842 (rustc-dev-guide subtree update)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 8a2568a into rust-lang:master Aug 25, 2025
10 of 11 checks passed
@rustbot rustbot added this to the 1.91.0 milestone Aug 25, 2025
rust-timer added a commit that referenced this pull request Aug 25, 2025
Rollup merge of #145620 - compiler-errors:fake-dyn-to-dyn, r=lcnr

Account for impossible bounds making seemingly unsatisfyable dyn-to-dyn casts

Fixes #141806

When we have an impossible where clause like `dyn Trait<u8>: Sized`, this may make a dyn-to-dyn cast like `dyn Trait<()> -> dyn trait<u8>` to successfully type check as if it were a wide-to-thin ptr cast (discarding metadata):

https://github.com/rust-lang/rust/blob/16ad385579cebb6f7d53367c552661b6b51a4a02/compiler/rustc_hir_typeck/src/cast.rs#L862-L865

In borrowck, we are expecting that the only meaningful dyn-to-dyn cast to be a metadata-preserving wide-to-wide ptr cast, which requires that the principals of the dyn pointers are equal. Borrowck additionally assumes that these principals have already been proven equal *modulo regions*, and we thus ICE since `Trait<u8>` and `Trait<()>` do not unify:

https://github.com/rust-lang/rust/blob/16ad385579cebb6f7d53367c552661b6b51a4a02/compiler/rustc_borrowck/src/type_check/mod.rs#L1481-L1524

This PR fixes this ICE by checking whether the RHS of the cast is considered to be Sized in the environment of the MIR typeck, and if so then skipping over this dyn->dyn principal compatibility check.

r? `@lcnr` perhaps?
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:called Result::unwrap() on an Err value: NoSolution
5 participants