diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2023-01-18 06:15:23 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-17 23:15:23 +0100 |
commit | cc08a9015e446471be8b734c2895d99c91c59cb3 (patch) | |
tree | 9ecf4c79d650d875433a99d9c3d509d671f493c9 | |
parent | 30da566d9dc81feab9ba3015d293d93b5c6785af (diff) | |
download | Nim-cc08a9015e446471be8b734c2895d99c91c59cb3.tar.gz |
fixes #21263; consider all candidates for concept matches (#21265)
-rw-r--r-- | compiler/concepts.nim | 2 | ||||
-rw-r--r-- | compiler/lookups.nim | 17 | ||||
-rw-r--r-- | tests/concepts/tconcepts_issues.nim | 25 |
3 files changed, 43 insertions, 1 deletions
diff --git a/compiler/concepts.nim b/compiler/concepts.nim index a810b3642..bcf2d4d0e 100644 --- a/compiler/concepts.nim +++ b/compiler/concepts.nim @@ -274,7 +274,7 @@ proc matchSym(c: PContext; candidate: PSym, n: PNode; m: var MatchCon): bool = proc matchSyms(c: PContext, n: PNode; kinds: set[TSymKind]; m: var MatchCon): bool = ## Walk the current scope, extract candidates which the same name as 'n[namePos]', ## 'n' is the nkProcDef or similar from the concept that we try to match. - let candidates = searchInScopesFilterBy(c, n[namePos].sym.name, kinds) + let candidates = searchInScopesAllCandidatesFilterBy(c, n[namePos].sym.name, kinds) for candidate in candidates: #echo "considering ", typeToString(candidate.typ), " ", candidate.magic m.magic = candidate.magic diff --git a/compiler/lookups.nim b/compiler/lookups.nim index 3f4fcb4d0..e7bca08bc 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -228,6 +228,23 @@ proc debugScopes*(c: PContext; limit=0, max = int.high) {.deprecated.} = if i == limit: return inc i +proc searchInScopesAllCandidatesFilterBy*(c: PContext, s: PIdent, filter: TSymKinds): seq[PSym] = + result = @[] + for scope in allScopes(c.currentScope): + var ti: TIdentIter + var candidate = initIdentIter(ti, scope.symbols, s) + while candidate != nil: + if candidate.kind in filter: + result.add candidate + candidate = nextIdentIter(ti, scope.symbols) + + if result.len == 0: + var marked = initIntSet() + for im in c.imports.mitems: + for s in symbols(im, marked, s, c.graph): + if s.kind in filter: + result.add s + proc searchInScopesFilterBy*(c: PContext, s: PIdent, filter: TSymKinds): seq[PSym] = result = @[] block outer: diff --git a/tests/concepts/tconcepts_issues.nim b/tests/concepts/tconcepts_issues.nim index 802582f57..3efb9964a 100644 --- a/tests/concepts/tconcepts_issues.nim +++ b/tests/concepts/tconcepts_issues.nim @@ -27,6 +27,8 @@ false true -1 Meow +10 0.0 +1 2.0 ''' joinable: false """ @@ -500,3 +502,26 @@ var r, b: Fp2[6, uint64] prod(r, b) + +block: # bug #21263 + type + DateDayFraction = concept # no T, an atom + proc date(a: Self): int + proc fraction(b: Self): float + Date = distinct int + DateDayFractionImpl = object + date : int + fraction : float + + proc date(a: Date): int = a.int + proc fraction(a:Date): float = 0.0 + + proc date(a: DateDayFractionImpl): int = a.date + proc fraction(b: DateDayFractionImpl): float = b.fraction + + + proc print(a: DateDayFraction) = + echo a.date, " ", a.fraction + + print(10.Date) # ok + print(DateDayFractionImpl(date: 1, fraction: 2)) # error |