Skip to content

Commit 5ca94b9

Browse files
authored
allow any routine kind in concepts, fix concepts in other modules (#835)
* allow any routine kind in concepts, fix concepts in other modules fixes #829 * fix generic procs in iterinliner, update test
1 parent 3eaf073 commit 5ca94b9

File tree

5 files changed

+41
-13
lines changed

5 files changed

+41
-13
lines changed

src/hexer/iterinliner.nim

+9-2
Original file line numberDiff line numberDiff line change
@@ -488,11 +488,18 @@ proc transformStmt(e: var EContext; c: var Cursor) =
488488
of FuncS, ProcS, ConverterS, MethodS:
489489
e.dest.add c
490490
inc c
491-
for i in 0..<BodyPos:
491+
takeTree(e, c) # name
492+
takeTree(e, c) # exported
493+
takeTree(e, c) # pattern
494+
let isGeneric = c.substructureKind == TypevarsU
495+
for i in 3..<BodyPos:
492496
takeTree(e, c)
493497
let oldTmpId = e.tmpId
494498
e.tmpId = 0
495-
transformStmt(e, c)
499+
if isGeneric:
500+
takeTree(e, c)
501+
else:
502+
transformStmt(e, c)
496503
e.tmpId = oldTmpId
497504
takeParRi(e, c)
498505
of VarS, LetS, CursorS, ResultS:

src/nimony/sem.nim

+10-8
Original file line numberDiff line numberDiff line change
@@ -735,15 +735,14 @@ proc pickBestMatch(c: var SemContext; m: openArray[Match]): int =
735735
other = -1
736736
if other >= 0: result = -2 # ambiguous
737737

738-
const
739-
ConceptProcY = CchoiceY
740-
741738
type MagicCallKind = enum
742739
NonMagicCall, MagicCall, MagicCallNeedsSemcheck
743740

744741
proc addFn(c: var SemContext; fn: FnCandidate; fnOrig: Cursor; args: openArray[Item]): MagicCallKind =
745742
result = NonMagicCall
746-
if fn.kind in RoutineKinds:
743+
if fn.fromConcept and fn.sym != SymId(0):
744+
c.dest.add identToken(symToIdent(fn.sym), fnOrig.info)
745+
elif fn.kind in RoutineKinds:
747746
assert fn.sym != SymId(0)
748747
let res = tryLoadSym(fn.sym)
749748
if res.status == LacksNothing:
@@ -772,8 +771,6 @@ proc addFn(c: var SemContext; fn: FnCandidate; fnOrig: Cursor; args: openArray[I
772771
error "broken `magic`: expected ')', but got: ", n
773772
if result == NonMagicCall:
774773
c.dest.add symToken(fn.sym, fnOrig.info)
775-
elif fn.kind == ConceptProcY and fn.sym != SymId(0):
776-
c.dest.add identToken(symToIdent(fn.sym), fnOrig.info)
777774
else:
778775
c.dest.addSubtree fnOrig
779776

@@ -848,7 +845,7 @@ proc maybeAddConceptMethods(c: var SemContext; fn: StrId; typevar: SymId; cands:
848845
if prc.kind == SymbolDef and sameIdent(prc.symId, fn):
849846
var d = ops
850847
skipToParams d
851-
cands.addUnique FnCandidate(kind: ConceptProcY, sym: prc.symId, typ: d)
848+
cands.addUnique FnCandidate(kind: sk, sym: prc.symId, typ: d, fromConcept: true)
852849
skip ops
853850

854851
proc considerTypeboundOps(c: var SemContext; m: var seq[Match]; candidates: FnCandidates; args: openArray[Item], genericArgs: Cursor, hasNamedArgs: bool) =
@@ -2407,7 +2404,10 @@ proc semConceptType(c: var SemContext; n: var Cursor) =
24072404
if n.stmtKind != StmtsS:
24082405
error "(stmts) expected, but got: ", n
24092406
takeToken c, n
2407+
let oldScopeKind = c.currentScope.kind
24102408
withNewScope c:
2409+
# make syms of routines in toplevel concept also toplevel:
2410+
c.currentScope.kind = oldScopeKind
24112411
while true:
24122412
let k = n.symKind
24132413
if k in RoutineKinds:
@@ -3962,7 +3962,9 @@ proc semFor(c: var SemContext; it: var Item) =
39623962
var isMacroLike = false
39633963
if c.dest[beforeCall+1].kind == Symbol and c.isIterator(c.dest[beforeCall+1].symId):
39643964
discard "fine"
3965-
elif iterCall.typ.typeKind == UntypedT:
3965+
elif iterCall.typ.typeKind == UntypedT or
3966+
# for iterators from concepts in generic context:
3967+
c.dest[beforeCall+1].kind == Ident:
39663968
isMacroLike = true
39673969
else:
39683970
buildErr c, it.n.info, "iterator expected"

src/nimony/sigmatch.nim

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ type
2020
kind*: SymKind
2121
sym*: SymId
2222
typ*: Cursor
23+
fromConcept*: bool
2324

2425
MatchErrorKind* = enum
2526
InvalidMatch
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# issue #829
2+
3+
iterator `..`*(a, b: int): int {.inline.} =
4+
var i = a
5+
while i <= b:
6+
yield i
7+
inc i
8+
9+
type
10+
Iterable* = concept
11+
iterator `..`(a, b: Self): Self
12+
13+
proc default2*[I: Iterable; T: HasDefault](x: typedesc[array[I, T]]): array[I, T] {.inline, noinit.} =
14+
# Needs to call iterator `..`(a, b: I): I
15+
for i in low(array[I, T]) .. high(array[I, T]):
16+
result[i] = default(T)
17+
18+
var x = default2(array[2, int])

tests/nimony/nosystem/tfib2.nif

+3-3
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,16 @@
7676
(concept . .
7777
(typevar :Self.0.tfitjdpcx . . . .) ~8,1
7878
(stmts
79-
(proc 5 :<=.0 . . . 9
79+
(proc 5 :<=.2.tfitjdpcx . . . 9
8080
(params 1
8181
(param :a.0 . . 6 Self.0.tfitjdpcx .) 4
8282
(param :b.0 . . 3 Self.0.tfitjdpcx .)) 14
8383
(bool) . . .) ,1
84-
(proc 5 :\2B.0 . . . 8
84+
(proc 5 :\2B.2.tfitjdpcx . . . 8
8585
(params 1
8686
(param :x.6 . . 6 Self.0.tfitjdpcx .) 4
8787
(param :y.6 . . 3 Self.0.tfitjdpcx .)) 14 Self.0.tfitjdpcx . . .) ,2
88-
(proc 5 :\2D.0 . . . 8
88+
(proc 5 :\2D.2.tfitjdpcx . . . 8
8989
(params 1
9090
(param :x.7 . . 6 Self.0.tfitjdpcx .) 4
9191
(param :y.7 . . 3 Self.0.tfitjdpcx .)) 14 Self.0.tfitjdpcx . . .)))) ,22

0 commit comments

Comments
 (0)