Skip to content

Diagnostic regression for proc-macro generated code #123503

Open
@weiznich

Description

@weiznich

Code

I tried this code:

use diesel::prelude::*; // 2.1.5

table! {
    users(id) {
        id -> Integer,
        name -> Text,
    }
}

#[derive(Insertable)]
struct User {
    id: String,
    name: i32,
}

fn main() {}

I expected to see a meaningful error that points to the relevant fields that cause this issue:

error[E0277]: the trait bound `String: diesel::Expression` is not satisfied
  --> src/main.rs:12:5
   |
12 |     id: String,
   |     ^^ the trait `diesel::Expression` is not implemented for `String`
   |
   = help: the following other types implement trait `diesel::Expression`:
             columns::name
             columns::id
             Box<T>
             columns::star
             diesel::expression::ops::numeric::Add<Lhs, Rhs>
             diesel::expression::ops::numeric::Sub<Lhs, Rhs>
             diesel::expression::ops::numeric::Mul<Lhs, Rhs>
             diesel::expression::ops::numeric::Div<Lhs, Rhs>
           and 119 others
   = note: required for `String` to implement `AsExpression<diesel::sql_types::Integer>`

error[E0277]: the trait bound `i32: diesel::Expression` is not satisfied
  --> src/main.rs:13:5
   |
13 |     name: i32,
   |     ^^^^ the trait `diesel::Expression` is not implemented for `i32`
   |
   = help: the following other types implement trait `diesel::Expression`:
             columns::name
             columns::id
             Box<T>
             columns::star
             diesel::expression::ops::numeric::Add<Lhs, Rhs>
             diesel::expression::ops::numeric::Sub<Lhs, Rhs>
             diesel::expression::ops::numeric::Mul<Lhs, Rhs>
             diesel::expression::ops::numeric::Div<Lhs, Rhs>
           and 119 others
   = note: required for `i32` to implement `AsExpression<diesel::sql_types::Text>`

error[E0277]: the trait bound `String: diesel::Expression` is not satisfied
  --> src/main.rs:12:5
   |
12 |     id: String,
   |     ^^ the trait `diesel::Expression` is not implemented for `String`
   |
   = help: the following other types implement trait `diesel::Expression`:
             columns::name
             columns::id
             Box<T>
             columns::star
             diesel::expression::ops::numeric::Add<Lhs, Rhs>
             diesel::expression::ops::numeric::Sub<Lhs, Rhs>
             diesel::expression::ops::numeric::Mul<Lhs, Rhs>
             diesel::expression::ops::numeric::Div<Lhs, Rhs>
           and 119 others
   = note: required for `&'insert String` to implement `diesel::Expression`
   = note: required for `&'insert String` to implement `AsExpression<diesel::sql_types::Integer>`

error[E0277]: the trait bound `i32: diesel::Expression` is not satisfied
  --> src/main.rs:13:5
   |
13 |     name: i32,
   |     ^^^^ the trait `diesel::Expression` is not implemented for `i32`
   |
   = help: the following other types implement trait `diesel::Expression`:
             columns::name
             columns::id
             Box<T>
             columns::star
             diesel::expression::ops::numeric::Add<Lhs, Rhs>
             diesel::expression::ops::numeric::Sub<Lhs, Rhs>
             diesel::expression::ops::numeric::Mul<Lhs, Rhs>
             diesel::expression::ops::numeric::Div<Lhs, Rhs>
           and 119 others
   = note: required for `&'insert i32` to implement `diesel::Expression`
   = note: required for `&'insert i32` to implement `AsExpression<diesel::sql_types::Text>`

Instead, this happened: Rustc emits an error message that duplicates the actual error several times. First it only points to the derive, later versions of the same error message point to the correct fields:

error[E0277]: the trait bound `String: diesel::Expression` is not satisfied
  --> src/main.rs:10:10
   |
