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

Overload resultion with generic variables an inheritance #23870

Merged
merged 15 commits into from
Jul 24, 2024

Conversation

Graveflo
Copy link
Contributor

The test case diff is self explanatory

@Graveflo
Copy link
Contributor Author

just to add some context here, the inheritance penalty is not looked at unless other more important factors are considered. (exact matches etc). For this reason a "penalty" of zero doesn't mean "no penalty" as in "better then a penalty of 1,2,..etc", it means "no relation". No relation has to be worse then any inheritance penalty because at least there is a relation if the penalty is non-zero.

@Graveflo
Copy link
Contributor Author

actually, I think it would make more sense to rework this to make a penalty of 0 actually mean what it conceptually should and make the default -1 with negatives signifying "no inheritance relation".

@Graveflo Graveflo marked this pull request as draft July 22, 2024 23:07
@Graveflo Graveflo marked this pull request as ready for review July 24, 2024 01:44
@Araq Araq merged commit c1f91c2 into nim-lang:devel Jul 24, 2024
16 of 18 checks passed
Copy link
Contributor

Thanks for your hard work on this PR!
The lines below are statistics of the Nim compiler built from c1f91c2

Hint: mm: orc; opt: speed; options: -d:release
173262 lines; 8.625s; 652.074MiB peakmem

@Graveflo Graveflo deleted the inheritance-overload branch July 24, 2024 22:20
narimiran pushed a commit that referenced this pull request Aug 29, 2024
The test case diff is self explanatory

(cherry picked from commit c1f91c2)
narimiran pushed a commit that referenced this pull request Aug 31, 2024
The test case diff is self explanatory

(cherry picked from commit c1f91c2)
@metagn
Copy link
Collaborator

metagn commented Sep 16, 2024

This broke something with varargs in a way I can't reproduce. It's the cause of this: nim-works/cps#333

Trying to compile cps/normalizedast without that change causes it, this should be the entire relevant code but it works by itself, so maybe it's related to symbol order:

# a.nim
import std/macros
type NormNode* = distinct NimNode
converter normNodeToNimNode(n: NormNode): NimNode =
  n.NimNode

# b.nim
import std/macros
from std/typetraits import distinctBase
from a import NormNode
proc upgradeToNormalizedNode*[T](n: T): NormNode =
  when T is NormNode:
    n
  elif T is NimNode or T is distinct and distinctBase(T) is NimNode:
    NormNode n
  else:
    {.error: "abc".}
type
  AnyNodeVarargs = varargs[NormNode, upgradeToNormalizedNode]
proc newTree*(kind: NimNodeKind, n: AnyNodeVarargs): NormNode =
  NormNode macros.newTree(kind, varargs[NimNode] n)
proc wrap*(kind: NimNodeKind, n: NormNode): NormNode =
  newTree(kind, n)

@Graveflo
Copy link
Contributor Author

This broke something with varargs in a way I can't reproduce

Unless this is a comment just for documentation purposes I'm going to need more info then this. Not to be haphazard, but changes like this might change overload precedence, especially in edge cases. I'm not sure what binding rule is being violated here, and if that is actually a breakage in Nim. Looks like this potentially involves scope, distinct types, generics and varags which seems edge-casey. To flush out an issue we might need to really think about what the correct behavior should be. I believe there are pretty straight forward ways to determine if bindings are correct or not in general, but I can't really apply them here when it's not apparent what is going on.

@metagn
Copy link
Collaborator

metagn commented Sep 17, 2024

Unless this is a comment just for documentation purposes I'm going to need more info then this.

Maybe I should have been clearer, trying to compile the file cps/normalizedast.nim by itself is enough to cause it. I don't have more information, if I did I would know what the issue is.

To make things easier, the issue still occurs if newTree in normalizedast just uses varargs[NormNode] instead of AnyNodeVarargs = varargs[NormNode, upgradeToNormalizedNode], as well as when removing the converter in rewrites never mind, it needs the converter because of #22416. So yes this is a Nim bug, it's picking an outright wrong overload. I'm just saying this issue only happens after this commit, I don't know anything more than that.

More info: a.convMatches == b.convMatches since varargs increases convMatches for both equal matches and converter matches. The problem is that the inheritancePenalty of the NimNode overload is 0 when the other is -1:

  ...
  result = a.convMatches - b.convMatches
  if result != 0: return
  result = cmpInheritancePenalty(a.inheritancePenalty, b.inheritancePenalty)
  if a.calleeSym != nil and a.calleeSym.name.s == "newTree":
    echo (result, a.inheritancePenalty, b.inheritancePenalty, a.calleeSym.typ, b.calleeSym.typ)
  if result != 0: return
  ...

Output of the echo is:

(-4611686018427387903, -1, 0, proc (kind: NimNodeKind, n: varargs[NormNode]): NormNode{.noSideEffect, gcsafe.}, proc (kind: NimNodeKind, children: varargs[NimNode]): NimNode{.noSideEffect, gcsafe.})

My guess is somehow the inheritance penalty is being delayed until after the converter call, which causes NimNode to match itself perfectly. If this is intentional, maybe we can change the varargs match to lower itself some other way, like with a negative c.varargsPenalty field.

@Graveflo
Copy link
Contributor Author

Alright thanks for clarifying. I'll take a closer look later.

Araq added a commit that referenced this pull request Sep 20, 2024
This fixes a logic error in  #23870
The inheritance penalty should be -1 if there is no inheritance
relationship. Not sure how to write a test case for this one honestly.

---------

Co-authored-by: Andreas Rumpf <[email protected]>
metagn pushed a commit to metagn/Nim that referenced this pull request Sep 21, 2024
This fixes a logic error in  nim-lang#23870
The inheritance penalty should be -1 if there is no inheritance
relationship. Not sure how to write a test case for this one honestly.

---------

Co-authored-by: Andreas Rumpf <[email protected]>
narimiran pushed a commit that referenced this pull request Sep 23, 2024
This fixes a logic error in  #23870
The inheritance penalty should be -1 if there is no inheritance
relationship. Not sure how to write a test case for this one honestly.

---------

Co-authored-by: Andreas Rumpf <[email protected]>
(cherry picked from commit 37dba85)
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

Successfully merging this pull request may close these issues.

3 participants