Make error message for empty new-styled concept more descriptive (#18506)
* Allow empty new-styled concept Slightly improve error messages * Make empty new-styled concepts an error
This commit is contained in:
parent
923a1c6ea7
commit
ac5435ecd0
3 changed files with 11 additions and 11 deletions
|
|
@ -11,8 +11,7 @@
|
||||||
## for details. Note this is a first implementation and only the "Concept matching"
|
## for details. Note this is a first implementation and only the "Concept matching"
|
||||||
## section has been implemented.
|
## section has been implemented.
|
||||||
|
|
||||||
import ast, astalgo, semdata, lookups, lineinfos, idents, msgs, renderer,
|
import ast, astalgo, semdata, lookups, lineinfos, idents, msgs, renderer, types, intsets
|
||||||
types, intsets
|
|
||||||
|
|
||||||
from magicsys import addSonSkipIntLit
|
from magicsys import addSonSkipIntLit
|
||||||
|
|
||||||
|
|
@ -23,7 +22,7 @@ const
|
||||||
## --------------------------------------
|
## --------------------------------------
|
||||||
|
|
||||||
proc declareSelf(c: PContext; info: TLineInfo) =
|
proc declareSelf(c: PContext; info: TLineInfo) =
|
||||||
## adds the magical 'Self' symbols to the current scope.
|
## Adds the magical 'Self' symbols to the current scope.
|
||||||
let ow = getCurrOwner(c)
|
let ow = getCurrOwner(c)
|
||||||
let s = newSym(skType, getIdent(c.cache, "Self"), nextSymId(c.idgen), ow, info)
|
let s = newSym(skType, getIdent(c.cache, "Self"), nextSymId(c.idgen), ow, info)
|
||||||
s.typ = newType(tyTypeDesc, nextTypeId(c.idgen), ow)
|
s.typ = newType(tyTypeDesc, nextTypeId(c.idgen), ow)
|
||||||
|
|
@ -32,7 +31,7 @@ proc declareSelf(c: PContext; info: TLineInfo) =
|
||||||
addDecl(c, s, info)
|
addDecl(c, s, info)
|
||||||
|
|
||||||
proc isSelf*(t: PType): bool {.inline.} =
|
proc isSelf*(t: PType): bool {.inline.} =
|
||||||
## is this the magical 'Self' type?
|
## Is this the magical 'Self' type?
|
||||||
t.kind == tyTypeDesc and tfPacked in t.flags
|
t.kind == tyTypeDesc and tfPacked in t.flags
|
||||||
|
|
||||||
proc makeTypeDesc*(c: PContext, typ: PType): PType =
|
proc makeTypeDesc*(c: PContext, typ: PType): PType =
|
||||||
|
|
@ -45,8 +44,8 @@ proc makeTypeDesc*(c: PContext, typ: PType): PType =
|
||||||
|
|
||||||
proc semConceptDecl(c: PContext; n: PNode): PNode =
|
proc semConceptDecl(c: PContext; n: PNode): PNode =
|
||||||
## Recursive helper for semantic checking for the concept declaration.
|
## Recursive helper for semantic checking for the concept declaration.
|
||||||
## Currently we only support lists of statements containing 'proc'
|
## Currently we only support (possibly empty) lists of statements
|
||||||
## declarations and the like.
|
## containing 'proc' declarations and the like.
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkStmtList, nkStmtListExpr:
|
of nkStmtList, nkStmtListExpr:
|
||||||
result = shallowCopy(n)
|
result = shallowCopy(n)
|
||||||
|
|
@ -60,7 +59,7 @@ proc semConceptDecl(c: PContext; n: PNode): PNode =
|
||||||
result[i] = n[i]
|
result[i] = n[i]
|
||||||
result[^1] = semConceptDecl(c, n[^1])
|
result[^1] = semConceptDecl(c, n[^1])
|
||||||
else:
|
else:
|
||||||
localError(c.config, n.info, "unexpected construct in the new-styled concept " & renderTree(n))
|
localError(c.config, n.info, "unexpected construct in the new-styled concept: " & renderTree(n))
|
||||||
result = n
|
result = n
|
||||||
|
|
||||||
proc semConceptDeclaration*(c: PContext; n: PNode): PNode =
|
proc semConceptDeclaration*(c: PContext; n: PNode): PNode =
|
||||||
|
|
@ -97,7 +96,7 @@ proc existingBinding(m: MatchCon; key: PType): PType =
|
||||||
proc conceptMatchNode(c: PContext; n: PNode; m: var MatchCon): bool
|
proc conceptMatchNode(c: PContext; n: PNode; m: var MatchCon): bool
|
||||||
|
|
||||||
proc matchType(c: PContext; f, a: PType; m: var MatchCon): bool =
|
proc matchType(c: PContext; f, a: PType; m: var MatchCon): bool =
|
||||||
## the heart of the concept matching process. 'f' is the formal parameter of some
|
## The heart of the concept matching process. 'f' is the formal parameter of some
|
||||||
## routine inside the concept that we're looking for. 'a' is the formal parameter
|
## routine inside the concept that we're looking for. 'a' is the formal parameter
|
||||||
## of a routine that might match.
|
## of a routine that might match.
|
||||||
const
|
const
|
||||||
|
|
|
||||||
|
|
@ -2058,6 +2058,8 @@ proc parseTypeClass(p: var Parser): PNode =
|
||||||
skipComment(p, result)
|
skipComment(p, result)
|
||||||
# an initial IND{>} HAS to follow:
|
# an initial IND{>} HAS to follow:
|
||||||
if not realInd(p):
|
if not realInd(p):
|
||||||
|
if result.isNewStyleConcept:
|
||||||
|
parMessage(p, "routine expected, but found '$1' (empty new-styled concepts are not allowed)", p.tok)
|
||||||
result.add(p.emptyNode)
|
result.add(p.emptyNode)
|
||||||
else:
|
else:
|
||||||
result.add(parseStmt(p))
|
result.add(parseStmt(p))
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,7 @@ discard """
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
yes int
|
yes int
|
||||||
string int
|
string int'''
|
||||||
true'''
|
|
||||||
joinable: false
|
joinable: false
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -102,5 +101,5 @@ type Monoid = concept
|
||||||
|
|
||||||
proc z(x: typedesc[int]): int = 0
|
proc z(x: typedesc[int]): int = 0
|
||||||
|
|
||||||
echo(int is Monoid)
|
doAssert int is Monoid
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue