parent
ea0e45e62f
commit
48d41ab375
3 changed files with 24 additions and 7 deletions
|
|
@ -69,7 +69,7 @@ type
|
||||||
efWantStmt, efAllowStmt, efDetermineType, efExplain,
|
efWantStmt, efAllowStmt, efDetermineType, efExplain,
|
||||||
efWantValue, efOperand, efNoSemCheck,
|
efWantValue, efOperand, efNoSemCheck,
|
||||||
efNoEvaluateGeneric, efInCall, efFromHlo, efNoSem2Check,
|
efNoEvaluateGeneric, efInCall, efFromHlo, efNoSem2Check,
|
||||||
efNoUndeclared, efIsDotCall
|
efNoUndeclared, efIsDotCall, efCannotBeDotCall
|
||||||
# Use this if undeclared identifiers should not raise an error during
|
# Use this if undeclared identifiers should not raise an error during
|
||||||
# overload resolution.
|
# overload resolution.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1363,7 +1363,7 @@ proc tryReadingTypeField(c: PContext, n: PNode, i: PIdent, ty: PType): PNode =
|
||||||
else:
|
else:
|
||||||
result = tryReadingGenericParam(c, n, i, ty)
|
result = tryReadingGenericParam(c, n, i, ty)
|
||||||
|
|
||||||
proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc builtinFieldAccess(c: PContext; n: PNode; flags: var TExprFlags): PNode =
|
||||||
## returns nil if it's not a built-in field access
|
## returns nil if it's not a built-in field access
|
||||||
checkSonsLen(n, 2, c.config)
|
checkSonsLen(n, 2, c.config)
|
||||||
# tests/bind/tbindoverload.nim wants an early exit here, but seems to
|
# tests/bind/tbindoverload.nim wants an early exit here, but seems to
|
||||||
|
|
@ -1401,12 +1401,15 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
# field access and we leave the compiler to compile a normal call:
|
# field access and we leave the compiler to compile a normal call:
|
||||||
if getCurrOwner(c).kind != skMacro:
|
if getCurrOwner(c).kind != skMacro:
|
||||||
n.typ = makeTypeFromExpr(c, n.copyTree)
|
n.typ = makeTypeFromExpr(c, n.copyTree)
|
||||||
|
flags.incl efCannotBeDotCall
|
||||||
return n
|
return n
|
||||||
else:
|
else:
|
||||||
return nil
|
return nil
|
||||||
else:
|
else:
|
||||||
|
flags.incl efCannotBeDotCall
|
||||||
return tryReadingTypeField(c, n, i, ty.base)
|
return tryReadingTypeField(c, n, i, ty.base)
|
||||||
elif isTypeExpr(n.sons[0]):
|
elif isTypeExpr(n.sons[0]):
|
||||||
|
flags.incl efCannotBeDotCall
|
||||||
return tryReadingTypeField(c, n, i, ty)
|
return tryReadingTypeField(c, n, i, ty)
|
||||||
elif ty.kind == tyError:
|
elif ty.kind == tyError:
|
||||||
# a type error doesn't have any builtin fields
|
# a type error doesn't have any builtin fields
|
||||||
|
|
@ -1458,6 +1461,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
if result == nil:
|
if result == nil:
|
||||||
let t = n[0].typ.skipTypes(tyDotOpTransparent)
|
let t = n[0].typ.skipTypes(tyDotOpTransparent)
|
||||||
result = tryReadingGenericParam(c, n, i, t)
|
result = tryReadingGenericParam(c, n, i, t)
|
||||||
|
flags.incl efCannotBeDotCall
|
||||||
|
|
||||||
proc dotTransformation(c: PContext, n: PNode): PNode =
|
proc dotTransformation(c: PContext, n: PNode): PNode =
|
||||||
if isSymChoice(n[1]):
|
if isSymChoice(n[1]):
|
||||||
|
|
@ -1474,9 +1478,11 @@ proc dotTransformation(c: PContext, n: PNode): PNode =
|
||||||
proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
# this is difficult, because the '.' is used in many different contexts
|
# this is difficult, because the '.' is used in many different contexts
|
||||||
# in Nim. We first allow types in the semantic checking.
|
# in Nim. We first allow types in the semantic checking.
|
||||||
result = builtinFieldAccess(c, n, flags - {efIsDotCall})
|
var f = flags - {efIsDotCall}
|
||||||
if result == nil or ((result.typ == nil or result.typ.skipTypes(abstractInst).kind != tyProc) and
|
result = builtinFieldAccess(c, n, f)
|
||||||
efIsDotCall in flags and callOperator notin c.features):
|
if result == nil or ((result.typ == nil or result.typ.skipTypes(abstractInst).kind != tyProc) and
|
||||||
|
efIsDotCall in flags and callOperator notin c.features and
|
||||||
|
efCannotBeDotCall notin f):
|
||||||
result = dotTransformation(c, n)
|
result = dotTransformation(c, n)
|
||||||
|
|
||||||
proc buildOverloadedSubscripts(n: PNode, ident: PIdent): PNode =
|
proc buildOverloadedSubscripts(n: PNode, ident: PIdent): PNode =
|
||||||
|
|
@ -1744,7 +1750,8 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
|
||||||
# r.f = x
|
# r.f = x
|
||||||
# --> `f=` (r, x)
|
# --> `f=` (r, x)
|
||||||
let nOrig = n.copyTree
|
let nOrig = n.copyTree
|
||||||
a = builtinFieldAccess(c, a, {efLValue})
|
var flags = {efLValue}
|
||||||
|
a = builtinFieldAccess(c, a, flags)
|
||||||
if a == nil:
|
if a == nil:
|
||||||
a = propertyWriteAccess(c, n, nOrig, n[0])
|
a = propertyWriteAccess(c, n, nOrig, n[0])
|
||||||
if a != nil: return a
|
if a != nil: return a
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
discard """
|
discard """
|
||||||
output: '''true'''
|
output: '''true
|
||||||
|
5.0'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#bug #592
|
#bug #592
|
||||||
|
|
@ -89,3 +90,12 @@ proc does_fail(): Foo =
|
||||||
result.bar(5, a)
|
result.bar(5, a)
|
||||||
|
|
||||||
doAssert does_fail().bar == 0
|
doAssert does_fail().bar == 0
|
||||||
|
|
||||||
|
# bug #20645
|
||||||
|
|
||||||
|
type Zzz[Gen] = object
|
||||||
|
|
||||||
|
proc testZ(z: Zzz) =
|
||||||
|
echo z.Gen(5)
|
||||||
|
|
||||||
|
testZ(Zzz[float]())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue