Skip to content
GitHub no longer supports this web browser. Learn more about the browsers we support.
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Examine our compiler errors, and see if we can improve them #151

Open
sgrif opened this issue Jan 30, 2016 · 12 comments
Open

Examine our compiler errors, and see if we can improve them #151

sgrif opened this issue Jan 30, 2016 · 12 comments

Comments

@sgrif
Copy link
Member

@sgrif sgrif commented Jan 30, 2016

At times, our compiler errors just flat out suck. While in this issue I will list several cases that I've specifically noticed are frequently problematic or have personally encountered, it should not be treated as exhaustive. If you've ever received a non-helpful compiler message from this lib, please comment with details. I do not think we will be able to fix all of them, but we should try to improve this issue before 1.0.

Truly "fixing" this will probably require significantly more control over the "trait not implemented" error, both on the trait itself (e.g. we can give a much better message for any case where SelectableExpression isn't implemented), and also at the function level (e.g. when find doesn't work, we can probably be more specific, even though none of the traits failing are specific to find).

As we attempt to make sure we create good error messages, we should update our compile-fail suite to be significantly more specific about the error messages we generate. While that will make those tests much more brittle, I'd rather have to update them frequently (and thus ensure that the new error message is still reasonable), than accidentally start generating a nonsense error for a common case.

Problem Cases

Recommending Expression instead of AsExpression

