Open narimiran opened 3 years ago
Reduced example program:
type
RstGenerator* = object of RootObj
splitAfter*: int # split too long entries in the TOC
listingCounter*: int
hasToc*: bool
theIndex: string # Contents of the index file to be dumped at the end.
outDir*: string ## output directory, initialized by docgen.nim
destFile*: string ## output (HTML) file, initialized by docgen.nim
filename*: string ## source Nim or Rst file
currentSection: string
id*: int ## A counter useful for generating IDs.
onTestSnippet*: proc (d: var RstGenerator; filename, cmd: string; status: int;
content: string)
TDocumentor = object of RstGenerator
modDesc: string # module description
modDeprecationMsg: string
PDoc = ref TDocumentor
proc newDocumentor*(): PDoc =
new(result)
result.onTestSnippet =
proc (gen: var RstGenerator; filename, cmd: string; status: int; content: string) =
inc(gen.id)
var d = TDocumentor(gen)
proc call(result: PDoc) =
result.onTestSnippet(result[], "filename", "cmd", 990, "content")
var d = newDocumentor()
d.call
Well ... ARC is correct, the docgen does some invalid object slicing here as TDocumentor
is a value type. We need to fix our docgen.
I think the issue is that we don't copy over the RTTI in =copy
:
type
RstGenerator = object of RootObj
filename: string
TDocumentor = object of RstGenerator
proc test(gen: var RstGenerator) =
gen.filename.add "he"
echo gen of TDocumentor
var d = TDocumentor(gen)
when false:
# Raises ObjectConversionDefect both on arc and refc
var r = RstGenerator()
test(r)
else:
# # Raises ObjectConversionDefect only on arc
var r = TDocumentor()
test(r)
This one shows the RTTI getting lost:
type
RstGenerator = object of RootObj
filename: string
TDocumentor = object of RstGenerator
proc test2(r: var RstGenerator) =
# With cursorinference:off shows that assignment did not copy the RTTI
echo r of TDocumentor
var a = r
var b = r
echo a of TDocumentor
var r = TDocumentor()
test2(r)
(needs to be compiled with --gc:arc --cursorinference:off
)
EDIT: Hmm, nevermind, I don't think this can work with value types :D
reduced "reduced example":
type
A* = object of RootObj
x*: int
f*: proc (a: var A)
B = object of A
proc newB*(): ref B =
new(result)
result.f =
proc (a: var A) =
inc(a.x)
var b = B(a)
var b = newB()
b.f(b[])
I did not understand what's wrong with object slicing here. B
is allocated on heap and var
is passed by reference. So why is it incorrect to do var b = B(a)
?
@a-mr your analysis is correct and mine was incorrect. But ARC currently constructs B(a)
from a copy of a
(which is of type A
) and fixing this looked very hard esp considering the fringe case -- inheritance is almost always done with ref object
instead. But ok, re-opening.
To reproduce this, you need to bootstrap using ARC:
koch boot --gc:arc
.Example
Save the example as
.rst
file, and run:nim rst2html thisfile.rst
Current Output
Expected Output
The same
.html
as when there is no:test: "nim c --gc:arc $1"
line. (Without that line, the example is successful)Additional Information
Devel version of Nim bootstrapped using ARC (
koch boot --gc:arc
).cc @Clyybber