Type Parameter Constraints on Return Type

I have a trait Table and a struct RowTable that implements Table. I have another struct that has a field with a type of &'a T where T: Table. I'd like to return this type (playground):

pub trait Table {
    fn foo<'a, T: Table>(&self) -> TableSlice<'a, T>;
}

pub struct TableSlice<'a, T: Table> {
    table: &'a T
}

pub struct RowTable { }

impl Table for RowTable {
    fn foo<'a, T: Table>(&self) -> TableSlice<'a, T> {
        TableSlice{ table: self }
    }
}

However, I get the following error:

error[E0308]: mismatched types
  --> src/main.rs:15:28
   |
15 |         TableSlice{ table: self }
   |                            ^^^^ expected type parameter, found struct `RowTable`
   |
   = note: expected type `&T`
              found type `&RowTable`

How can I accomplish this? Thanks!

foo<'a, T: Table>(&self) -> TableSlice<'a, T> requires implementors to be able to work with any and all T: Table type parameters when the method is called. But you tried to implement just for your own type Self.

If you always expect to return your own type, try fn foo<'a>(&self) -> TableSlice<'a, Self> instead. Otherwise, you might want make this an associated type, and then implementors can choose to use their own Self or something else.

pub trait Table {
    type Output: Table;
    fn foo<'a>(&self) -> TableSlice<'a, Self::Output>;
}

impl Table for RowTable {
    type Output = Self;
    fn foo<'a>(&self) -> TableSlice<'a, Self::Output> {
        TableSlice{ table: self }
    }
}

The next problem is that the lifetime 'a is floating, not connected to any inputs. You may want that to borrow &'a self, in which case you can also omit the lifetimes altogether to leave it implied.

If you always expect to return your own type, try fn foo<'a>(&self) -> TableSlice<'a, Self> instead.

I do! RowTable will/should only ever return TableSlice<'a, RowTable>. There were a few more details, so I'm going to post (playground) what I was able to get working for the next person:

use std::marker::Sized;

pub trait Table {
    fn foo(&self) -> TableSlice<Self> where Self: Sized;
}

pub struct TableSlice<'a, T: Table> {
    table: &'a T
}

pub struct RowTable { }

impl Table for RowTable {
    fn foo(&self) -> TableSlice<RowTable> {
        TableSlice{ table: self }
    }
}

@cuviper, thank you VERY much for the help here!!!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.