treat var modifiers inside the concept body correctly: #1033
This commit is contained in:
parent
4483cefa0c
commit
c3e5c6c326
3 changed files with 46 additions and 8 deletions
|
|
@ -2206,9 +2206,14 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
message(n.info, warnDeprecated, "bind")
|
message(n.info, warnDeprecated, "bind")
|
||||||
result = semExpr(c, n.sons[0], flags)
|
result = semExpr(c, n.sons[0], flags)
|
||||||
of nkTypeOfExpr, nkTupleTy, nkTupleClassTy, nkRefTy..nkEnumTy, nkStaticTy:
|
of nkTypeOfExpr, nkTupleTy, nkTupleClassTy, nkRefTy..nkEnumTy, nkStaticTy:
|
||||||
|
if c.matchedConcept != nil and n.len == 1:
|
||||||
|
let modifier = n.modifierTypeKindOfNode
|
||||||
|
if modifier != tyNone:
|
||||||
|
var baseType = semExpr(c, n[0]).typ.skipTypes({tyTypeDesc})
|
||||||
|
result.typ = c.makeTypeDesc(c.newTypeWithSons(modifier, @[baseType]))
|
||||||
|
return
|
||||||
var typ = semTypeNode(c, n, nil).skipTypes({tyTypeDesc})
|
var typ = semTypeNode(c, n, nil).skipTypes({tyTypeDesc})
|
||||||
result.typ = makeTypeDesc(c, typ)
|
result.typ = makeTypeDesc(c, typ)
|
||||||
#result = symNodeFromType(c, typ, n.info)
|
|
||||||
of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit:
|
of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit:
|
||||||
# check if it is an expression macro:
|
# check if it is an expression macro:
|
||||||
checkMinSonsLen(n, 1)
|
checkMinSonsLen(n, 1)
|
||||||
|
|
|
||||||
|
|
@ -1202,6 +1202,15 @@ proc freshType(res, prev: PType): PType {.inline.} =
|
||||||
else:
|
else:
|
||||||
result = res
|
result = res
|
||||||
|
|
||||||
|
template modifierTypeKindOfNode(n: PNode): TTypeKind =
|
||||||
|
case n.kind
|
||||||
|
of nkVarTy: tyVar
|
||||||
|
of nkRefTy: tyRef
|
||||||
|
of nkPtrTy: tyPtr
|
||||||
|
of nkStaticTy: tyStatic
|
||||||
|
of nkTypeOfExpr: tyTypeDesc
|
||||||
|
else: tyNone
|
||||||
|
|
||||||
proc semTypeClass(c: PContext, n: PNode, prev: PType): PType =
|
proc semTypeClass(c: PContext, n: PNode, prev: PType): PType =
|
||||||
# if n.sonsLen == 0: return newConstraint(c, tyTypeClass)
|
# if n.sonsLen == 0: return newConstraint(c, tyTypeClass)
|
||||||
if nfBase2 in n.flags:
|
if nfBase2 in n.flags:
|
||||||
|
|
@ -1227,13 +1236,7 @@ proc semTypeClass(c: PContext, n: PNode, prev: PType): PType =
|
||||||
dummyName: PNode
|
dummyName: PNode
|
||||||
dummyType: PType
|
dummyType: PType
|
||||||
|
|
||||||
let modifier = case param.kind
|
let modifier = param.modifierTypeKindOfNode
|
||||||
of nkVarTy: tyVar
|
|
||||||
of nkRefTy: tyRef
|
|
||||||
of nkPtrTy: tyPtr
|
|
||||||
of nkStaticTy: tyStatic
|
|
||||||
of nkTypeOfExpr: tyTypeDesc
|
|
||||||
else: tyNone
|
|
||||||
|
|
||||||
if modifier != tyNone:
|
if modifier != tyNone:
|
||||||
dummyName = param[0]
|
dummyName = param[0]
|
||||||
|
|
|
||||||
30
tests/concepts/tmodifiersinplace.nim
Normal file
30
tests/concepts/tmodifiersinplace.nim
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
type
|
||||||
|
VarContainer[T] = concept c
|
||||||
|
put(var c, T)
|
||||||
|
|
||||||
|
AltVarContainer[T] = concept var c
|
||||||
|
put(c, T)
|
||||||
|
|
||||||
|
NonVarContainer[T] = concept c
|
||||||
|
put(c, T)
|
||||||
|
|
||||||
|
GoodContainer = object
|
||||||
|
x: int
|
||||||
|
|
||||||
|
BadContainer = object
|
||||||
|
x: int
|
||||||
|
|
||||||
|
proc put(x: BadContainer, y: int) = discard
|
||||||
|
proc put(x: var GoodContainer, y: int) = discard
|
||||||
|
|
||||||
|
template ok(x) = assert(x)
|
||||||
|
template no(x) = assert(not(x))
|
||||||
|
|
||||||
|
static:
|
||||||
|
ok GoodContainer is VarContainer[int]
|
||||||
|
ok GoodContainer is AltVarContainer[int]
|
||||||
|
no BadContainer is VarContainer[int]
|
||||||
|
no BadContainer is AltVarContainer[int]
|
||||||
|
ok GoodContainer is NonVarContainer[int]
|
||||||
|
ok BadContainer is NonVarContainer[int]
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue