Feature Request: be able to match traits on 'as'

Idea: It would be nice to match traits on 'as' conversion. This currently can't be done.

Why: I was writing a small reflection lib for my app so I could load the reflection data from a separate dynamic lib and then enumerate the methods / types into the main application.

I was building most this with a proc_macro but was thinking i could just use type_name & a trait to greatly simplify building all the info. However, there isn't a way to match against casting to a static function and the implementation basically became near impossible with a decent interface. I also couldn't use things like transmute_copy to get pointer references since function items have a default size of 0 until cast ... which I can't do inside a trait.

Solution 1: Implement Into for all as conversions by default and people can always match 'as' with an existing trait. Advantage no real compiler changes. Downsides can't actually use the real 'as' syntax here.

Solution 2: New trait matching syntax as(T) then the 'as' syntax could be used within the trait as expected. As is essentially 'compiler magic' as implemented currently so the scope of a change like this I'd imagine is relatively low since the logic in the compiler to detect 'as' compatibility already exists.

impl<F> MyTrait for F 
where F: Copy + as(fn()->())
{
   /*...implementation*/
}

I can work around this with a proc macro but in general having to use proc macros for something that would be otherwise simple seems really really really weird and unnecessary.

Note that lang and libs are both not really a fan of as, since it does too much stuff.

As such, there will likely never be a trait for as, but rather traits for the different parts. Like it would be nice to have WrappingFrom::wrapping_from for the integer uses of as (https://github.com/rust-lang/rfcs/pull/2484#discussion_r200892454).

Does num_traits not have the kinds of things you need?

This could be solved by creating a new conversion trait, which would do the conversions that are currently handled by as. (Is there any magic to as that wouldn't allow this? If there is, could that magic be moved into the trait in question?) This would allow using it as a trait bound.

This could be a good opportunity to split the overloaded functionalities of as: each kind of cast as does could get its own separate trait. That would also make this the first step towards deprecating as.

Some amount of magic is required to e.g. support downcasting from dyn Trait + Auto to dyn Trait for every object-safe Trait and every auto trait Auto, including those in foreign traits.[1] I'd be surprised if there weren't similar hurdles[2] around supporting every possible subtype coercion, say.


  1. Every possible combination of auto-traits, actually. ↩︎

  2. practical if not technical ↩︎

1 Like