Fan compilation with Generics

As an academic test I wrote a generic function to (relatively) chk if a type is a Data Type or a Ref Type.
Appart from the fact the method the function uses is discutable I encounter a Fan event when it turns to test Struct or Class.

If I remove struct & class tests it compiles very fast. If I compile with only struct or class it's very slow. If I compile all it takes minutes and the Fan races.

I tried the same on other main languages (not C#) I didn't meet such situation.

class Pointer<T>{
    var pointee: T
    init(for pointee: T) { self.pointee = pointee }
}
func chk<T>(_ typeName: String, _ v1: T, _ v2: T? = nil, _ copy: ((Pointer<T>,  T)->Void)? = nil, _ equal: @escaping (Pointer<T>, Pointer<T>)->Bool) {
    // check 1
    let t1 = Pointer(for: v1)
    let t2 = Pointer(for: v1)
    if let v2 = v2, let copy = copy { copy(t1,v2) }
    let result = equal(t1,t2) ? "Ref Type " : "Data Type"
    print( "\(typeName): \(result)" )
}

chk("Int     ", 1, 2) { t, v in t.pointee += v } _: { t1, t2 in t1.pointee == t2.pointee }

chk("String  ", "A", "B") { t, v in t.pointee += v } _: { t1, t2 in t1.pointee == t2.pointee }

chk("Tuple   ", (1,2), (2,3)) { t, v in t.pointee.0 = v.0; t.pointee.1 = v.1 } _: { t1, t2 in t1.pointee == t2.pointee }

chk("Set     ", Set([1]), Set([2])) { (t: Pointer<Set<Int>>, v: Set<Int>) in
    t.pointee.removeAll() ; t.pointee.insert(Array(v)[0]) } _: { t1, t2 in t1.pointee == t2.pointee }

chk("Closure ", closure(1)) { t1, t2 in t1.pointee() + 1 == t2.pointee() }

chk("MetaType", Int.self, String.self) { t, v in t.pointee = v } _: { t1, t2 in t1.pointee == t2.pointee }

struct Strukt { var v1: Int; var v2: Int }
chk("Struct  ", Strukt(v1:1,v2:2), Strukt(v1:2,v2:3)) { t, v in t.pointee.v1 = v.v1; t.pointee.v2 = v.v2 } _: { t1, t2 in t1.pointee.v1 == t2.pointee.v1 && t1.pointee.v2 == t2.pointee.v2 }

class Klass { var v1: Int; var v2: Int; init( v1: Int, v2: Int) { self.v1 = v1; self.v2 = v2 } }
chk("Class   ", Klass(v1:1,v2:2), Klass(v1:2,v2:3)) { t, v in t.pointee.v1 = v.v1; t.pointee.v2 = v.v2 } _: { t1, t2 in t1.pointee.v1 == t2.pointee.v1 && t1.pointee.v2 == t2.pointee.v2 }

Nobody has an idea of where can come from this strange behavior?

What is closure here?

I’m not sure, but my guess is that your high compilation times are being caused by type inference. This article should be helpful (particularly the “Add type annotations” and “Alternatively: make small changes to your code” sections).

    let closure = { (start: Int) -> ()->Int in
        var value = start;
        return { value += 1; return value }
    }

Thanks for the tip. I gonna try to add type annotation to see if it solves the compilation time.

As soon as I have put Type Annotation on Struct and Class the problem stopped.

Thanks

2 Likes