I have this: (on Xcode 11.2 11B52)
/// Adds a `didSet` observer which logs the new value of the wrapped property when it changes.
@propertyWrapper
struct LogChanges <ValueType: Equatable> {
var wrappedValue: ValueType {
didSet {
if wrappedValue != oldValue {
print("\(oldValue) → \(wrappedValue)")
}
}
}
}
struct Thingy {
@LogChanges var trackedProperty: Int = 0
}
var thingy = Thingy()
thingy.trackedProperty = 1 // 0 → 1
thingy.trackedProperty = 2 // 1 → 2
thingy.trackedProperty = 3 // 2 → 3
and it works fine, but it's not very helpful when tracking multiple values because there's no way to tell which one is changing!
So I tried to add this to the wrapper:
let name: String
init(wrappedValue: ValueType,
_ callerFile: String = #file,
_ callerFunction: String = #function)
{
self.wrappedValue = wrappedValue
self.name = "\(callerFile) \(callerFunction)"
}
Something like that works with the inits of non-wrapper types, but trying to compile this gives a segmentation fault:
Stack dump:
...
1. While running pass #0 SILModuleTransform "SerializeSILPass".
2. While serializing 'trackedProperty' (at /Users/Me/PropertyWrapperProblem/PropertyWrapperProblem/main.swift:33:8)
0 swift 0x0000000104f4da13 PrintStackTraceSignalHandler(void*) + 51
1 swift 0x0000000104f4d1e6 SignalHandler(int) + 358
2 libsystem_platform.dylib 0x00007fff67263b1d _sigtramp + 29
3 swift 0x0000000101b411aa llvm::Optional<swift::Type> llvm::function_ref<llvm::Optional<swift::Type> (swift::TypeBase*)>::callback_fn<substType(swift::Type, llvm::function_ref<swift::Type (swift::SubstitutableType*)>, llvm::function_ref<llvm::Optional<swift::ProtocolConformanceRef> (swift::CanType, swift::Type, swift::ProtocolDecl*)>, swift::SubstOptions)::$_17>(long, swift::TypeBase*) + 410
4 swift 0x0000000101b04d3d swift::extractInlinableText(swift::SourceManager&, swift::ASTNode, llvm::SmallVectorImpl<char>&) + 461
5 swift 0x0000000101a98796 swift::ParamDecl::getDefaultValueStringRepresentation(llvm::SmallVectorImpl<char>&) const + 1030
6 swift 0x000000010181f98a swift::serialization::Serializer::writeDecl(swift::Decl const*) + 5946
7 swift 0x000000010184542f swift::serialization::Serializer::writeAllDeclsAndTypes() + 62287
8 swift 0x00000001018523f4 swift::serialization::Serializer::writeAST(llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, bool) + 5364
9 swift 0x000000010185f330 swift::serialization::Serializer::writeToStream(llvm::raw_ostream&, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::SILModule const*, swift::SerializationOptions const&) + 6016
10 swift 0x0000000101860c0b bool llvm::function_ref<bool (llvm::raw_pwrite_stream&)>::callback_fn<swift::serialize(llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::SerializationOptions const&, swift::SILModule const*)::$_8>(long, llvm::raw_pwrite_stream&) + 139
11 swift 0x0000000100b67729 swift::withOutputFile(swift::DiagnosticEngine&, llvm::StringRef, llvm::function_ref<bool (llvm::raw_pwrite_stream&)>) + 2569
12 swift 0x0000000101860a67 swift::serialize(llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::SerializationOptions const&, swift::SILModule const*) + 311
13 swift 0x0000000100ba31bb std::__1::__function::__func<performCompileStepsPostSILGen(swift::CompilerInstance&, swift::CompilerInvocation&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> >, bool, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::PrimarySpecificPaths const&, bool, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*)::$_12, std::__1::allocator<performCompileStepsPostSILGen(swift::CompilerInstance&, swift::CompilerInvocation&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> >, bool, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::PrimarySpecificPaths const&, bool, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*)::$_12>, void ()>::operator()() + 603
14 swift 0x000000010134ac61 SerializeSILPass::run() + 49
15 swift 0x0000000101241129 swift::SILPassManager::execute() + 7305
16 swift 0x0000000100e9dc0b swift::CompilerInstance::performSILProcessing(swift::SILModule*, swift::UnifiedStatsReporter*) + 1563
17 swift 0x0000000100b99375 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 33925
18 swift 0x0000000100b8d6e4 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 6820
19 swift 0x0000000100b1abe3 main + 1219
20 libdyld.dylib 0x00007fff670622e5 start + 1
21 libdyld.dylib 0x0000000000000047 start + 2566511971
error: Segmentation fault: 11 (in target 'PropertyWrapperProblem' from project 'PropertyWrapperProblem')
I could manually specify the property name at every usage like @LogChanges(name: "trackedProperty") but that would be inconvenient, ugly and not always accurate.