Skip to content
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

ICE(?): LLVM ERROR: Broken module found, compilation aborted! #20544

Closed
tikue opened this issue Jan 4, 2015 · 8 comments
Closed

ICE(?): LLVM ERROR: Broken module found, compilation aborted! #20544

tikue opened this issue Jan 4, 2015 · 8 comments
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@tikue
Copy link
Contributor

tikue commented Jan 4, 2015

Sorry that this example isn't very minimal. I was basically just trying to use the Mul operator (*) as function composition.

#![feature(associated_types)]
#![feature(unboxed_closures)]
#![feature(default_type_params)]

use std::ops::Mul;

struct Fun<F: Fn(T) -> T, T>(F);

impl<F, T> Fn(T) -> T for Fun<F, T>
where 
    F: Fn(T) -> T {

    extern "rust-call" fn call(&self, (t,): (T,)) -> T {
        (self.0)(t)
    }
}

impl<T, F1, F2> Mul<Fun<F2, T>> for Fun<F1, T>
where 
    F1: Fn(T) -> T, 
    F2: Fn(T) -> T {

    type Output = Compose<Fun<F1, T>, Fun<F2, T>, T>;
    fn mul(self, rhs: Fun<F2, T>) -> Compose<Fun<F1, T>, Fun<F2, T>, T> {
        Compose{f1: self, f2: rhs}
    }
}


struct Compose<F1, F2, T> where F1: Fn(T) -> T, F2: Fn(T) -> T {
    f1: F1,
    f2: F2
}

impl<T, F1, F2> Fn(T) -> T for Compose<F1, F2, T> 
where
    F1: Fn(T) -> T,
    F2: Fn(T) -> T {

    extern "rust-call" fn call(&self, (t,): (T,)) -> T {
        (self.f1)((self.f2)(t))
    }
}

fn main() {
    let f1 = Fun(|i: int| i * 2);
    let f2 = Fun(|i: int| i - 1);
    let f3 = f1 * f2;
    println!("{}", f3(3));
}

The error when compiling:

Global is external, but doesn't have external or weak linkage!
i64 (%closure*, i64)* @_ZN4main20unboxed_closure.1371E
invalid linkage type for function declaration
i64 (%closure*, i64)* @_ZN4main20unboxed_closure.1371E
Global is external, but doesn't have external or weak linkage!
i64 (%closure.1*, i64)* @_ZN4main20unboxed_closure.1373E
invalid linkage type for function declaration
i64 (%closure.1*, i64)* @_ZN4main20unboxed_closure.1373E
LLVM ERROR: Broken module found, compilation aborted!
@kmcallister kmcallister added I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. labels Jan 4, 2015
@pfalabella
Copy link
Contributor

probably a dup of #20174

@pfalabella
Copy link
Contributor

@tikue as a workaround, your code works if you change Fun from a newtype to a struct with a named field, like this: struct Fun<F: Fn(T) -> T, T> {f: F}

@tikue
Copy link
Contributor Author

tikue commented Jan 5, 2015

Thank you @pfalabella!

@yann-ledu
Copy link

That last struct abstraction does not work anymore : how can we express it now ?

@Stebalien
Copy link
Contributor

Here is a working version.

#![feature(unboxed_closures)]
#![feature(core)]

use std::ops::Mul;

struct Fun<F: Fn(T) -> T, T>(F, std::marker::PhantomData<T>);

impl<F, T> FnOnce<(T,)> for Fun<F, T> where F: Fn(T) -> T {
    type Output = T;

    extern "rust-call" fn call_once(self, args: (T,)) -> T {
        self.call(args)
    }
}

impl<F, T> FnMut<(T,)> for Fun<F, T> where F: Fn(T) -> T {
    extern "rust-call" fn call_mut(&mut self, args: (T,)) -> T {
        self.call(args)
    }
}

impl<F, T> Fn<(T,)> for Fun<F, T> where F: Fn(T) -> T {
    extern "rust-call" fn call(&self, (t,): (T,)) -> T {
        (self.0)(t)
    }
}

impl<T, F1, F2> Mul<Fun<F2, T>> for Fun<F1, T>
where 
    F1: Fn(T) -> T, 
    F2: Fn(T) -> T {

    type Output = Compose<Fun<F1, T>, Fun<F2, T>, T>;
    fn mul(self, rhs: Fun<F2, T>) -> Compose<Fun<F1, T>, Fun<F2, T>, T> {
        Compose{f1: self, f2: rhs, _ph: std::marker::PhantomData}
    }
}


struct Compose<F1, F2, T> where F1: Fn(T) -> T, F2: Fn(T) -> T {
    f1: F1,
    f2: F2,
    _ph: std::marker::PhantomData<T>,
}


impl<T, F1, F2> FnOnce<(T,)> for Compose<F1, F2, T> where F1: Fn(T) -> T, F2: Fn(T) -> T {
    type Output = T;

    extern "rust-call" fn call_once(self, args: (T,)) -> T {
        self.call(args)
    }
}

impl<T, F1, F2> FnMut<(T,)> for Compose<F1, F2, T> where F1: Fn(T) -> T, F2: Fn(T) -> T {

    extern "rust-call" fn call_mut(&mut self, args: (T,)) -> T {
        self.call(args)
    }
}

impl<T, F1, F2> Fn<(T,)> for Compose<F1, F2, T> where F1: Fn(T) -> T, F2: Fn(T) -> T {

    extern "rust-call" fn call(&self, (t,): (T,)) -> T {
        (self.f1)((self.f2)(t))
    }
}

fn main() {
    let f1 = Fun(|i: isize| i * 2, std::marker::PhantomData::<isize>);
    let f2 = Fun(|i: isize| i - 1, std::marker::PhantomData::<isize>);
    let f3 = f1 * f2;
    println!("{}", f3(3));
}

@Stebalien
Copy link
Contributor

And a minimal example:

#![feature(unboxed_closures)]
#![feature(core)]

struct Fun<F>(F);

impl<F, T> FnOnce<(T,)> for Fun<F> where F: Fn(T) -> T {
    type Output = T;

    extern "rust-call" fn call_once(self, (t,): (T,)) -> T {
        (self.0)(t)
    }
}

fn main() {
    let fun = Fun(|i: isize| i * 2);
    println!("{}", fun(3));
}

@pmarcelll
Copy link
Contributor

@Stebalien both examples compile and run on my machine with the latest nightly.

@Stebalien
Copy link
Contributor

@pmarcelll yes they do. This can probably be closed.

@arielb1 arielb1 added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label Jul 8, 2015
@bors bors closed this as completed in 00f7268 Jul 17, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
Development

No branches or pull requests

7 participants