-
Notifications
You must be signed in to change notification settings - Fork 13k
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
LLVM error: Call parameter type does not match function signature #36744
Comments
stable 1.8.0 is fine, stable 1.9.0 fails |
Nominating as this was a stable-to-stable regression |
On nightly, this was introduced between |
According to git-bisect f3ac509 is the cause. |
First off, this is a more minimal test: struct A<'a> {
a: &'a i32,
}
fn call<T>(s: T, functions: &Vec<fn(&T)>) {
}
fn f(a: &A) { }
fn main() {
let a = A { a: &10 };
let vec: Vec<fn(&A)> = vec![f];
call(a, &vec); // 'x
} In any case, @pnkfelix, I looked into this a bit. I am not sure why this ever worked, but I think I see the problem. It has to do with the subtyping (as opposed to coercion) relationship between bound and free regions. In particular, Now, in Presumably some bug or other made this work before. We probably just want to insert an LLVM cast in such cases though. |
The problem even arises with this slightly further reduced, independently-developed variant of what @nikomatsakis posted: #![allow(dead_code)]
struct A<'l> { _a: &'l i32 }
fn call<'m, T>(_functions: &'m Vec<for <'n> fn(&'n T)>) { }
#[cfg(wont_compile_due_to_type_mismatch)]
fn caller1<'o>(vec: &'o Vec<for <'s> fn(&'s A<'s>)>) { call(vec); }
fn caller2<'t>(vec: &'t Vec<for <'u,'v> fn(&'u A<'v>)>) { call(vec); }
fn main() { } Even here, where we are not passing a value of type
|
It seems to me that fully erasing even bound regions in LLVM types might well be a reasonable thing to do. But that might then lead to duplicate definitions of types, I suppose? For example, these two vector types are distinct types that are both declared, presumably. The only option I see is inserting casts to account for subtyping, which I believe we used to do (I remember hitting this problem before in the distant past). Perhaps this code just got left out of MIR trans? |
We could just erase all bound lifetimes in covariant slots - since these can't matter for layout. |
@arielb1 I'm not sure why you singled out "covariant slots" here (or even what you mean by a "covariant slot", actually). For example, if the type were |
Sure, you have to look at the variance of the binder, not of the lifetime. OTOH, this would make extracting type parameters from NOTE: this can be reached even without calls: pub struct A<'a>(&'a ());
pub struct S<T>(T);
#[no_mangle]
pub fn bad<'s>(v: &mut S<fn(A<'s>)>, y: S<for<'b> fn(A<'b>)>) {
*v = y;
}
fn main() {} This occurs at every place MIR has subtyping. If MIR type-checking is correct, this is function arguments, function return values, and assignments. If we go by that, this bug could be fixed by checking whether the erased Rust types are different at these points and performing the appropriate cast (this could hide bugs, but that's life - maybe add "proper-subtype" annotations to MIR or something). |
Yeah, this is precisely what I was thinking of doing. I agree it can hide bugs, but we can at minimum add some kind of assertions (same size, etc). One other thought I had is that we could probably erase lifetimes fully when generating LLVM types, but we'd have to be aware that distinct Rust types may map to the same LLVM type (but it should have the same runtime representation). We could probably just keep a set of the LLVM types that have been created. IOW, if we have |
@nikomatsakis If I may ruin your dream... those types can be distinct in stable Rust. |
@eddyb I am aware of that, but they can still share the same LLVM representation without a problem, I think? |
@nikomatsakis How would you even determine that automatically without building them first? |
@eddyb hmm, ok, I see your point. Yeah, I was wrong. =) |
I get the error
on this code (which I reduced as much as possible while still getting the error)
This is on Rust 1.11.0, on Linux 64.
The text was updated successfully, but these errors were encountered: