diesel-rs/diesel · error · syn::Error

references are not supported in `Queryable` types consider…

Error message

references are not supported in `Queryable` types
consider using `std::borrow::Cow<'{}, {}>` instead

What it means

The `#[derive(Queryable)]` proc macro in diesel_derives generates code that checks each field type of the struct against the query row. Fields declared as references (e.g. `&'a str`) cannot be supported because generated deserialization code cannot produce borrows with valid lifetimes from the row. The macro explicitly rejects `syn::Type::Reference` fields in `to_field_ty_bound` and suggests `std::borrow::Cow` as a replacement that can own or borrow data.

Solutions

  1. Change the reference field to an owned type (`String`, `Vec<u8>`) or `std::borrow::Cow<'a, str>`.
  2. If you must avoid allocation, deserialize to owned types and borrow afterwards, or use `sql_types::Text` mappings with owned `String`.
  3. If the reference is unnecessary, drop the lifetime entirely and use owned field types.

Example fix

// before
#[derive(Queryable)]
struct User<'a> {
    name: &'a str,
}

// after
use std::borrow::Cow;
#[derive(Queryable)]
struct User<'a> {
    name: Cow<'a, str>,
}
// or simply: struct User { name: String }
Defensive patterns

Strategy: type-guard

Validate before calling

// Compile-time check: this fails to compile if any field is a reference
fn assert_no_refs<T>() {}
struct User { name: String }
fn main() { assert_no_refs::<User>(); }

Type guard

fn has_reference_fields<'a>(s: &'a str) -> bool { std::mem::size_of_val(&s) == std::mem::size_of::<&'a str>() && false } // Prefer: simply use owned or Cow<'a, T> field types so the derive always compiles

Prevention

When it happens

Trigger: Deriving `Queryable` (or `QueryableByName`/`Selectable` checked via `generate_check_function`) on a struct containing a reference-typed field such as `name: &'a str` or `&'a [u8]`.

Common situations: Developers porting structs that borrowed from input data, trying to avoid allocations in query results, or copying a struct shape that works with serde but not with diesel's `Queryable` derive.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of diesel-rs/diesel@6fa6ed01b2 (2026-09-07). Data as JSON: /api/errors/97d419a1feb72bf1. Report an issue: GitHub.

Appendix: source

Thrown at diesel_derives/src/selectable.rs:150

    let where_clause = where_clause.get_or_insert_with(|| parse_quote!(where));
    for field_check in field_check_bound {
        where_clause.predicates.push(field_check);
    }
    Ok(quote::quote! {
        fn #function_name #original_impl_generics()
            #where_clause
        {}
    })
}

fn to_field_ty_bound(field_ty: &syn::Type) -> Result<TokenStream> {
    match field_ty {
        syn::Type::Reference(r) => {
            use crate::quote::ToTokens;
            // references are not supported for checking for now
            //
            // (How ever you can even have references in a `Queryable` struct anyway)
            Err(syn::Error::new(
                field_ty.span(),
                format!(
                    "references are not supported in `Queryable` types\n\
                         consider using `std::borrow::Cow<'{}, {}>` instead",
                    r.lifetime
                        .as_ref()
                        .expect("It's a struct field so it must have a named lifetime")
                        .ident,
                    r.elem.to_token_stream()
                ),
            ))
        }
        field_ty => Ok(quote::quote! {
            #field_ty
        }),
    }
}

View on GitHub (pinned to 6fa6ed01b2)