Consider the following example:
fn myfn<T: Field>()
where X2: Extension<T> {}
I want to create a custom trait XField
that allows me to not repeat the where-bound:
fn myfn<T: XField>() {}
The following does not seem to work (the compiler seems to know that XField requires the where-bound, but still requires me to actually type it out):
fn trait_bound_extension_not_satisfied<T: XField>() {}
trait XField: Field
where X2: Extension<Self> {}
Notice that I want XType
to encapsulate the X2: Extension<Self>
bound, but it doesn't seem to work, possibly because it is a sort of inverse/reverse type bound. Is there a way to do this, or is it not possible in Rust?
For reference, here is a complete code example:
fn this_works<T: Field>()
where X2: Extension<T> {}
fn trait_bound_extension_not_satisfied<T: XField>() {}
trait Field where Self: Sized {}
trait Extension<T: Field> {}
trait XField: Field
where X2: Extension<Self> {}
struct X0;
impl Field for X0 {}
impl Extension<X0> for X0 {}
struct X1;
impl Field for X1 {}
impl Extension<X0> for X1 {}
impl Extension<X1> for X1 {}
struct X2;
impl Field for X2 {}
impl Extension<X0> for X2 {}
impl Extension<X1> for X2 {}
impl Extension<X2> for X2 {}
struct Y0;
impl Field for Y0 {}
impl Extension<Y0> for Y0 {}
Consider the following example:
fn myfn<T: Field>()
where X2: Extension<T> {}
I want to create a custom trait XField
that allows me to not repeat the where-bound:
fn myfn<T: XField>() {}
The following does not seem to work (the compiler seems to know that XField requires the where-bound, but still requires me to actually type it out):
fn trait_bound_extension_not_satisfied<T: XField>() {}
trait XField: Field
where X2: Extension<Self> {}
Notice that I want XType
to encapsulate the X2: Extension<Self>
bound, but it doesn't seem to work, possibly because it is a sort of inverse/reverse type bound. Is there a way to do this, or is it not possible in Rust?
For reference, here is a complete code example:
fn this_works<T: Field>()
where X2: Extension<T> {}
fn trait_bound_extension_not_satisfied<T: XField>() {}
trait Field where Self: Sized {}
trait Extension<T: Field> {}
trait XField: Field
where X2: Extension<Self> {}
struct X0;
impl Field for X0 {}
impl Extension<X0> for X0 {}
struct X1;
impl Field for X1 {}
impl Extension<X0> for X1 {}
impl Extension<X1> for X1 {}
struct X2;
impl Field for X2 {}
impl Extension<X0> for X2 {}
impl Extension<X1> for X2 {}
impl Extension<X2> for X2 {}
struct Y0;
impl Field for Y0 {}
impl Extension<Y0> for Y0 {}
Thanks to kmdreko for referring me to the imply_hack crate! This seems to work, and even produces good error messages:
fn foo<T: XField>() {}
trait XField: Field + Imply<X2, Is: Extension<Self>> {}
impl<T: Field> XField for T
where X2: Extension<T> {}
trait Imply<T>: sealed::ImplyInner<T, Is = T> {}
impl<T, U> Imply<T> for U {}
mod sealed {
pub trait ImplyInner<T> {
type Is;
}
impl<T, U> ImplyInner<T> for U {
type Is = T;
}
}
fn main() {
foo::<X0>(); // works!
foo::<X1>(); // works!
foo::<X2>(); // works!
foo::<Y0>(); // error[E0277]: the trait bound `X2: Extension<Y0>` is not satisfied
}
trait Field where Self: Sized {}
trait Extension<T: Field> {}
struct X0;
impl Field for X0 {}
impl Extension<X0> for X0 {}
struct X1;
impl Field for X1 {}
impl Extension<X0> for X1 {}
impl Extension<X1> for X1 {}
struct X2;
impl Field for X2 {}
impl Extension<X0> for X2 {}
impl Extension<X1> for X2 {}
impl Extension<X2> for X2 {}
struct Y0;
impl Field for Y0 {}
impl Extension<Y0> for Y0 {}