A consistent source of confusion is rustc's recommendation to implement Expression, NonAggregate, and QueryFragment, when the missing piece is actually AsExpression. Ultimately this is due to rust-lang/rust#28894. If we can't fix that issue in the language, we should probably just remove that blanket impl and brute force it instead (I'm honestly surprised the coherence rules haven't forced this already, I think this is the only blanket impl that's survived).

Some types are too long to ever appear in error messages

Another case that we should look for is any case where SelectStatement or FilterQuerySource end up in the final error message. It doesn't matter what trait is missing, the error message SelectStatement<(type1, type2, type3, 10moretypes), (col1, col2, col3, 10morecolumns), InnerJoinQuerySource<left_table, right_table>, NoWhereClause, NoOrderClause, NoLimitClause, NoOffsetClause> does not implement AsQuery will always be too noisy to be helpful. That specific error is actually one of the simpler cases, and even with that exact case, every type would have the fully qualified path, and be repeated 3 times (saying it looked at SelectStatement, &SelectStatement, and &mut SelectStatement). It's not uncommon for that kind of error message to take up the entire terminal window.

@jgillich

This comment has been minimized.

Copy link
Contributor

@jgillich jgillich commented Mar 18, 2016

Yes, please. Here is one that drives me crazy:

src/models/artist.rs:17:61: 17:66 error: the trait `diesel::types::FromSqlRow<diesel::types::Integer, diesel::pg::backend::Pg>` is not implemented for the type `collections::string::String` [E0277]

src/models/artist.rs:17         match artists::table.filter(artists::name.eq(name)).first(conn) {

                                                                                    ^~~~~

src/models/artist.rs:17:61: 17:66 help: run `rustc --explain E0277` to see a detailed explanation

src/models/artist.rs:17:61: 17:66 help: the following implementations were found:

src/models/artist.rs:17:61: 17:66 help:   <collections::string::String as diesel::types::FromSqlRow<diesel::types::VarChar, DB>>

src/models/artist.rs:17:61: 17:66 help:   <collections::string::String as diesel::types::FromSqlRow<diesel::types::Text, DB>>

Model:

#[derive(Queryable)]
pub struct Artist {
    pub name: String,
    pub id: i32
}

I looked at the tests and the code looks alright. But I'm also just getting started with Diesel, so maybe I got something fundamentally wrong..

@sgrif

This comment has been minimized.

Copy link
Member Author

@sgrif sgrif commented Mar 18, 2016

Switch the order of the columns on your model. It's trying to load the ID
column into name and vice versa. This is a separate issue I'd like to
improve.

On Fri, Mar 18, 2016, 6:25 PM Jakob Gillich notifications@github.com
wrote:

Yes, please. Here is one that drives me crazy:

src/models/artist.rs:17:61: 17:66 error: the trait diesel::types::FromSqlRow<diesel::types::Integer, diesel::pg::backend::Pg> is not implemented for the type collections::string::String [E0277]

src/models/artist.rs:17 match artists::table.filter(artists::name.eq(name)).first(conn) {

                                                                                ^~~~~

src/models/artist.rs:17:61: 17:66 help: run rustc --explain E0277 to see a detailed explanation

src/models/artist.rs:17:61: 17:66 help: the following implementations were found:

src/models/artist.rs:17:61: 17:66 help: <collections::string::String as diesel::types::FromSqlRow<diesel::types::VarChar, DB>>

src/models/artist.rs:17:61: 17:66 help: <collections::string::String as diesel::types::FromSqlRow<diesel::types::Text, DB>>

Model:

#[derive(Queryable)]
pub struct Artist {
pub name: String,
pub id: i32
}

I looked at the tests and the code looks alright. But I'm also just
getting started with Diesel, so maybe I got something fundamentally wrong..


You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub
#151 (comment)

@jgillich

This comment has been minimized.

Copy link
Contributor

@jgillich jgillich commented Mar 18, 2016

Oh wow, the order matters? I had no idea haha, thanks!

@sgrif

This comment has been minimized.

Copy link
Member Author

@sgrif sgrif commented Mar 18, 2016

For now, yes. We use indexed access instead of named access for performance
reasons. I want to remove the ordered requirement without impacting that.

On Fri, Mar 18, 2016, 6:30 PM Jakob Gillich notifications@github.com
wrote:

Oh wow, the order matters? I had no idea haha, thanks!


You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub
#151 (comment)

@TheNeikos

This comment has been minimized.

Copy link

@TheNeikos TheNeikos commented Aug 24, 2016

Order Matters

I believe this is something that could be adressed (for now) in the guide as I just stumbled onto this as well, and it cost me around more than hour trying to find out what is going on.

@ggrochow

This comment has been minimized.

Copy link
Contributor

@ggrochow ggrochow commented Mar 24, 2017

This is one you helped me with in gitter.im

error[E0277]: the trait bound `(): diesel::Queryable<(diesel::types::Integer, diesel::types::Integer, diesel::types::Text, diesel::types::Text, diesel::types::Timestamp, diesel::types::Timestamp, diesel::types::Text, diesel::types::Text), diesel::pg::Pg>` is not satisfied
  --> src/models/file.rs:66:24
   |
66 |         let res = self.save_changes(&conn)?;
   |                        ^^^^^^^^^^^^ the trait `diesel::Queryable<(diesel::types::Integer, diesel::types::Integer, diesel::types::Text, diesel::types::Text, diesel::types::Timestamp, diesel::types::Timestamp, diesel::types::Text, diesel::types::Text), diesel::pg::Pg>` is not implemented for `()`

adding an explicit type annotation to res solved this issue

let res: Self = self.save_changes(&conn)?;

@flybayer

This comment has been minimized.

Copy link

@flybayer flybayer commented May 5, 2017

I'm stuck with the below error and can't figure it out. The postgres table was created with Rails which manages the schema.

Error

(reformatted a bit for readability)

error[E0277]: the trait bound
`diesel::types::Timestamp: diesel::types::FromSqlRow<diesel::types::Timestamp, _>` is not satisfied
  --> lora/src/lib.rs:45:31
   |
45 |     let results = end_devices.load::<EndDevice>(&connection).expect("Error loading devices");
   |                               ^^^^ the trait `diesel::types::FromSqlRow<diesel::types::Timestamp, _>` is not implemented for `diesel::types::Timestamp`
   |
   = note: required because of the requirements on the impl of
   `diesel::types::FromSqlRow<(
       diesel::types::BigInt,
       diesel::types::Nullable<diesel::types::Text>,
       diesel::types::Nullable<diesel::types::Text>,
       diesel::types::Timestamp, 
       diesel::types::Timestamp), _>` 
   for 
   `(i64, 
     std::option::Option<std::string::String>, 
     std::option::Option<std::string::String>, 
     diesel::types::Timestamp, 
     diesel::types::Timestamp)`

   = note: required because of the requirements on the impl of `diesel::Queryable<(diesel::types::BigInt, diesel::types::Nullable<diesel::types::Text>, diesel::types::Nullable<diesel::types::Text>, diesel::types::Timestamp, diesel::types::Timestamp), _>` for `models::EndDevice`

Model

#[derive(Queryable)]
pub struct EndDevice {
    pub id: i64,
    pub eui: Option<String>,
    pub app_key: Option<String>,
    pub created_at: types::Timestamp,
    pub updated_at: types::Timestamp,
}

My DB Table

lens_development=# SELECT * FROM end_devices WHERE id=87;
 id |           eui           |             app_key              |         created_at         |         updated_at
----+-------------------------+----------------------------------+----------------------------+----------------------------
 87 | 00-80-00-00-00-00-01-01 | 4F7E61E31F2E9AF39DC0C52CE542909F | 2017-05-04 21:58:56.668025 | 2017-05-04 21:58:56.668025
@Eijebong

This comment has been minimized.

Copy link
Member

@Eijebong Eijebong commented May 5, 2017

You shouldn't use diesel::types::Timestamp
Add the chrono feature instead and use chrono types.

@flybayer

This comment has been minimized.

Copy link

@flybayer flybayer commented May 8, 2017

Thank you @Eijebong, I got it working!

For reference, this is working:

use chrono::prelude::*;

#[derive(Queryable, Debug)]
pub struct EndDevice {
    pub id: i64,
    pub eui: Option<String>,
    pub app_key: Option<String>,
    pub created_at: NaiveDateTime,
    pub updated_at: NaiveDateTime,
}
@killercup

This comment has been minimized.

Copy link
Member

@killercup killercup commented Jul 1, 2017

Just saw rust-lang/rust#43000 and remembered this issue.

I think we talked about it, but I'm not sure what the result was: Did we ever try something like the following?

#![cfg_attr(feature="unstable", feature(on_unimplemented))]

#[cfg_attr(feature="unstable", rustc_on_unimplemented("To query … you can find more info in our docs at http://diesel.rs/")]
pub trait FromSql // …
@sgrif

This comment has been minimized.

Copy link
Member Author

@sgrif sgrif commented Jul 4, 2017

Yes. It doesn't give us the diagnostics we'd need in most cases, and rust-lang/rust#28894 and rust-lang/rust#33094 generally cause our error message to never show up anyway

@sgrif

This comment has been minimized.

Copy link
Member Author

@sgrif sgrif commented Feb 17, 2019

So I discussed this with some folks at the all hands this year, and rustc_on_unimplemented has gotten a lot more functionality since the last time we looked at it. It still won't solve all our problematic cases, but I think it may be enough to help us in a few of them. I'm going to try to look into this further to give the compiler folks more feedback on where it could help, and where we still need better hooks.

This is something I'd like to make a major focus in 2019, hopefully looking into using a lint to help cases that we can't fix with other compiler hooks. A lot has changed since the last activity on this issue, so I'd like to renew the call for "please give us your bad error messages". If you can provide a small, single file script to reproduce the problem (e.g. something we'd be able to add as a compile test to Diesel), that would be much appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants
You can’t perform that action at this time.