Skip to content

Commit 5d8f3e9

Browse files
committed
Improve the error message when insert is called with an owned value
Prior to this commit, the error will occur when you attempt to call `execute`, `get_result`, or `get_results`. The message will indicate that those methods don't exist, because `InsertQuery` doesn't implement `QueryFragment`, with a very long generic type signature. The reason for this being that `StructName` doesn't implement `Insertable`, `&StructName` does. This now handles this common error as quickly and directly as possible. The error message will now be: ``` error: mismatched types: expected `&_` found `StructName` ``` This does cause a minor change in functionality, as it becomes impossible to pass an owned value to `insert`. I don't think this is a problem, as really the only thing this removes is the ability to construct an insert statement and the return the query without executing it, e.g.: ```rust fn build_insert_query(name: &str) -> Box<QueryFragment<Pg>> { let new_user = NewUser { name: name }; insert(new_user).into(users::table) } ``` However, this case just doesn't seem like it matters, and I'm fine with losing support for it. Fixes diesel-rs#249.
1 parent 4771cb6 commit 5d8f3e9

4 files changed

Lines changed: 37 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ for Rust libraries in [RFC #1105](https://github.com/rust-lang/rfcs/blob/master/
1818
change in the return type of `ToSql` and `FromSql` to have those bounds as
1919
well.
2020

21+
* It is no longer possible to pass an owned value to `diesel::insert`. `insert`
22+
will now give a more helpful error message when you accidentally try to pass
23+
an owned value instead of a reference.
24+
2125
### Fixed
2226

2327
* `#[insertable_into]` can now be used with structs that have lifetimes with

diesel/src/persistable.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use query_source::{Table, Column};
88
/// Represents that a structure can be used to to insert a new row into the database.
99
/// Implementations can be automatically generated by
1010
/// [`#[insertable_into]`](https://github.com/sgrif/diesel/tree/master/diesel_codegen#insertable_intotable_name).
11-
/// This is automatically implemented for `&[T]`, `Vec<T>` and `&Vec<T>` for inserting more than
11+
/// This is automatically implemented for `&[T]` and `&Vec<T>` for inserting more than
1212
/// one record.
1313
pub trait Insertable<T: Table, DB: Backend> {
1414
type Values: InsertValues<DB>;

diesel/src/query_builder/functions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ pub fn delete<T: UpdateTarget>(source: T) -> DeleteStatement<T> {
108108
/// Creates an insert statement. Will add the given data to a table. This
109109
/// function is not exported by default. As with other commands, the resulting
110110
/// query can return the inserted rows if you choose.
111-
pub fn insert<T>(records: T) -> IncompleteInsertStatement<T> {
111+
pub fn insert<'a, T: ?Sized>(records: &'a T) -> IncompleteInsertStatement<&'a T> {
112112
IncompleteInsertStatement::new(records)
113113
}
114114

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#![feature(custom_derive, custom_attribute, plugin)]
2+
#![plugin(diesel_codegen)]
3+
4+
#[macro_use]
5+
extern crate diesel;
6+
7+
use diesel::*;
8+
use diesel::pg::PgConnection;
9+
10+
table! {
11+
users {
12+
id -> Integer,
13+
name -> VarChar,
14+
}
15+
}
16+
17+
#[insertable_into(users)]
18+
struct NewUser<'a> {
19+
name: &'a str,
20+
}
21+
22+
fn main() {
23+
let connection = PgConnection::establish("").unwrap();
24+
let new_user = NewUser { name: "Sean" };
25+
insert(new_user).into(users::table).execute(&connection).unwrap();
26+
//~^ ERROR mismatched types
27+
//~| expected `&_`
28+
//~| found `NewUser<'_>`
29+
//~| ERROR E0275
30+
// The E0275 is a quirk in Rust, not something we actually care about
31+
}

0 commit comments

Comments
 (0)