2024-05-04 07:26:24 -05:00
|
|
|
//@ revisions: current next
|
|
|
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
|
|
|
//@[next] compile-flags: -Znext-solver
|
|
|
|
|
|
|
|
#![feature(do_not_recommend)]
|
|
|
|
|
|
|
|
pub trait Expression {
|
|
|
|
type SqlType;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait AsExpression<ST> {
|
|
|
|
type Expression: Expression<SqlType = ST>;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Text;
|
|
|
|
pub struct Integer;
|
|
|
|
|
|
|
|
pub struct Bound<T>(T);
|
|
|
|
pub struct SelectInt;
|
|
|
|
|
|
|
|
impl Expression for SelectInt {
|
|
|
|
type SqlType = Integer;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Expression for Bound<T> {
|
|
|
|
type SqlType = T;
|
|
|
|
}
|
|
|
|
|
2024-05-10 07:12:30 -05:00
|
|
|
#[diagnostic::do_not_recommend]
|
2024-05-04 07:26:24 -05:00
|
|
|
impl<T, ST> AsExpression<ST> for T
|
|
|
|
where
|
|
|
|
T: Expression<SqlType = ST>,
|
|
|
|
{
|
|
|
|
type Expression = T;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AsExpression<Integer> for i32 {
|
|
|
|
type Expression = Bound<Integer>;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AsExpression<Text> for &'_ str {
|
|
|
|
type Expression = Bound<Text>;
|
|
|
|
}
|
|
|
|
|
|
|
|
trait Foo: Expression + Sized {
|
|
|
|
fn check<T>(&self, _: T) -> <T as AsExpression<<Self as Expression>::SqlType>>::Expression
|
|
|
|
where
|
|
|
|
T: AsExpression<Self::SqlType>,
|
|
|
|
{
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Foo for T where T: Expression {}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
SelectInt.check("bar");
|
2024-05-21 14:56:53 -05:00
|
|
|
//~^ ERROR the trait bound `&str: AsExpression<Integer>` is not satisfied
|
|
|
|
//[next]~| the trait bound `&str: AsExpression<<SelectInt as Expression>::SqlType>` is not satisfied
|
|
|
|
//[next]~| type mismatch
|
2024-05-04 07:26:24 -05:00
|
|
|
}
|