10 | #[derive(Insertable)]
   |          ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `String`, which is required by `String: AsExpression<diesel::sql_types::Integer>`
   |
   = help: the following other types implement trait `diesel::Expression`:
             &'a T
             (T0, T1)
             (T0, T1, T2)
             (T0, T1, T2, T3)
             (T0, T1, T2, T3, T4)
             (T0, T1, T2, T3, T4, T5)
             (T0, T1, T2, T3, T4, T5, T6)
             (T0, T1, T2, T3, T4, T5, T6, T7)
           and 119 others
   = note: required for `String` to implement `AsExpression<diesel::sql_types::Integer>`
   = note: this error originates in the derive macro `Insertable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `i32: diesel::Expression` is not satisfied
  --> src/main.rs:10:10
   |
10 | #[derive(Insertable)]
   |          ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `i32`, which is required by `i32: AsExpression<diesel::sql_types::Text>`
   |
   = help: the following other types implement trait `diesel::Expression`:
             &'a T
             (T0, T1)
             (T0, T1, T2)
             (T0, T1, T2, T3)
             (T0, T1, T2, T3, T4)
             (T0, T1, T2, T3, T4, T5)
             (T0, T1, T2, T3, T4, T5, T6)
             (T0, T1, T2, T3, T4, T5, T6, T7)
           and 119 others
   = note: required for `i32` to implement `AsExpression<diesel::sql_types::Text>`
   = note: this error originates in the derive macro `Insertable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `String: diesel::Expression` is not satisfied
  --> src/main.rs:10:10
   |
10 | #[derive(Insertable)]
   |          ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `String`, which is required by `&'insert String: AsExpression<diesel::sql_types::Integer>`
   |
   = help: the following other types implement trait `diesel::Expression`:
             &'a T
             (T0, T1)
             (T0, T1, T2)
             (T0, T1, T2, T3)
             (T0, T1, T2, T3, T4)
             (T0, T1, T2, T3, T4, T5)
             (T0, T1, T2, T3, T4, T5, T6)
             (T0, T1, T2, T3, T4, T5, T6, T7)
           and 119 others
   = note: required for `&'insert String` to implement `diesel::Expression`
   = note: required for `&'insert String` to implement `AsExpression<diesel::sql_types::Integer>`
   = note: this error originates in the derive macro `Insertable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `i32: diesel::Expression` is not satisfied
  --> src/main.rs:10:10
   |
10 | #[derive(Insertable)]
   |          ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `i32`, which is required by `&'insert i32: AsExpression<diesel::sql_types::Text>`
   |
   = help: the following other types implement trait `diesel::Expression`:
             &'a T
             (T0, T1)
             (T0, T1, T2)
             (T0, T1, T2, T3)
             (T0, T1, T2, T3, T4)
             (T0, T1, T2, T3, T4, T5)
             (T0, T1, T2, T3, T4, T5, T6)
             (T0, T1, T2, T3, T4, T5, T6, T7)
           and 119 others
   = note: required for `&'insert i32` to implement `diesel::Expression`
   = note: required for `&'insert i32` to implement `AsExpression<diesel::sql_types::Text>`
   = note: this error originates in the derive macro `Insertable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `String: diesel::Expression` is not satisfied
  --> src/main.rs:12:5
   |
12 |     id: String,
   |     ^^ the trait `diesel::Expression` is not implemented for `String`, which is required by `String: AsExpression<diesel::sql_types::Integer>`
   |
   = help: the following other types implement trait `diesel::Expression`:
             &'a T
             (T0, T1)
             (T0, T1, T2)
             (T0, T1, T2, T3)
             (T0, T1, T2, T3, T4)
             (T0, T1, T2, T3, T4, T5)
             (T0, T1, T2, T3, T4, T5, T6)
             (T0, T1, T2, T3, T4, T5, T6, T7)
           and 119 others
   = note: required for `String` to implement `AsExpression<diesel::sql_types::Integer>`

error[E0277]: the trait bound `i32: diesel::Expression` is not satisfied
  --> src/main.rs:13:5
   |
13 |     name: i32,
   |     ^^^^ the trait `diesel::Expression` is not implemented for `i32`, which is required by `i32: AsExpression<diesel::sql_types::Text>`
   |
   = help: the following other types implement trait `diesel::Expression`:
             &'a T
             (T0, T1)
             (T0, T1, T2)
             (T0, T1, T2, T3)
             (T0, T1, T2, T3, T4)
             (T0, T1, T2, T3, T4, T5)
             (T0, T1, T2, T3, T4, T5, T6)
             (T0, T1, T2, T3, T4, T5, T6, T7)
           and 119 others
   = note: required for `i32` to implement `AsExpression<diesel::sql_types::Text>`

error[E0277]: the trait bound `String: diesel::Expression` is not satisfied
  --> src/main.rs:12:5
   |
12 |     id: String,
   |     ^^ the trait `diesel::Expression` is not implemented for `String`, which is required by `&'insert String: AsExpression<diesel::sql_types::Integer>`
   |
   = help: the following other types implement trait `diesel::Expression`:
             &'a T
             (T0, T1)
             (T0, T1, T2)
             (T0, T1, T2, T3)
             (T0, T1, T2, T3, T4)
             (T0, T1, T2, T3, T4, T5)
             (T0, T1, T2, T3, T4, T5, T6)
             (T0, T1, T2, T3, T4, T5, T6, T7)
           and 119 others
   = note: required for `&'insert String` to implement `diesel::Expression`
   = note: required for `&'insert String` to implement `AsExpression<diesel::sql_types::Integer>`

