admin管理员组

文章数量:1313742

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 {}
Share Improve this question edited Jan 30 at 20:57 Tobias Bergkvist asked Jan 30 at 20:54 Tobias BergkvistTobias Bergkvist 2,4841 gold badge25 silver badges25 bronze badges 1
  • 3 docs.rs/imply-hack/0.1.0/imply_hack – kmdreko Commented Jan 30 at 20:57
Add a comment  | 

1 Answer 1

Reset to default 1

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 {}

本文标签: rustHow can I make a quotreversequot bound part of a traitStack Overflow