1

I am trying to make some convenience methods so I can call banana.get(&conn, &pk) or banana.delete(&conn) on an instance of Banana, but I can't get the trait bounds right and seem to keep getting a recursion error:

Cargo.toml

[package]
name = "m"
version = "0.1.0"
edition = "2018"

[dependencies]
diesel = { version = "1.4.5", features = ["postgres"] }

src/lib.rs

use diesel::PgConnection;
use diesel::{
    associations::{HasTable, Identifiable},
    delete,
    query_dsl::QueryDsl,
    result::QueryResult,
};

pub trait DbModel: HasTable + Identifiable + QueryDsl {
    fn get(
        conn: &PgConnection,
        pk: &<Self as Identifiable>::Id,
    ) -> QueryResult<Self> {
        Self::table().find(pk).first(conn)
    }

    fn delete(&self, conn: &PgConnection) -> QueryResult<usize> {
        delete(self).execute(conn)
    }
}

Errors on build:

error[E0275]: overflow evaluating the requirement `_: std::marker::Sized`
  --> src/lib.rs:14:23
   |
14 |         Self::table().find(pk).first(conn)
   |                       ^^^^
   |
   = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`m`)
   = note: required because of the requirements on the impl of `diesel::query_dsl::filter_dsl::FilterDsl<_>` for `<<Self as diesel::associations::HasTable>::Table as diesel::query_builder::AsQuery>::Query`

Errors for delete when get is commented out:

error[E0275]: overflow evaluating the requirement `_: std::marker::Sized`
   --> src/lib.rs:18:9
    |
18  |         delete(self).execute(conn)
    |         ^^^^^^
    | 
   ::: /home/danj/.cargo/registry/src/github.com-1ecc6299db9ec823/diesel-1.4.5/src/query_builder/functions.rs:135:18
    |
135 | pub fn delete<T: IntoUpdateTarget>(source: T) -> DeleteStatement<T::Table, T::WhereClause> {
    |                  ---------------- required by this bound in `diesel::query_builder::functions::delete`
    |
    = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`m`)
    = note: required because of the requirements on the impl of `diesel::query_dsl::filter_dsl::FilterDsl<_>` for `<<Self as diesel::associations::HasTable>::Table as diesel::query_builder::AsQuery>::Query`
    = note: required because of the requirements on the impl of `diesel::query_builder::update_statement::target::IntoUpdateTarget` for `&Self`

Compiling using cargo 1.46.0-nightly (c26576f9a 2020-06-23)

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Dan Jenson
  • 961
  • 7
  • 20
  • It looks like your question might be answered by the answers of [Generic usage of Diesel's find or filter to perform deletions](https://stackoverflow.com/q/55213466/155423); [Why do I get “overflow evaluating the requirement `Sized`” when using tokio_io's read_exact with a Rc?](https://stackoverflow.com/q/50189976/155423). If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Aug 31 '20 at 16:27
  • You need to add one of the bounds mentioned in the `note: required because of the requirements on the impl of …` from the compiler output to your trait bounds. If than another error occurs just keep adding trait bounds if you really want to go down that route. – weiznich Sep 01 '20 at 13:12
  • @weiznich, so I did that until I got to private trait bounds, and couldn't figure out how to go any further: https://gist.github.com/danjenson/c06736a7bf6910068440ff86f0f1e879 – Dan Jenson Sep 11 '20 at 18:42
  • @weiznich, essentially I have `get` and `delete` methods copied into each of the `impl`s for my entities, and it feels so not DRY; the code looks like it should be able to be pulled out into a trait, but it has proven exceedingly difficult for me: https://gist.github.com/danjenson/e51c2d54badd37fd7d64f40141be0d68 – Dan Jenson Sep 11 '20 at 19:30
  • First of all, you call the "duplication" of similar queries not DRY, but would you call the repetition of `INSERT INTO` in plain SQL statements as not DRY? (If not, the diesel dsl is basically the same). Other than that, for private types you likely want to use on of the typedefs exposed in `diesel::dsl`, so something like `diesel::dsl::Filter` for this case. – weiznich Sep 15 '20 at 09:18

1 Answers1

1

This was happening for me when I was trying to use Enums.

I used something like this for my enum code:

#[derive(
    Debug, Clone, Serialize, Deserialize, GraphQLEnum, DbEnum
)]
#[ExistingTypePath = "crate::models::schema::sql_types::UnitStatus"]
pub enum UnitStatus {
    NotStarted,
    InProgress,
    Completed,
}

Using diesel-derive-enum crate for DbEnum derive. My problem was that I was using AsExpression with DbEnum so it couldn't resolve which to use (I think)

Removing AsExpression and just using DbEnum with the ExistingTypePath fixed the issue.

mateos
  • 1,405
  • 1
  • 17
  • 26