Skip to content

Rustc fails to resolve trait bounds #46309

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

Closed
weiznich opened this issue Nov 27, 2017 · 3 comments
Closed

Rustc fails to resolve trait bounds #46309

weiznich opened this issue Nov 27, 2017 · 3 comments
Labels
C-bug Category: This is a bug.

Comments

@weiznich
Copy link
Contributor

Calling a trait function directly or with UFCS should be interchangeable if no additional type parameters need to be specified.
This code shows a example where this is not the case. As soon as line 76 is comment in the code will fail to compile with this pretty error message.

(The example code needs diesel master as dependency)

@TimNN TimNN added the C-bug Category: This is a bug. label Nov 28, 2017
@sgrif
Copy link
Contributor

sgrif commented Dec 12, 2017

This seems very likely to be related to #34260 to me, but it's extremely surprising that it doesn't overflow when using UFCS.

@Spoonbender
Copy link

Triage: I tried updating the code to modern-day diesel (1.4.8), and it seems to me the issue won't reproduce anymore using rustc 1.59.0 (9d1b2106e 2022-02-23)

@weiznich can you verify?

#[macro_use]
extern crate diesel;


use diesel::*;
use diesel::pg::{PgConnection, Pg};
use diesel::associations::HasTable;
use diesel::query_dsl::LoadQuery;
use diesel::insertable::Insertable;
use diesel::query_builder::InsertStatement;
use diesel::query_builder::UndecoratedInsertRecord;
use diesel::query_source::Table;
use diesel::result::QueryResult;



pub trait GstInsertable<'insert, T, Res, Ret = Res, E = Self> {
    fn insert(&'insert self, conn: &PgConnection) -> QueryResult<Ret>;
}

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

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

#[derive(Insertable)]
#[table_name = "users"]
struct NewUser<'a> {
    name: &'a str,
}

impl<'a, Res> GstInsertable<'a, users::table, Res> for NewUser<'a>
    where Res: Queryable<(diesel::types::Integer, diesel::types::Text), Pg>
{
    fn insert(&'a self, conn: &PgConnection) -> QueryResult<Res> {
        ::diesel::insert_into(users::table)
            .values(self)
            .get_result(conn)
    }
}

impl<'a, C, E, T, Res> GstInsertable<'a, T, Res, Vec<Res>, E> for C
where
    C: AsRef<[E]>,
    E: GstInsertable<'a, T, Res> + 'a + UndecoratedInsertRecord<T>,
    T: Table + HasTable<Table = T>,
    for<'b> InsertStatement<T, <&'b [E] as Insertable<T>>::Values>: LoadQuery<PgConnection, Res>,
    for<'b> &'b [E]: Insertable<T> + UndecoratedInsertRecord<T>,
{
    fn insert(&'a self, conn: &PgConnection) -> QueryResult<Vec<Res>> {
        ::diesel::insert_into(T::table())
            .values(self.as_ref())
            .get_results( conn)
    }
}


fn main() {
    let conn: PgConnection = unimplemented!();
    let new_user = NewUser { name: "jon" };

    let _: User = new_user.insert(&conn).unwrap();
    let users = &vec![new_user];

    // previously wasn't working, but now seems OK
    let _: Vec<User> = users.insert(&conn).unwrap();

    // but this is
    let _: Vec<User> = GstInsertable::insert(users, &conn).unwrap();
}

@weiznich
Copy link
Contributor Author

I can verify that the bug is fixed with a recent rustc version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

4 participants