-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
compiler should give ambiguity errors in case of multiple compatible matches #8568
Comments
Here is the algorithm in excruciating detail. About |
actually the manual is not clear here for Exact match: a and f are of the same type. that depends on definition of "the same type" and "generic":
As for the other points marked as BUG, do you agree they are bugs? we can debate what correct answer should be for these (ambiguity error or a different match), but selected match doesn't make sense |
proc I agree all other points are bugs. |
ok; then docs in "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]." definitely need to be clarified and add an example like "A|B" |
yikes, that implies that vesion1 and vesion2 below have different semantics [1], and that version 2 should be preferred if we wanna avoid hijacking even though it's more convenient and "doesn't look" generic (even though it is) # version 1
proc foo(x:A|B) = bar(x)
# version 2
proc foo(x:A) = bar(x)
proc foo(x:B) = bar(x) [1] with yet another caveat: version 1 is hijackable (and not version 2), except if A is itself a generic... |
Yes- at least, this is my understanding. The difference is that in version 2 you are actually writing two specializations yourself. I find that thinking in terms of concrete types vs things that have to be specialized is the simplest point of view for understading most of Nim. (I am sure @Araq or @zah can correct if I got something wrong here) |
@andreaferretti Your remarks are all correct. |
I think this is another case, written in slightly different terms: proc foo(a: int): string = "foo1 "
proc foo(a: static[int]): string = "foo2 "
proc foo(a: var int): string = "foo3 "
proc foo[T: int](a: T): string = "foo4 "
#proc foo[T](a: T): string = "foo5 " # enable | disable this proc
const tmp1 = 1
let tmp2 = 1
var tmp3 = 1
echo foo(1), foo(tmp1), foo(tmp2), foo(tmp3)
echo foo[int](1), foo[int](tmp1), foo[int](tmp2), foo[int](tmp3)
#[
Results (disabled):
foo2 foo2 foo1 foo3
foo4 foo4 foo4 foo4
Results (enabled):
foo2 foo2 foo1 foo3
foo1 foo1 foo1 foo3
]# I'm not sure why specifying the generic in |
/cc @LemonBoy in #8700 you say:
(also reflected in PR title: Don't consider tyAnd/tyNot/tyOr/tyAnything as generic) this contradicts @andreaferretti 's comment above
so... what's the truth? Note: the answer to this affects how |
|
makes sense. So I guess: type T = T1|T2
proc foo(a:T)=discard
#is equivalent to:
proc foo[U: T1 | T2](a:U)=discard ?
|
Must not block the release, high prio instead of showstopper. |
see all entries marked as BUG:
The text was updated successfully, but these errors were encountered: