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:
konsumlamm 2021-07-18 10:49:03 +02:00 • committed by GitHub
commit ac5435ecd0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 11 additions and 11 deletions

View file

@ -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

View file

@ -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))

View file

@ -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