I've encountered some strange (to me) behavior in dealing with a struct that contains a wrapped property with a default initializer. A contrived main.swift example is below:
protocol DefaultConstructible {
init()
}
extension String: DefaultConstructible {}
@propertyWrapper
struct Wrapper<Value: DefaultConstructible> {
private var value: Value
public var wrappedValue: Value {
return value
}
public init(wrappedValue: Value) {
self.value = wrappedValue
}
//public init() { value = Value() }
}
struct SomeData {
@Wrapper
var data: String
func print() {
Swift.print(data)
}
}
let data = SomeData(data: "data")
data.print()
As pasted above, this compiles and runs just fine, but if I uncomment the //public init() { value = Value() } line above, I get:
main.swift:34:27: error: cannot convert value of type 'String' to expected argument type 'Wrapper<String>'
let data = SomeData(data: "data")
^
The memberwise initialization section of the property wrapper proposal doesn't mention an empty initializer for the the wrapper changing the memberwise initializer back to the wrapper type, but I may be misinterpreting the difference between "initial value" and having an empty initializer.
Can anyone provide any more information or workarounds so I can have both the memberwise initializer on the struct and an empty initializer on the property wrapper?
It does have the same problem with Swift 5.2 on Linux.
Anyhow, the arguments in synthesized initializer needs to be prioritized given that we’re not synthesizing all wrapper/wrapped combinations thereof. What surprises me is that choice changes between minor version. That alone does sound like a bug.
This is interesting, if I compile the code on 5.2 (using swiftenv, if it matters), I get the same behavior as originally reported on 5.2.4, but on 5.1.5 I get a compiler error and stack dump when trying to compile with the init() uncommented (commented out it works just fine):
$ swift build
SIL verification failed: return value type does not match return type of function: functionResultType == instResultType
Verifying instruction:
%1 = apply %0() : $@convention(thin) () -> @owned Wrapper<String> // user: %2
-> return %1 : $Wrapper<String> // id: %2
In function:
// default argument 0 of SomeData.init(data:)
sil [ossa] @$s21StructPropertyWrapper8SomeDataV4dataACSS_tcfcfA_ : $@convention(thin) () -> @owned String {
bb0:
// function_ref variable initialization expression of SomeData._data
%0 = function_ref @$s21StructPropertyWrapper8SomeDataV5_data33_4741C1CC30866EF9503AFFCFBFF2CBB6LLAA0C0VySSGvpfi : $@convention(thin) () -> @owned Wrapper<String> // user: %1
%1 = apply %0() : $@convention(thin) () -> @owned Wrapper<String> // user: %2
return %1 : $Wrapper<String> // id: %2
} // end sil function '$s21StructPropertyWrapper8SomeDataV4dataACSS_tcfcfA_'
Stack dump:
0. Program arguments: /Library/Developer/Toolchains/swift-5.1.5-RELEASE.xctoolchain/usr/bin/swift -frontend -c -primary-file /Users/mplewis/Projects/StructPropertyWrapper/Sources/StructPropertyWrapper/main.swift -emit-module-path /Users/mplewis/Projects/StructPropertyWrapper/.build/x86_64-apple-macosx/debug/StructPropertyWrapper.build/main~partial.swiftmodule -emit-module-doc-path /Users/mplewis/Projects/StructPropertyWrapper/.build/x86_64-apple-macosx/debug/StructPropertyWrapper.build/main~partial.swiftdoc -emit-dependencies-path /Users/mplewis/Projects/StructPropertyWrapper/.build/x86_64-apple-macosx/debug/StructPropertyWrapper.build/main.d -emit-reference-dependencies-path /Users/mplewis/Projects/StructPropertyWrapper/.build/x86_64-apple-macosx/debug/StructPropertyWrapper.build/main.swiftdeps -target x86_64-apple-macosx10.10 -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -I /Users/mplewis/Projects/StructPropertyWrapper/.build/x86_64-apple-macosx/debug -F /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks -enable-testing -g -module-cache-path /Users/mplewis/Projects/StructPropertyWrapper/.build/x86_64-apple-macosx/debug/ModuleCache -swift-version 5 -Onone -D SWIFT_PACKAGE -D DEBUG -color-diagnostics -enable-anonymous-context-mangled-names -module-name StructPropertyWrapper -o /Users/mplewis/Projects/StructPropertyWrapper/.build/x86_64-apple-macosx/debug/StructPropertyWrapper.build/main.swift.o -index-store-path /Users/mplewis/Projects/StructPropertyWrapper/.build/x86_64-apple-macosx/debug/index/store -index-system-modules
1. While silgen emitDefaultArgGenerator SIL function "@$s21StructPropertyWrapper8SomeDataV4dataACSS_tcfcfA_".
for '_data' (at /Users/mplewis/Projects/StructPropertyWrapper/Sources/StructPropertyWrapper/main.swift:26:6)
2. While verifying SIL function "@$s21StructPropertyWrapper8SomeDataV4dataACSS_tcfcfA_".
for '_data' (at /Users/mplewis/Projects/StructPropertyWrapper/Sources/StructPropertyWrapper/main.swift:26:6)
0 swift 0x000000010c27cff5 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 37
1 swift 0x000000010c27c2e5 llvm::sys::RunSignalHandlers() + 85
2 swift 0x000000010c27d5d8 SignalHandler(int) + 264
3 libsystem_platform.dylib 0x00007fff6aecb5fd _sigtramp + 29
4 swift 0x000000010e0c5000 (anonymous namespace)::DarwinX86AsmBackend::getCompactUnwindRegNum(unsigned int) const::CU64BitRegs + 219730
5 libsystem_c.dylib 0x00007fff6ada1808 abort + 120
6 swift 0x000000010924eab8 (anonymous namespace)::SILVerifier::_require(bool, llvm::Twine const&, std::__1::function<void ()> const&) + 616
7 swift 0x0000000109261f00 swift::SILInstructionVisitor<(anonymous namespace)::SILVerifier, void>::visit(swift::SILInstruction*) + 67248
8 swift 0x00000001092505dc (anonymous namespace)::SILVerifier::visitSILBasicBlock(swift::SILBasicBlock*) + 1484
9 swift 0x000000010924b287 swift::SILFunction::verify(bool) const + 7303
10 swift 0x0000000108cff26d swift::Lowering::SILGenModule::postEmitFunction(swift::SILDeclRef, swift::SILFunction*) + 205
11 swift 0x0000000108d07849 swift::Lowering::SILGenModule::emitDefaultArgGenerator(swift::SILDeclRef, swift::ParamDecl*)::$_5::operator()(swift::SILFunction*) const + 217
12 swift 0x0000000108d013d7 swift::Lowering::SILGenModule::emitDefaultArgGenerator(swift::SILDeclRef, swift::ParamDecl*) + 407
13 swift 0x0000000108cff58a swift::Lowering::SILGenModule::emitAbstractFuncDecl(swift::AbstractFunctionDecl*) + 122
14 swift 0x0000000108cff77f swift::Lowering::SILGenModule::emitConstructor(swift::ConstructorDecl*) + 31
15 swift 0x0000000108dd1307 (anonymous namespace)::SILGenType::emitType() + 535
16 swift 0x0000000108dd10e9 swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 25
17 swift 0x0000000108d03cc6 swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*) + 822
18 swift 0x0000000108d04b25 swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*) + 293
19 swift 0x0000000108d05046 swift::performSILGeneration(swift::FileUnit&, swift::SILOptions&) + 38
20 swift 0x0000000108a291f3 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 8291
21 swift 0x0000000108a2626a swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 3002
22 swift 0x00000001089ced18 main + 696
23 libdyld.dylib 0x00007fff6acd2cc9 start + 1
24 libdyld.dylib 0x000000000000002a start + 2503136098
The iOS version might handle things differently, I guess.