error[E0277]: the trait bound `i32: diesel::Expression` is not satisfied
  --> src/main.rs:13:5
   |
13 |     name: i32,
   |     ^^^^ the trait `diesel::Expression` is not implemented for `i32`, which is required by `&'insert i32: AsExpression<diesel::sql_types::Text>`
   |
   = help: the following other types implement trait `diesel::Expression`:
             &'a T
             (T0, T1)
             (T0, T1, T2)
             (T0, T1, T2, T3)
             (T0, T1, T2, T3, T4)
             (T0, T1, T2, T3, T4, T5)
             (T0, T1, T2, T3, T4, T5, T6)
             (T0, T1, T2, T3, T4, T5, T6, T7)
           and 119 others
   = note: required for `&'insert i32` to implement `diesel::Expression`
   = note: required for `&'insert i32` to implement `AsExpression<diesel::sql_types::Text>`

Version it worked on

It most recently worked on: Rust 1.74

Version with regression

rustc --version --verbose:

rustc 1.77.0 (aedd173a2 2024-03-17)
binary: rustc
commit-hash: aedd173a2c086e558c2b66d3743b344f977621a7
commit-date: 2024-03-17
host: x86_64-unknown-linux-gnu
release: 1.77.0
LLVM version: 17.0.6

I've checked the stable rust versions in between and the error message first changes in 1.75 which introduces the messages that point to #[derive(Insertable)] but back then these were shown at the end of the output instead as first error message. Bisecting between the two stable releases points to #117159 as PR that introduced the duplicated messages.

Bisect Log

Regression in rust-lang-ci@dc8cfe1
The PR introducing the regression in this rollup is #117159: Work around the fact that check_mod_type_wf may spuriousl…

searched nightlies: from nightly-2023-10-01 to nightly-2023-11-11
regressed nightly: nightly-2023-10-26
searched commit range: df871fb...ab5c841
regressed commit: ab5c841

bisected with cargo-bisect-rustc v0.6.8

Host triple: x86_64-unknown-linux-gnu
Reproduce with:

cargo bisect-rustc --start 1.74.0 --end 1.75.0 --prompt 

The error then changed again between 1.76.0 and 1.77.0 by moving the message mentioning #[derive(Insertable)] at the begin of the error output. Bisecting points to 791a53f as the commit that introduced that change.

Bisect Log Attempting to search unrolled perf builds ERROR: couldn't find perf build comment

searched nightlies: from nightly-2023-12-21 to nightly-2024-02-01
regressed nightly: nightly-2024-01-06
searched commit range: f688dd6...595bc6f
regressed commit: 791a53f

bisected with cargo-bisect-rustc v0.6.8

Host triple: x86_64-unknown-linux-gnu
Reproduce with:

cargo bisect-rustc --start 1.76.0 --end 1.77.0 --prompt 

@rustbot modify labels: +regression-from-stable-to-stable -regression-untriaged +A-diagnostics

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsC-bugCategory: This is a bug.D-verboseDiagnostics: Too much output caused by a single piece of incorrect code.E-needs-mcveCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable ExampleP-mediumMedium priorityregression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions