mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 05:50:30 +00:00
treat var modifiers inside the concept body correctly: #1033
This commit is contained in:
committed by
Andreas Rumpf
parent
4483cefa0c
commit
c3e5c6c326
@@ -2206,9 +2206,14 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
message(n.info, warnDeprecated, "bind")
|
||||
result = semExpr(c, n.sons[0], flags)
|
||||
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})
|
||||
result.typ = makeTypeDesc(c, typ)
|
||||
#result = symNodeFromType(c, typ, n.info)
|
||||
of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit:
|
||||
# check if it is an expression macro:
|
||||
checkMinSonsLen(n, 1)
|
||||
|
||||
@@ -1202,6 +1202,15 @@ proc freshType(res, prev: PType): PType {.inline.} =
|
||||
else:
|
||||
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 =
|
||||
# if n.sonsLen == 0: return newConstraint(c, tyTypeClass)
|
||||
if nfBase2 in n.flags:
|
||||
@@ -1227,13 +1236,7 @@ proc semTypeClass(c: PContext, n: PNode, prev: PType): PType =
|
||||
dummyName: PNode
|
||||
dummyType: PType
|
||||
|
||||
let modifier = case param.kind
|
||||
of nkVarTy: tyVar
|
||||
of nkRefTy: tyRef
|
||||
of nkPtrTy: tyPtr
|
||||
of nkStaticTy: tyStatic
|
||||
of nkTypeOfExpr: tyTypeDesc
|
||||
else: tyNone
|
||||
let modifier = param.modifierTypeKindOfNode
|
||||
|
||||
if modifier != tyNone:
|
||||
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]
|
||||
|
||||
Reference in New Issue
Block a user