Sophie McCarrell
Sophie McCarrell

Reputation: 2871

does swift not allow initialization in function parameters?

This first block generates a generic Swift Compile Error (doesn't even point to the line)

let screenDivision = size.width / 5;
var game1 = SKSpriteNode(color: .redColor(), size: CGSize(width: 2 * screenDivision, height: size.height));

This second block works fine.

let screenDivision = size.width / 5;
var a = CGSize(width: 2 * screenDivision, height: size.height)
var game1 = SKSpriteNode(color: .redColor(), size: a);

Why? I'd hate to run into this error again and not remember where I wrote such code.

(I also need to pass it a variable, not a constant? Wtf... [if I change var a, to let a, I get the compile error])

Upvotes: 2

Views: 305

Answers (2)

rintaro
rintaro

Reputation: 51911

It seems, it's a compiler bug.

In this case, "Implicit Member Expression" should be performed.

An implicit member expression is an abbreviated way to access a member of a type, such as an enumeration case or a class method, in a context where type inference can determine the implied type. It has the following form:

.member name

I reproduced exact the same problem with this code:

class MyClass {
    class func create() -> MyClass { return MyClass() }
}

func f(arg:MyClass!, arg2:Int) { } 

f(.create(), 1)

/*
Bitcast requires both operands to be pointer or neither
  %.asUnsubstituted = bitcast %C4test7MyClass* %6 to i64
LLVM ERROR: Broken function found, compilation aborted!
*/

or even with enum:

enum MyEnum {
    case Case1
}

func f(arg:MyEnum!, arg2:Int) { } 

f(.Case1, 1)

/*
0  swift                    0x00000001062d8a68 llvm::sys::PrintStackTrace(__sFILE*) + 40
1  swift                    0x00000001062d8f54 SignalHandler(int) + 452
2  libsystem_platform.dylib 0x00007fff8a314f1a _sigtramp + 26
3  libsystem_platform.dylib 0x00007fd8085362e8 _sigtramp + 2116162536
4  swift                    0x00000001056e8e98 emitApplyArgument((anonymous namespace)::IRGenSILFunction&, swift::SILValue, swift::SILParameterInfo, llvm::ArrayRef<swift::Substitution>, swift::irgen::Explosion&) + 456
5  swift                    0x00000001056e5f1d swift::SILVisitor<(anonymous namespace)::IRGenSILFunction, void>::visit(swift::ValueBase*) + 34605
6  swift                    0x00000001056dcbab swift::irgen::IRGenModule::emitSILFunction(swift::SILFunction*) + 9179
7  swift                    0x0000000105656347 swift::irgen::IRGenModule::emitLazyDefinitions() + 199
8  swift                    0x00000001056c9966 performIRGeneration(swift::IRGenOptions&, swift::Module*, swift::SILModule*, llvm::StringRef, llvm::LLVMContext&, swift::SourceFile*, unsigned int) + 2038
9  swift                    0x00000001056ca2e3 swift::performIRGeneration(swift::IRGenOptions&, swift::SourceFile&, swift::SILModule*, llvm::StringRef, llvm::LLVMContext&, unsigned int) + 51
10 swift                    0x000000010561f5f4 frontend_main(llvm::ArrayRef<char const*>, char const*, void*) + 5444
11 swift                    0x000000010561c96d main + 1677
12 libdyld.dylib            0x00007fff90b525c9 start + 1
13 libdyld.dylib            0x0000000000000010 start + 1867176520
Stack dump:
0.  Program arguments: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -c -primary-file test.swift -target x86_64-apple-darwin14.0.0 -target-cpu core2 -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk -color-diagnostics -module-name test -o /var/folders/kb/xgglxb597sv6h8b744d5vft00000gn/T/test-4cf5cc.o 
1.  While emitting IR SIL function @top_level_code<unknown>:0: error: unable to execute command: Segmentation fault: 11
<unknown>:0: error: swift frontend command failed due to signal (use -v to see invocation)
*/

Both cases, removing ! from the function parameter solves the problem.

Let's say: "DO NOT USE implicit member expression for implicitly unwrapped optional context"

Upvotes: 4

drewag
drewag

Reputation: 94703

The error goes away if you include UIColor in your call to redColor:

let screenDivision = size.width / 5;
var game1 = SKSpriteNode(
    color: UIColor.redColor(),
    size: CGSize(width: 2 * screenDivision,
    height: size.height)
)

I am not aware of the ability to leave out type names for class methods. I am only aware of that being possible with Enumeration cases. The Swift programming guide mentions specifically that this is possible with enumerations but says nothing in the type method section.

I am actually surprised that the second version works. For now, I would always include the type name unless you are referring to an enumeration case.

Upvotes: 4

Related Questions