-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Confusing output for signature mismatch in Fn trait with GAT lifetime parameter #93342
Comments
... and the interesting thing is that, once I used a trait to "prove" (which is exactly the technique I used in https://github.com/skyzh/type-exercise-in-rust when I was implementing expression vectorization in safe, nightly Rust without any macro) #![feature(generic_associated_types)]
use std::marker::PhantomData;
pub trait Scalar: 'static {
type RefType<'a>: ScalarRef<'a>;
}
pub trait ScalarRef<'a>: 'a {}
impl Scalar for i32 {
type RefType<'a> = i32;
}
impl Scalar for String {
type RefType<'a> = &'a str;
}
impl Scalar for bool {
type RefType<'a> = i32;
}
impl<'a> ScalarRef<'a> for bool {}
impl<'a> ScalarRef<'a> for i32 {}
impl<'a> ScalarRef<'a> for &'a str {}
fn str_contains(a: &str, b: &str) -> bool {
a.contains(b)
}
pub struct BinaryExpression<A: Scalar, B: Scalar, O: Scalar, F>
where
// We don't use `Fn` trait here. Instead, we use a bridge trait called `BinaryExprFunc`
F: BinaryExprFunc<A, B, O>,
{
f: F,
_phantom: PhantomData<(A, B, O)>,
}
impl<A: Scalar, B: Scalar, O: Scalar, F> BinaryExpression<A, B, O, F>
where
F: BinaryExprFunc<A, B, O>,
{
pub fn new(f: F) -> Self {
Self {
f,
_phantom: PhantomData,
}
}
}
pub trait BinaryExprFunc<A: Scalar, B: Scalar, O: Scalar> {
fn eval(&self, a: A::RefType<'_>, b: B::RefType<'_>) -> O;
}
// We prove that `str_contains` is `Fn(A::RefType<'_>, B::RefType<'_>) -> O` by implementing `BinaryExprFunc`
impl<A: Scalar, B: Scalar, O: Scalar, F> BinaryExprFunc<A, B, O> for F
where
F: Fn(A::RefType<'_>, B::RefType<'_>) -> O,
{
fn eval(&self, a: A::RefType<'_>, b: B::RefType<'_>) -> O {
self(a, b)
}
}
fn success_case_1() {
BinaryExpression::<String, String, bool, _>::new(str_contains);
}
fn success_case_2() {
BinaryExpression::<String, String, bool, _> {
f: str_contains,
_phantom: PhantomData,
};
}
fn main() {
println!("Hello, world!");
}
|
I'd like to take a look at this. @rustbot claim |
I think this was fixed in #90887, but needs to be confirmed. |
Thanks a lot! I'll have a try on the latest nightly. |
@jackh726, I manually checked this compiles on master. |
I tried this code:
I expected to see this happen:
Both functions compile.
Instead, this happened:
If I directly call
new
,... but if I manually construct the struct, it succeeds.
Meta
rustc --version --verbose
:Thanks for investigating!
The text was updated successfully, but these errors were encountered: