-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Rust Version
1.94.0
Diesel Version
2.3.7
Diesel Features
sqlite returning_clauses_for_sqlite_3_35 uuid chrono
Database Version
Sqlite 3.43.2
Operating System Version
macOS 15.7.3 (Sequoia) arm64
What happened?
See the reproduction example below.
To me, it looks like, if #[diesel(serialize_as)] or #[diesel(deserialize_as)] is present in the struct definition (in this example, MyTable), the derive macro #[derive(AsChangeset)] always tries to implement AsChangeset for &'update MyTable.
However, if the struct contains a field with #[diesel(embed)] and its type (I've called it Embed) does not implement &'update Embed: AsChangeset, this leads to a compilation error.
The error goes away in both the following cases:
- if I comment the line marked with
(1):&'update Embed: AsChangesetis now derived and the implementation of&'update MyTable: AsChangesetworks; - if I uncomment the line marked with
(2):#[derive(AsChangeset)]detects the use of#[diesel(serialize_as)]/#[diesel(deserialize_as)]and doesn't try to implement&'update MyTable: AsChangeset.
What did you expect to happen?
I think #[derive(AsChangeset)] should not try and implement &'update MyTable: AsChangeset if at least one field has a type that does not implement the trait by reference (especially #[diesel(embed)]ded fields).
However, it should implement MyTable: AsChangeset correctly.
Additional details
No response
Steps to reproduce
use diesel::{
deserialize::{FromSql, FromSqlRow},
expression::AsExpression,
prelude::*,
serialize::ToSql,
sql_types::Text,
sqlite::Sqlite,
};
#[derive(Debug, Clone, PartialEq, Eq, AsExpression, FromSqlRow)]
#[diesel(sql_type = Text)]
struct Foo(String);
impl From<String> for Foo {
fn from(value: String) -> Self {
Foo(value)
}
}
impl Into<String> for Foo {
fn into(self) -> String {
self.0
}
}
impl FromSql<Text, Sqlite> for Foo {
fn from_sql(
bytes: <Sqlite as diesel::backend::Backend>::RawValue<'_>,
) -> diesel::deserialize::Result<Self> {
<String as FromSql<Text, Sqlite>>::from_sql(bytes).map(Self)
}
}
impl ToSql<Text, Sqlite> for Foo {
fn to_sql<'b>(
&'b self,
out: &mut diesel::serialize::Output<'b, '_, Sqlite>,
) -> diesel::serialize::Result {
ToSql::<Text, Sqlite>::to_sql(&self.0, out)
}
}
diesel::table! {
my_table(id) {
id -> Text,
foo -> Text,
bar -> Text,
}
}
#[derive(Queryable, Selectable, AsChangeset)]
#[diesel(table_name = my_table)]
struct Embed {
#[diesel(serialize_as = String, deserialize_as = String)] // <-- (1)
foo: Foo,
}
#[derive(HasQuery, AsChangeset)]
#[diesel(table_name = my_table)]
struct MyTable {
id: String,
//#[diesel(serialize_as = String, deserialize_as = String)] // <-- (2)
bar: Foo,
#[diesel(embed)]
embed: Embed,
}Compile time error
error[E0277]: the trait bound `&'update Embed: diesel::AsChangeset` is not satisfied
--> src/lib/test.rs:54:20
|
54 | #[derive(HasQuery, AsChangeset)]
| ^^^^^^^^^^^ the trait `diesel::AsChangeset` is not implemented for `&'update Embed`
|
help: the trait `diesel::AsChangeset` is implemented for `Embed`
--> src/lib/test.rs:47:33
|
47 | #[derive(Queryable, Selectable, AsChangeset)]
| ^^^^^^^^^^^
= note: required for `(Grouped<Eq<bar, Bound<Text, &Foo>>>, &Embed)` to implement `diesel::AsChangeset`
= note: the full name for the type has been written to '…'
= note: consider using `--verbose` to print the full type name to the console
= note: this error originates in the derive macro `AsChangeset` (in Nightly builds, run with -Z macro-backtrace for more info)
Checklist
-
I have already looked over the issue tracker and the discussion forum for similar possible closed issues.
-
This issue can be reproduced on Rust's stable channel. (Please submit the issue in the Rust issue tracker instead if that's not the case)
-
This issue can be reproduced without requiring a third party crate