sure, i’m probably holding them wrong, noncopyable types are just… not fun.
here’s a noncopyable struct:
@frozen public
struct DiagnosticContext<Symbolicator>:~Copyable
{
@usableFromInline internal
var diagnostics:[Diagnostic]
}
and then here’s an intermediate abstraction that contains a stored property of that noncopyable struct:
import Diagnostics
extension StaticLinker
{
struct Tables:~Copyable
{
var diagnostics:DiagnosticContext<StaticSymbolicator>
...
}
}
and now here’s a toplevel type that contains the intermediate type
struct StaticLinker:~Copyable
{
private
var tables:Tables
....
}
now i’m trying to do
extension StaticLinker
{
consuming
func diagnostics() -> DiagnosticContext<StaticSymbolicator>
{
self.tables.diagnostics
}
}
but that doesn’t work
error: cannot partially consume 'self'
nor does
(consume self).tables.diagnostics
error: cannot partially consume 'unknown'
this doesn’t parse
(consume (consume self).tables).diagnostics
this crashes the compiler
var diagnostics:DiagnosticContext<StaticSymbolicator>
{
_read
{
yield self.tables.diagnostics
}
}
COW-proofing is a lot harder than i thought…
Joe_Groff
(Joe Groff)
November 10, 2023, 2:56am
2
Partial consumption is coming but the read coroutine is probably closer to what you want. That ought to work, I'll look into a fix.
1 Like
oof, just ran into a compiler segfault when building in release mode only. details here:
opened 03:31AM - 10 Nov 23 UTC
bug
triage needed
this [commit](https://github.com/tayloraswift/swift-unidoc/pull/63/commits/5cb4f… 8caba26539d9394187abb26aae1467a5da9) of swift-unidoc crashes the compiler with a segfault.
[CI run](https://github.com/tayloraswift/swift-unidoc/actions/runs/6820384093/job/18549187675)
```
error: compile command failed due to signal 11 (use -v to see invocation)
Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the crash backtrace.
Stack dump:
0. Program arguments: /usr/bin/swift-frontend -frontend -c /swift/swift-unidoc/Sources/UnidocDiagnostics/Contexts/Demangler.swift /swift/swift-unidoc/Sources/UnidocDiagnostics/Contexts/DiagnosticContext.Group.swift /swift/swift-unidoc/Sources/UnidocDiagnostics/Contexts/DiagnosticContext.swift /swift/swift-unidoc/Sources/UnidocDiagnostics/Contexts/DiagnosticSubject.swift /swift/swift-unidoc/Sources/UnidocDiagnostics/Contexts/DiagnosticSymbolicator.swift /swift/swift-unidoc/Sources/UnidocDiagnostics/Diagnostic.swift /swift/swift-unidoc/Sources/UnidocDiagnostics/DiagnosticNote.swift /swift/swift-unidoc/Sources/UnidocDiagnostics/InvalidAutolinkError.swift /swift/swift-unidoc/Sources/UnidocDiagnostics/InvalidCodelinkError.Note.swift /swift/swift-unidoc/Sources/UnidocDiagnostics/InvalidCodelinkError.swift /swift/swift-unidoc/Sources/UnidocDiagnostics/Messages/DiagnosticMessage.Severity.swift /swift/swift-unidoc/Sources/UnidocDiagnostics/Messages/DiagnosticMessage.swift /swift/swift-unidoc/Sources/UnidocDiagnostics/Messages/DiagnosticOutput.swift /swift/swift-unidoc/Sources/UnidocDiagnostics/Messages/SourceContext.Line.swift /swift/swift-unidoc/Sources/UnidocDiagnostics/Messages/SourceContext.swift /swift/swift-unidoc/Sources/UnidocDiagnostics/Messages/TerminalColor.swift /swift/swift-unidoc/Sources/UnidocDiagnostics/Messages/TerminalColors.swift -supplementary-output-file-map /tmp/TemporaryDirectory.L4JLMr/supplementaryOutputs-1 -target x86_64-unknown-linux-gnu -disable-objc-interop -I /swift/swift-unidoc/.build/x86_64-unknown-linux-gnu/release -color-diagnostics -g -module-cache-path /swift/swift-unidoc/.build/x86_64-unknown-linux-gnu/release/ModuleCache -swift-version 5 -O -D SWIFT_PACKAGE -new-driver-path /usr/bin/swift-driver -enable-experimental-feature StrictConcurrency -enable-upcoming-feature BareSlashRegexLiterals -enable-upcoming-feature ConciseMagicFile -enable-upcoming-feature ExistentialAny -empty-abi-descriptor -resource-dir /usr/lib/swift -Xcc -fPIC -module-name UnidocDiagnostics -package-name swift_unidoc -plugin-path /usr/lib/swift/host/plugins -plugin-path /usr/local/lib/swift/host/plugins -enable-default-cmo -parse-as-library -num-threads 12 -o /swift/swift-unidoc/.build/x86_64-unknown-linux-gnu/release/UnidocDiagnostics.build/Contexts/Demangler.swift.o -o /swift/swift-unidoc/.build/x86_64-unknown-linux-gnu/release/UnidocDiagnostics.build/Contexts/DiagnosticContext.Group.swift.o -o /swift/swift-unidoc/.build/x86_64-unknown-linux-gnu/release/UnidocDiagnostics.build/Contexts/DiagnosticContext.swift.o -o /swift/swift-unidoc/.build/x86_64-unknown-linux-gnu/release/UnidocDiagnostics.build/Contexts/DiagnosticSubject.swift.o -o /swift/swift-unidoc/.build/x86_64-unknown-linux-gnu/release/UnidocDiagnostics.build/Contexts/DiagnosticSymbolicator.swift.o -o /swift/swift-unidoc/.build/x86_64-unknown-linux-gnu/release/UnidocDiagnostics.build/Diagnostic.swift.o -o /swift/swift-unidoc/.build/x86_64-unknown-linux-gnu/release/UnidocDiagnostics.build/DiagnosticNote.swift.o -o /swift/swift-unidoc/.build/x86_64-unknown-linux-gnu/release/UnidocDiagnostics.build/InvalidAutolinkError.swift.o -o /swift/swift-unidoc/.build/x86_64-unknown-linux-gnu/release/UnidocDiagnostics.build/InvalidCodelinkError.Note.swift.o -o /swift/swift-unidoc/.build/x86_64-unknown-linux-gnu/release/UnidocDiagnostics.build/InvalidCodelinkError.swift.o -o /swift/swift-unidoc/.build/x86_64-unknown-linux-gnu/release/UnidocDiagnostics.build/Messages/DiagnosticMessage.Severity.swift.o -o /swift/swift-unidoc/.build/x86_64-unknown-linux-gnu/release/UnidocDiagnostics.build/Messages/DiagnosticMessage.swift.o -o /swift/swift-unidoc/.build/x86_64-unknown-linux-gnu/release/UnidocDiagnostics.build/Messages/DiagnosticOutput.swift.o -o /swift/swift-unidoc/.build/x86_64-unknown-linux-gnu/release/UnidocDiagnostics.build/Messages/SourceContext.Line.swift.o -o /swift/swift-unidoc/.build/x86_64-unknown-linux-gnu/release/UnidocDiagnostics.build/Messages/SourceContext.swift.o -o /swift/swift-unidoc/.build/x86_64-unknown-linux-gnu/release/UnidocDiagnostics.build/Messages/TerminalColor.swift.o -o /swift/swift-unidoc/.build/x86_64-unknown-linux-gnu/release/UnidocDiagnostics.build/Messages/TerminalColors.swift.o
1. Swift version 5.9.1 (swift-5.9.1-RELEASE)
2. Compiling with the current language version
3. While evaluating request ExecuteSILPipelineRequest(Run pipelines { PrepareOptimizationPasses, EarlyModulePasses, HighLevel,Function+EarlyLoopOpt, HighLevel,Module+StackPromote, MidLevel,Function, ClosureSpecialize, LowLevel,Function, LateLoopOpt, SIL Debug Info Generator } on SIL for UnidocDiagnostics)
4. While running pass #509 SILFunctionTransform "ComputeSideEffects" on SILFunction "@$s17UnidocDiagnostics22DiagnosticSymbolicatorPAAE11symbolicateySayAA0C7MessageOGAA0C7ContextVyxGnF".
for 'symbolicate(_:)' (at /swift/swift-unidoc/Sources/UnidocDiagnostics/Contexts/DiagnosticSymbolicator.swift:40:5)
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
/usr/bin/swift-frontend(+0x6023253)[0x55a04a9cc253]
/usr/bin/swift-frontend(+0x602117e)[0x55a04a9ca17e]
/usr/bin/swift-frontend(+0x60235cf)[0x55a04a9cc5cf]
/lib64/libpthread.so.0(+0x118e0)[0x7f971b3f98e0]
/usr/bin/swift-frontend(+0x19b5592)[0x55a04635e592]
*** Program crashed: Bad pointer dereference at 0x00007ffcc879aff8 ***
Thread 0 "swift-frontend" crashed:
0 0x000055a04635e592 swift::SILInstruction::mayRelease() const + 2 in swift-frontend
Registers:
rax 0x00000000000000c4 196
rdx 0x000055a04e02b2b0 40 b2 02 4e a0 55 00 00 40 b3 02 4e a0 55 00 00 @²·N U··@³·N U··
rcx 0x000055a04635e67e 66 90 8a 47 38 3c d3 74 08 3c 4b 74 04 3c 4d 75 f··G8<Ót·<Kt·<Mu
rbx 0x000055a04bf61f24 28 c7 3f fa 28 c7 3f fa 5a c7 3f fa 5a c7 3f fa (Ç?ú(Ç?úZÇ?úZÇ?ú
rsi 0x000055a04e02b2b0 40 b2 02 4e a0 55 00 00 40 b3 02 4e a0 55 00 00 @²·N U··@³·N U··
rdi 0x0000000000000000 0
rbp 0x000055a04e02b2b0 40 b2 02 4e a0 55 00 00 40 b3 02 4e a0 55 00 00 @²·N U··@³·N U··
rsp 0x00007ffcc879b000 d8 b2 02 4e a0 55 00 00 00 00 00 00 00 00 00 00 ز·N U··········
r8 0x0000000000000000 0
r9 0x000055a04cf29230 00 00 00 00 00 00 00 00 48 90 f2 4c a0 55 00 00 ········H·òL U··
r10 0x000055a04e16f028 48 e8 1c 1b 97 7f 00 00 38 9f 0e 1b 97 7f 00 00 Hè······8·······
r11 0x000055a04d0be0a0 0a 00 23 00 2a 02 d3 00 69 02 8b 02 95 02 45 00 ··#·*·Ó·i·····E·
r12 0x0000010101010101 1103823438081
r13 0x0000000000000000 0
r14 0x000055a04e02b2d8 30 92 f2 4c a0 55 00 00 ff ff ff ff 03 00 00 00 0·òL U··ÿÿÿÿ····
r15 0x00007ffcc8f92d90 68 b2 02 4e a0 55 00 00 00 f0 ff ff ff ff ff ff h²·N U···ðÿÿÿÿÿÿ
rip 0x000055a04635e592 53 50 48 89 fb 8a 47 38 8d 48 66 80 f9 30 77 13 SPH·û·G8·Hf·ù0w·
rflags 0x0000000000010a16 AF PF
cs 0x0033 fs 0x0000 gs 0x0000
Images (33 omitted):
0x000055a0449a9000–0x000055a04b5528c0 <no build ID> swift-frontend /usr/bin/swift-frontend
[153/624] Compiling tls13_client.cc
```
debug builds don’t seem to be affected.
```
$ swift --version
Swift version 5.9.1 (swift-5.9.1-RELEASE)
Target: x86_64-unknown-linux-gnu
```
argh! i’m running into this again, except this time i actually do need to partially consume the field.
i have a type Table
and a second type TableWrapper
:
struct Table:~Copyable {}
struct TableWrapper:~Copyable
{
var table:Table
}
i can create the TableWrapper
by transferring to it an instance of Table
, but i am totally stumped as to how to get the Table
back out of the TableWrapper
when i am done with it. surely there is something obvious i am missing?
Can't you add a consuming get function to the wrapper?
no, the access in the body of the getter is still considered a partial consumption
Alejandro
(Alejandro Alonso)
June 6, 2024, 9:37pm
7
struct Table: ~Copyable {}
struct TableWrapper: ~Copyable {
var table: Table
consuming func intoTable() -> Table {
table
}
}
this works fine using the latest nightly
Just to make sure I'm understanding properly, this does not compile?
struct TableWrapper: ~Copyable {
var table: Table
consuming func get() -> Table {
return table
}
}
var table = Table()
let wrapper = TableWrapper(table: table)
// Do stuff with wrapper
table = wrapper.get()
no it does not , which is why @Alejandro was careful to specify latest nightly where it does compile.
Swift version 5.10 (swift-5.10-RELEASE)
Target: x86_64-unknown-linux-gnu
<stdin>:5:16: error: cannot partially consume 'self'
return table
^
1 Like
Joe_Groff
(Joe Groff)
June 6, 2024, 10:04pm
10
This should just work now in Swift 6.0 nightlies. In earlier versions, the best you could do is swap in a dummy value to replace the one you want to get out, like:
struct Table:~Copyable {
init(dummy: ()) {}
mutating func swapWithDummy() -> Table {
let value = self
self = .init(dummy: ())
return value
}
}
struct TableWrapper:~Copyable
{
var table:Table
mutating func takeTable() -> Table {
return self.table.swapWithDummy()
}
}
2 Likes
that works! i had forgotten that mutating
also lets you temporarily consume noncopyable self
…