Reputation: 123
Is there a way to take a borrow of a type and add a trait bound on the inner type (i.e. you have type &T but want to say where T something)
I was assuming I could require &T to have ToOwned and then add the constraint to the Owned type but that seems to keep the borrow e.g. in this little example. Why does the below not work and is there a way I can get the inner type?
let c: <&i32 as ToOwned>::Owned = 1;
// ^ expected &i32, found i32
My ultimate goal here is to be able to take in a type which implemented diesel::Identifiable and the Id of that Identifiable must implement Deserialize. Currently I have a struct like this
#[derive(Queryable, Selectable, Identifiable, serde::Serialize, serde::Deserialize)]
#[diesel(table_name = crate::schema::my_models)]
#[diesel(check_for_backend(diesel::pg::Pg))]
pub struct MyDieselModel {
pub id: i32,
pub title: String,
pub body: String,
pub published: bool,
}
and a function along these lines:
fn use_model<'ident, T>(model: T)
where
T: HasTable,
&'ident T: Identifiable
<&'ident TModel as Identifiable>::Id: Send + ToOwned,
<<&'ident TModel as Identifiable>::Id as ToOwned>::Owned: Deserialize<'ident>,
{
...
}
If I call use_model<MyDieselModel>()
it fails saying
the trait bound `&i32: Deserialize<'_>` is not satisfied
the trait `Deserialize<'_>` is implemented for `i32`
for that trait implementation, expected `i32`, found `&i32`
which makes total sense given the above example where ::Owned isn't giving the type inside the borrow... Any ideas on how I can achieve this ?
Upvotes: 1
Views: 86
Reputation: 23246
Note that ToOwned
is implemented for T
, not for &T
and that <T as ToOwned>::Owned
is T
itself. You can get the pointed type for a reference with Deref::Target
:
use std::ops::Deref;
fn main() {
let _c: <&i32 as Deref>::Target = 1;
}
Upvotes: 3