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

Overloading resolution chooses a generic template instead of a method for an inherited type #17003

Closed
ghost opened this issue Feb 10, 2021 · 2 comments

Comments

@ghost
Copy link

ghost commented Feb 10, 2021

This code is expected to call the dispose method but it calls a template instead.

Found in the 4th NiGui example.
It crashes with ARC/ORC because Nim calls ARC's dispose from here instead of NiGui's dispose defined here (it's exported in the forward declaration at the top of the file).

Example

type
  Window* = ref object of RootObj
  WindowImpl* = ref object of Window

# Without that template the method will be called
template dispose[T](x: ref T) = 
  echo "called the template dispose"

method dispose(t: Window) {.base.} = 
  echo "called the method dispose"

var t = WindowImpl()
t.dispose()

Current Output

called the template dispose

Expected Output

called the method dispose
$ nim -v
Nim Compiler Version 1.5.1 [Linux: amd64]
Compiled at 2021-02-10
Copyright (c) 2006-2021 by Andreas Rumpf

git hash: 216be4060a853b3425501318537d598c4842eefc
active boot switches: -d:release
@ghost

This comment has been minimized.

@ghost ghost changed the title With ARC/ORC the wrong dispose is called when inheritance is involved Overloading resolution wrongly chooses a generic template instead of a proc Feb 10, 2021
@ghost ghost changed the title Overloading resolution wrongly chooses a generic template instead of a proc Overloading resolution wrongly chooses a generic template instead of a proc for an inherited type Feb 10, 2021
@ghost ghost changed the title Overloading resolution wrongly chooses a generic template instead of a proc for an inherited type Overloading resolution wrongly chooses a generic template instead of a method for an inherited type Feb 10, 2021
@ghost ghost changed the title Overloading resolution wrongly chooses a generic template instead of a method for an inherited type Overloading resolution chooses a generic template instead of a method for an inherited type Feb 10, 2021
@Araq
Copy link
Member

Araq commented Feb 16, 2021

From the spec:

Every arg in args needs to match. There are multiple different categories how an
argument can match. Let f be the formal parameter's type and a the type
of the argument.

  1. Generic match: f is a generic type and a matches, for
    instance a is int and f is a generic (constrained) parameter
    type (like in [T] or [T: int|char].
  2. Subrange or subtype match: a is a range[T] and T
    matches f exactly. Or: a is a subtype of f.

These matching categories have a priority: An exact match is better than a
literal match and that is better than a generic match etc.

The compiler is correct.

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

No branches or pull requests

1 participant