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

Unable to make a const instance of an inherited, generic object. #11268

Closed
linkmonitor opened this issue May 16, 2019 · 10 comments

Comments

Projects
None yet
6 participants
@linkmonitor
Copy link

commented May 16, 2019

Compilation fails when it includes a const instance of an object inherited from a generic object.

Example

type
  Point1[T] = object of RootObj
    x:T

  Point2[T] = object of Point1[T]
    y:T

proc main =
  var a = Point2[int](x:1, y:2)
  echo a

  let b = Point2[int](x:1, y:2)
  echo b

  const c = Point2[int](x:1, y:2)
  echo c

when isMainModule:
  main()

Current Output

main.nim(15, 24) Error: cannot create null element for: [T]

Expected Output

(y: 2, x: 1)
(y: 2, x: 1)
(y: 2, x: 1)

Additional Information

Updated my toolchain using choosenim approximately 6 hours ago.

$ nim -v
Nim Compiler Version 0.19.9 [Linux: amd64]
Compiled at 2019-05-16
Copyright (c) 2006-2019 by Andreas Rumpf

active boot switches: -d:release
@mratsim

This comment has been minimized.

Copy link
Collaborator

commented May 17, 2019

This shouldn't be allowed and caught during semcheck.

Point2 should be a ref object of Point1 because it adds new field and that will change the size of the type.

@krux02

This comment has been minimized.

Copy link
Contributor

commented May 17, 2019

@mratsim: Well I disagree. I think is not code where you should use a ref type. I think it is just a bug in the VM.

@krux02 krux02 added VM and removed Language design labels May 17, 2019

@mratsim

This comment has been minimized.

Copy link
Collaborator

commented May 17, 2019

I think it brings extra complexity with little benefits.
For example you cannot store them in a sequence:

type
  Point1 = object of RootObj
    x: int

  Point2 = object of Point1
    y: int

  PointString = object of Point1
    s: string

var a: seq[Point1]

a.add Point1(x: 1)
a.add Point2(x: 2, y: 2)
a.add PointString(x: 3, s: "s")

echo a
@linkmonitor

This comment has been minimized.

Copy link
Author

commented May 17, 2019

Whether or not inheritance is appropriate for this snippet, I think it's reasonable to assume there are cases where non-ref inheritance is useful.

I don't use the "generic inherited point" pattern in code; it's an example I use to explore what's possible given the language's features.

@krux02

This comment has been minimized.

Copy link
Contributor

commented May 18, 2019

@mratsim I know what non ref inheritance means. Nobody tries to do that here.

I was thinking that the combination of generics and inheritance at compile time causes the problems here, but aparently that is not the cause of this problem. The snippet refuses to work even without generics:

type
  Point1 = object of RootObj
    x: int

  Point2 = object of Point1
    y: int

proc main =
  var a = Point2(x:1, y:2)
  echo a

  let b = Point2(x:1, y:2)
  echo b


  const c = Point2(x:1, y:2)

  echo c

static:
  let d = Point2(x:1, y:2)
  echo d

when isMainModule:
  main()
@Araq

This comment has been minimized.

Copy link
Member

commented May 20, 2019

const objects are not allowed to inherit and are not allowed to have case in them, the compiler's error message should say so, but doesn't.

@linkmonitor

This comment has been minimized.

Copy link
Author

commented May 20, 2019

Out of curiosity, why can't const objects inherit or have case in them? It may be obvious to others, but I don't intrinsically understand why.

@krux02

This comment has been minimized.

Copy link
Contributor

commented May 20, 2019

@linkmonitor it's not outright impossible to have const objects with inheritance and case objects in them. But it is not implemented in the VM. So if the demand to support this functionality for Nim raises and people actually want to have const cast objects with inheritance, then it might be possible to implement it. But right now it is more important to fix issues with existing features and have proper error messages on features that just don't work well.

But really, normally it is totally sufficient to have normals objects as const values.

@linkmonitor

This comment has been minimized.

Copy link
Author

commented May 20, 2019

Copy that, and I absolutely understand the need to prioritize.

Thank you for explaining.

Araq added a commit that referenced this issue May 21, 2019

@Araq Araq closed this in 23dbc9a May 22, 2019

@Clyybber

This comment has been minimized.

Copy link
Contributor

commented May 24, 2019

Now fails with
(16, 19) Error: invalid field at index 2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.