Thanks for using Compiler Explorer
Sponsors
C with Coccinelle
C++ with Coccinelle
Jakt
C++
Ada
Algol68
Analysis
Android Java
Android Kotlin
Assembly
C
C3
Carbon
C++ (Circle)
CIRCT
Clean
CMake
CMakeScript
COBOL
C++ for OpenCL
MLIR
Cppx
Cppx-Blue
Cppx-Gold
Cpp2-cppfront
Crystal
C#
CUDA C++
D
Dart
Elixir
Erlang
Fortran
F#
GLSL
Go
Haskell
HLSL
Hook
Hylo
IL
ispc
Java
Julia
Kotlin
LLVM IR
LLVM MIR
Modula-2
Nim
Numba
Objective-C
Objective-C++
OCaml
Odin
OpenCL C
Pascal
Pony
Python
Racket
Ruby
Rust
Snowball
Scala
Slang
Solidity
Spice
SPIR-V
Swift
LLVM TableGen
Toit
TypeScript Native
V
Vala
Visual Basic
Vyper
WASM
Zig
Javascript
GIMPLE
Ygen
sway
rust source #1
Output
Compile to binary object
Link to binary
Execute the code
Intel asm syntax
Demangle identifiers
Verbose demangling
Filters
Unused labels
Library functions
Directives
Comments
Horizontal whitespace
Debug intrinsics
Compiler
mrustc (master)
rustc 1.0.0
rustc 1.1.0
rustc 1.10.0
rustc 1.11.0
rustc 1.12.0
rustc 1.13.0
rustc 1.14.0
rustc 1.15.1
rustc 1.16.0
rustc 1.17.0
rustc 1.18.0
rustc 1.19.0
rustc 1.2.0
rustc 1.20.0
rustc 1.21.0
rustc 1.22.0
rustc 1.23.0
rustc 1.24.0
rustc 1.25.0
rustc 1.26.0
rustc 1.27.0
rustc 1.27.1
rustc 1.28.0
rustc 1.29.0
rustc 1.3.0
rustc 1.30.0
rustc 1.31.0
rustc 1.32.0
rustc 1.33.0
rustc 1.34.0
rustc 1.35.0
rustc 1.36.0
rustc 1.37.0
rustc 1.38.0
rustc 1.39.0
rustc 1.4.0
rustc 1.40.0
rustc 1.41.0
rustc 1.42.0
rustc 1.43.0
rustc 1.44.0
rustc 1.45.0
rustc 1.45.2
rustc 1.46.0
rustc 1.47.0
rustc 1.48.0
rustc 1.49.0
rustc 1.5.0
rustc 1.50.0
rustc 1.51.0
rustc 1.52.0
rustc 1.53.0
rustc 1.54.0
rustc 1.55.0
rustc 1.56.0
rustc 1.57.0
rustc 1.58.0
rustc 1.59.0
rustc 1.6.0
rustc 1.60.0
rustc 1.61.0
rustc 1.62.0
rustc 1.63.0
rustc 1.64.0
rustc 1.65.0
rustc 1.66.0
rustc 1.67.0
rustc 1.68.0
rustc 1.69.0
rustc 1.7.0
rustc 1.70.0
rustc 1.71.0
rustc 1.72.0
rustc 1.73.0
rustc 1.74.0
rustc 1.75.0
rustc 1.76.0
rustc 1.77.0
rustc 1.78.0
rustc 1.79.0
rustc 1.8.0
rustc 1.80.0
rustc 1.81.0
rustc 1.82.0
rustc 1.83.0
rustc 1.84.0
rustc 1.85.0
rustc 1.86.0
rustc 1.9.0
rustc beta
rustc nightly
rustc-cg-gcc (master)
x86-64 GCCRS (GCC master)
x86-64 GCCRS (GCCRS master)
x86-64 GCCRS 14.1 (GCC assertions)
x86-64 GCCRS 14.1 (GCC)
x86-64 GCCRS 14.2 (GCC assertions)
x86-64 GCCRS 14.2 (GCC)
Options
Source code
// An always applicable impl. trait ProjectTo { type Usize; type This; type Myself; } impl<T> ProjectTo for T { type Usize = usize; type This = T; type Myself = T; } // A diverging associated type whose item-bound must not apply // and differs from an always applicable impl. trait Diverges { type Diverge<T: Diverges>: ProjectTo<Usize = &'static str>; } impl Diverges for () { type Diverge<T: Diverges> = T::Diverge<()>; } // We need to transfer the item bound to an existing type while only // using the diverging associated type in a generic context. // // The idea is to use an indirection which uses the diverging associated type // in a where-clause. This then uses its item-bound in the caller and normalizes // via the applicable impl internally. // // `<T as Apply<D::Diverge<()>>::Assoc` for `D: Diverge` has // an invalid item-bound and can be normalized to a concrete type while // `D` is still generic. trait Apply<D> { type Assoc: ProjectTo<Myself = usize>; } impl<T: ProjectTo<Myself = <D as ProjectTo>::Usize>, D> Apply<D> for T { type Assoc = T; } // It's still diffuclt to actually using this item bound as we must // avoid `D::Diverge<()>` being mentioned in the MIR. We otherwise // try to normalize it during codegen and error with overflow instead. fn transmute<D: Diverges>(x: &usize) -> &&'static str { // We need to prove the where-bounds here while `D` is still generic // as they mention `D::Diverge<()>`. // // We normalize `<&'static str as Apply<D::Diverge<()>>>::Assoc` to `&'static str` // here. We therefore need to prove `&'static str: ProjectTo<This = &'static str>` // and `&'static str: Apply<D::Diverge<()>>`. Proving the second where-clause relies // on the item bound of `D::Diverge<()>`. provide_where_bound::<D, _>(x) } // `<T as ProjectTo>::This` normalizes to the rigid associated type // `<T as Apply<D::Diverge<()>>>::Assoc` inside of this function. fn provide_where_bound<D: Diverges, T>(x: &usize) -> &T where T: ProjectTo<This = <T as Apply<D::Diverge<()>>>::Assoc>, T: Apply<D::Diverge<()>>, { // We therefore prove `<T as Apply<D::Diverge<()>>>::Assoc: ProjectTo<Myself = usize>` // here. This holds thanks to the item-bound. apply_where_bound::<T>(x) } // `<T as ProjectTo>::This` normalizes to `T` inside of this function. // THis means we've now get the incorret where-bound `T: ProjectTo<Myself = usize>` // inside of this function. Exploiting this is trivial. fn apply_where_bound<T>(x: &usize) -> &T where <T as ProjectTo>::This: ProjectTo<Myself = usize>, { via_impl::<T>(x) } fn via_impl<T>(x: &<T as ProjectTo>::Myself) -> &T { x } pub fn main() { println!("{}", transmute::<()>(&0)); }
Become a Patron
Sponsor on GitHub
Donate via PayPal
Source on GitHub
Mailing list
Installed libraries
Wiki
Report an issue
How it works
Contact the author
CE on Mastodon
CE on Bluesky
About the author
Statistics
Changelog
Version tree