Skip to content

Commit

Permalink
Change the order of generic arguments for InsertValues
Browse files Browse the repository at this point in the history
This commit changes to order of generic arguments for the `InsertValues`
trait. This allows us to generate a sound impl of that trait via
`#[derive(MultiConnection)]` that will be accepted by future rust
compiler versions as well. This works as the backend type is this case
local, while the table type is generic. By having first the backend type
and then the table type we first have the local type, which is allowed
according to the rust coherence rules.

This is no breaking change as `InsertValues` is not part of the public
API: https://docs.diesel.rs/2.1.x/diesel/index.html?search=insertvalues

This fixes #4035
  • Loading branch information
weiznich committed May 28, 2024
1 parent db6730c commit 54cbf9b
Show file tree
Hide file tree
Showing 5 changed files with 11 additions and 11 deletions.
8 changes: 4 additions & 4 deletions diesel/src/insertable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ where
}
}

pub trait InsertValues<T: Table, DB: Backend>: QueryFragment<DB> {
pub trait InsertValues<DB: Backend, T: Table>: QueryFragment<DB> {
fn column_names(&self, out: AstPass<'_, '_, DB>) -> QueryResult<()>;
}

Expand Down Expand Up @@ -154,7 +154,7 @@ impl<T> Default for DefaultableColumnInsertValue<T> {
}
}

impl<Col, Expr, DB> InsertValues<Col::Table, DB>
impl<Col, Expr, DB> InsertValues<DB, Col::Table>
for DefaultableColumnInsertValue<ColumnInsertValue<Col, Expr>>
where
DB: Backend + SqlDialect<InsertWithDefaultKeyword = sql_dialect::default_keyword_for_insert::IsoSqlDefaultKeyword>,
Expand All @@ -168,7 +168,7 @@ where
}
}

impl<Col, Expr, DB> InsertValues<Col::Table, DB> for ColumnInsertValue<Col, Expr>
impl<Col, Expr, DB> InsertValues<DB, Col::Table> for ColumnInsertValue<Col, Expr>
where
DB: Backend,
Col: Column,
Expand Down Expand Up @@ -218,7 +218,7 @@ where
}

#[cfg(feature = "sqlite")]
impl<Col, Expr> InsertValues<Col::Table, crate::sqlite::Sqlite>
impl<Col, Expr> InsertValues<crate::sqlite::Sqlite, Col::Table>
for DefaultableColumnInsertValue<ColumnInsertValue<Col, Expr>>
where
Col: Column,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ where
T: Table + Copy + QueryId + 'static,
T::FromClause: QueryFragment<Sqlite>,
Op: Copy + QueryId + QueryFragment<Sqlite>,
V: InsertValues<T, Sqlite> + CanInsertInSingleQuery<Sqlite> + QueryId,
V: InsertValues<Sqlite, T> + CanInsertInSingleQuery<Sqlite> + QueryId,
{
fn execute((Yes, query): Self, conn: &mut C) -> QueryResult<usize> {
conn.transaction(|conn| {
Expand Down
2 changes: 1 addition & 1 deletion diesel/src/query_builder/insert_statement/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ impl<T, Tab, DB> QueryFragment<DB> for ValuesClause<T, Tab>
where
DB: Backend,
Tab: Table,
T: InsertValues<Tab, DB>,
T: InsertValues<DB, Tab>,
DefaultValues: QueryFragment<DB>,
{
fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
Expand Down
4 changes: 2 additions & 2 deletions diesel/src/type_impls/tuples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,11 @@ macro_rules! tuple_impls {
}

#[allow(unused_assignments)]
impl<$($T,)+ Tab, __DB> InsertValues<Tab, __DB> for ($($T,)+)
impl<$($T,)+ Tab, __DB> InsertValues<__DB, Tab> for ($($T,)+)
where
Tab: Table,
__DB: Backend,
$($T: InsertValues<Tab, __DB>,)+
$($T: InsertValues<__DB, Tab>,)+
{
fn column_names(&self, mut out: AstPass<'_, '_, __DB>) -> QueryResult<()> {
let mut needs_comma = false;
Expand Down
6 changes: 3 additions & 3 deletions diesel_derives/src/multiconnection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1195,7 +1195,7 @@ fn generate_querybuilder(connection_types: &[ConnectionVariant]) -> TokenStream
let ty = c.ty;
quote::quote! {
super::backend::MultiBackend::#ident(_) => {
<Self as diesel::insertable::InsertValues<Col::Table, <#ty as diesel::connection::Connection>::Backend>>::column_names(
<Self as diesel::insertable::InsertValues<<#ty as diesel::connection::Connection>::Backend, Col::Table>>::column_names(
&self,
out.cast_database(
super::bind_collector::MultiBindCollector::#lower_ident,
Expand All @@ -1214,7 +1214,7 @@ fn generate_querybuilder(connection_types: &[ConnectionVariant]) -> TokenStream
let insert_values_backend_bounds = connection_types.iter().map(|c| {
let ty = c.ty;
quote::quote! {
diesel::insertable::DefaultableColumnInsertValue<diesel::insertable::ColumnInsertValue<Col, Expr>>: diesel::insertable::InsertValues<Col::Table, <#ty as diesel::connection::Connection>::Backend>
diesel::insertable::DefaultableColumnInsertValue<diesel::insertable::ColumnInsertValue<Col, Expr>>: diesel::insertable::InsertValues<<#ty as diesel::connection::Connection>::Backend, Col::Table>
}
});

Expand Down Expand Up @@ -1405,7 +1405,7 @@ fn generate_querybuilder(connection_types: &[ConnectionVariant]) -> TokenStream
}
}

impl<Col, Expr> diesel::insertable::InsertValues<Col::Table, super::multi_connection_impl::backend::MultiBackend>
impl<Col, Expr> diesel::insertable::InsertValues<super::multi_connection_impl::backend::MultiBackend, Col::Table>
for diesel::insertable::DefaultableColumnInsertValue<diesel::insertable::ColumnInsertValue<Col, Expr>>
where
Col: diesel::prelude::Column,
Expand Down

0 comments on commit 54cbf9b

Please sign in to comment.