Repository: diesel-rs/diesel (language: rust)

Issue:
Selectable's check_for_backend ignores deserialize_as attribute
This causes it to generate a `_check_field_compatibility` that verifies that the final target type matches the schema, instead of the type it will actually be deserialized in, causing unnecessary compilation errors until `check_for_backend` is disabled.


Discussion / hints:
Yes that's a bug in this code:

https://github.com/diesel-rs/diesel/blob/3590184026fd6888715bc51728b5dc0fb9df0df6/diesel_derives/src/selectable.rs#L53

We need to call `ty_for_deserialize()` there instead of directly using `f.ty`.

Fix patch:
diff --git a/diesel_derives/src/selectable.rs b/diesel_derives/src/selectable.rs
index 5edc93138c10..4d0b92b4c637 100644
--- a/diesel_derives/src/selectable.rs
+++ b/diesel_derives/src/selectable.rs
@@ -50,7 +50,7 @@ pub fn derive(item: DeriveInput) -> Result<TokenStream> {
             .filter(|(f, _)| !f.embed())
             .flat_map(|(f, ty)| {
                 backends.iter().map(move |b| {
-                    let field_ty = to_field_ty_bound(&f.ty);
+                    let field_ty = to_field_ty_bound(f.ty_for_deserialize());
                     let span = field_ty.span();
                     quote::quote_spanned! {span =>
                         #field_ty: diesel::deserialize::FromSqlRow<diesel::dsl::SqlTypeOf<#ty>, #b>


Test patch:
diff --git a/diesel_derives/tests/helpers.rs b/diesel_derives/tests/helpers.rs
index 361f68d09ca8..79715735f8c7 100644
--- a/diesel_derives/tests/helpers.rs
+++ b/diesel_derives/tests/helpers.rs
@@ -1,6 +1,9 @@
 use diesel::prelude::*;
 use diesel::sql_query;
 
+#[allow(dead_code)] // that's used in one of the compile tests
+pub type TestBackend = <TestConnection as diesel::Connection>::Backend;
+
 cfg_if! {
     if #[cfg(feature = "sqlite")] {
         pub type TestConnection = SqliteConnection;
diff --git a/diesel_derives/tests/selectable.rs b/diesel_derives/tests/selectable.rs
index a4aba7b49863..af1c73e4591c 100644
--- a/diesel_derives/tests/selectable.rs
+++ b/diesel_derives/tests/selectable.rs
@@ -145,3 +145,30 @@ fn manually_specified_expression() {
     let data = my_structs::table.select(A::as_select()).get_result(conn);
     assert!(data.is_err());
 }
+
+#[allow(dead_code)] // that's essentially a compile test
+#[test]
+fn check_for_backend_with_deserialize_as() {
+    table! {
+        tests {
+            id -> Integer,
+            name -> Text,
+        }
+    }
+
+    struct MyString(String);
+
+    impl From<String> for MyString {
+        fn from(s: String) -> Self {
+            Self(s)
+        }
+    }
+
+    #[derive(Queryable, Selectable)]
+    #[diesel(check_for_backend(crate::helpers::TestBackend))]
+    struct Test {
+        id: i32,
+        #[diesel(deserialize_as = String)]
+        name: MyString,
+    }
+}