IssueRaiser

Typesystem soundness hole involving cyclically-defined associated type in trait, and normalization in trait bounds

<!-- homu-ignore:start --> *[View all comments](https://triagebot.infra.rust-lang.org/gh-comments/rust-lang/rust/issues/135011)* <!-- homu-ignore:end --> This isn't quite trivial, but well… it works. a “transmute” in safe Rust: ```rust fn main() { let s: String = transmute(vec![65_u8, 66, 67]); println!("{s}"); // ABC } ``` ```rust fn transmute<L, R>(x: L) -> R { transmute_inner_1::<L, R, RewriteReflRight<FakeRefl<L, R>>>(x) } fn transmute_inner_1<L, R, P: TyEq<LHS = L, RHS = R>>(x: L) -> R { transmute_inner_2::<<P::ProofIsProofValue as TyEq>::ProofDef, L, R, P::ProofValue, P>(x) } fn transmute_inner_2<Rw, L, R, Actual, P: TyEq<LHS = L, RHS = R, ProofValue = Actual>>(x: L) -> R where <Rw as TypeIs<P::ProofValue>>::Is: TyEq<LHS = L, RHS = R>, { transmute_inner_3::<L, R, Actual>(x) } fn transmute_inner_3<L, R, P: TyEq<LHS = L, RHS = R>>(x: L) -> R { transmute_inner_4::<R, P::ProofDef>(x) } fn transmute_inner_4<R, Rw>(x: <Rw as TypeIs<R>>::Is) -> R { x } ``` ```rust trait TypeIs<T> { type Is; } impl<_Self, T> TypeIs<T> for _Self { type Is = T; } trait TyEq: TyEqImpl { type ProofDef: TypeIs<Self::RHS, Is = Self::LHS>; } trait TyEqImpl { type LHS; type RHS; type Proof<_Dummy>: TyEq<LHS = Self::LHS, RHS = Self::RHS>; type ProofValue; type ProofIsProofValue: TyEq<LHS = Self::Proof<()>, RHS = Self::ProofValue>; } trait DeriveEqFromImpl {} impl<P: TyEqImpl + DeriveEqFromImpl> TyEq for P { type ProofDef = <P

Posted by steffahn on Jan 2, 2025, 4:22 AM

Tags

Related issues

Raise real-world problems, find people facing the same issue, and discuss solutions.2,000 issues0 comments

github (Sysadmin)

Typesystem soundness hole involving cyclically-defined associated type in trait, and normalization in trait bounds

steffahnJan 2, 2025, 4:22 AM

<!-- homu-ignore:start --> *[View all comments](https://triagebot.infra.rust-lang.org/gh-comments/rust-lang/rust/issues/135011)* <!-- homu-ignore:end --> This isn't quite trivial, but well… it works. a “transmute” in safe Rust: ```rust fn main() { let s: String = transmute(vec![65_u8, 66, 67]); println!("{s}"); // ABC } ``` ```rust fn transmute<L, R>(x: L) -> R { transmute_inner_1::<L, R, RewriteReflRight<FakeRefl<L, R>>>(x) } fn transmute_inner_1<L, R, P: TyEq<LHS = L, RHS = R>>(x: L) -> R { transmute_inner_2::<<P::ProofIsProofValue as TyEq>::ProofDef, L, R, P::ProofValue, P>(x) } fn transmute_inner_2<Rw, L, R, Actual, P: TyEq<LHS = L, RHS = R, ProofValue = Actual>>(x: L) -> R where <Rw as TypeIs<P::ProofValue>>::Is: TyEq<LHS = L, RHS = R>, { transmute_inner_3::<L, R, Actual>(x) } fn transmute_inner_3<L, R, P: TyEq<LHS = L, RHS = R>>(x: L) -> R { transmute_inner_4::<R, P::ProofDef>(x) } fn transmute_inner_4<R, Rw>(x: <Rw as TypeIs<R>>::Is) -> R { x } ``` ```rust trait TypeIs<T> { type Is; } impl<_Self, T> TypeIs<T> for _Self { type Is = T; } trait TyEq: TyEqImpl { type ProofDef: TypeIs<Self::RHS, Is = Self::LHS>; } trait TyEqImpl { type LHS; type RHS; type Proof<_Dummy>: TyEq<LHS = Self::LHS, RHS = Self::RHS>; type ProofValue; type ProofIsProofValue: TyEq<LHS = Self::Proof<()>, RHS = Self::ProofValue>; } trait DeriveEqFromImpl {} impl<P: TyEqImpl + DeriveEqFromImpl> TyEq for P { type ProofDef = <P

Comments (0)

No comments yet. Start the discussion.

Comment on this issue