From the playground:
println!("{}", (element as &mut Foo<18>).foo(16));
That's a bit different than (bar as [the trait] Foo<4>). There is no &mut Foo<18> trait, so above, you're talking about ($Expression as $Type) -- which is a cast, like @jofas mentioned.
Moreover, you may have noticed the suggestion
error[E0782]: expected a type, found a trait
--> src/main.rs:33:37
|
33 | println!("{}", (element as &mut Foo<18>).foo(16));
| ^^^^^^^
|
help: you can add the `dyn` keyword if you want a trait object
|
33 | println!("{}", (element as &mut dyn Foo<18>).foo(16));
| +++
Which does indeed compile, performing a cast to the &mut dyn Foo<18> type and dynamically dispatching to the method. On edition 2015 and edition 2018, the dyn indicator is optional for backwards compatibility reasons, and the original code compiles.
All in all, I think any variation on ($Expression as $...) is too ambiguous to fly, especially since some of them are valid code in older editions, which would be quite confusing. But maybe other possibilities would be entertained.
// Spit-balling
element.foo::<in Foo<18>>(101);
You could search IRLO to see if it's come up before.
As for alternatives that work today...
// you also do this which is clearly but a lot bulkier but is clearer
<Struct as Foo<18>>::foo(element, 101);
This usually also works.
<_ as Foo<18>>::foo(element, 101);
For this particular example, you could also
pub trait Quz {
fn quz<const X: usize>(&mut self, bar: u64) where Self: Foo<X> {
self.foo(bar);
}
}
impl<T: ?Sized> Quz for T {}
// ...
element.quz::<18>(101);