Cheat-code for bypassing trait bounds!

There was previously another post demonstrating a way to bypass trait bounds. That one was a bit too unreadable. Here’s my take on it.

trait Super {
    type Assoc;
}

trait Sub: Super<Assoc: std::fmt::Debug> {}

fn do_debug<O: Sub + ?Sized>(x: O::Assoc) {
    println!("{x:?}");
}

// Doesn't need T: Debug
// Debug-prints the value of x.
// Works even in generic contexts where we don't have a T: Debug bound.
fn debug<T>(x: T) {
    do_debug::<dyn Sub<Assoc = T>>(x);
}

fn main() {
    debug("lol");
    debug(123);
}

(playground)

Based on: Associated type bound from supertrait isn't checked for trait object · Issue #152607 · rust-lang/rust · GitHub

Obviously don’t use this in production lol

7 Likes

And by adding a struct NotDebug and debug(NotDebug), we actually can turn this example into an ICE.

2 Likes

This is actually just Rust adding support for C++-style duck-typed templates, and the long and mostly-irrelevant information contained in the ICE message is part of the experience.

17 Likes

and that's why existence of each and every type should be demonstrated /j

Maybe silly question... What's an ICE in this context?

It's an "Internal Compilation Error" (or "internal compiler error"), where the compiler itself panics.

1 Like

Playground link with the ICE, for reference