Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid dynamic type after slicing sink assignment #24730

Open
arnetheduck opened this issue Feb 26, 2025 · 4 comments
Open

Invalid dynamic type after slicing sink assignment #24730

arnetheduck opened this issue Feb 26, 2025 · 4 comments

Comments

@arnetheduck
Copy link
Contributor

arnetheduck commented Feb 26, 2025

Description

type A {.inheritable.} = object
type B = object of A

type C = object
  a: A

var c: C

proc f(v: sink A) =
  var a: A = move(v)
  echo a of B
  c.a = move(a)
  echo c.a of B

f(B())

Nim Version

2.2.0

Current Output

true
true

Expected Output

false
false

Known Workarounds

No response

Additional Information

No response

@ringabout
Copy link
Member

See also #7002;

refc gives ObjectAssignmentDefect for now

@arnetheduck
Copy link
Contributor Author

One tricky bit is the following:

proc f(v: sink A) =
  echo v of B

f(B())

what should this print? ie when exactly does the slicing happen?

@forchid
Copy link

forchid commented Feb 26, 2025

The memory is out of order.

type A {.inheritable.} = object
type B = object of A
    value: int

type C = object
  a: A
  
method print(a: A) {.base.} =
    echo "A: no value"
    
method print(b: B) =
    echo "B: value ", b.value

var c: C

proc f(v: sink A) =
  v.print
  var a: A = move(v)
  a.print
  echo a of B
  c.a = move(a)
  c.a.print
  echo c.a of B
  
proc f1(v: sink A) =
  v.print
  echo v of B
  
proc f2(v: A) =
  v.print
  echo v of B

f(B(value: 1))
f1(B(value: 1))
f2(B(value: 1))
var v: A = B(value: 1)
echo v of B
v.print

The test result

mem>objcast_test
B: value 1
B: value 140694538682368
true
B: value 0
true
B: value 1
true
B: value 1
true
true
B: value 140696177906336

Nim version
2.2.2

@ringabout
Copy link
Member

For the record, this example needs to continue to work

type
  A {.inheritable.} = object
  B = object of A
    f: int

proc `=destroy`(x: var B) = discard


proc `$$`[T](x: sink T): string =
  "{}"

let a: ref A = new(B)
doAssert $$a[] == "{}"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants