diff options
-rw-r--r-- | compiler/semdata.nim | 2 | ||||
-rw-r--r-- | compiler/semexprs.nim | 17 | ||||
-rw-r--r-- | tests/overload/toverl4.nim | 12 |
3 files changed, 24 insertions, 7 deletions
diff --git a/compiler/semdata.nim b/compiler/semdata.nim index e9804fd56..337b5f867 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -69,7 +69,7 @@ type efWantStmt, efAllowStmt, efDetermineType, efExplain, efWantValue, efOperand, efNoSemCheck, efNoEvaluateGeneric, efInCall, efFromHlo, efNoSem2Check, - efNoUndeclared, efIsDotCall + efNoUndeclared, efIsDotCall, efCannotBeDotCall # Use this if undeclared identifiers should not raise an error during # overload resolution. diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index daee3dffa..08fc4f98f 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1363,7 +1363,7 @@ proc tryReadingTypeField(c: PContext, n: PNode, i: PIdent, ty: PType): PNode = else: 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 checkSonsLen(n, 2, c.config) # 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: if getCurrOwner(c).kind != skMacro: n.typ = makeTypeFromExpr(c, n.copyTree) + flags.incl efCannotBeDotCall return n else: return nil else: + flags.incl efCannotBeDotCall return tryReadingTypeField(c, n, i, ty.base) elif isTypeExpr(n.sons[0]): + flags.incl efCannotBeDotCall return tryReadingTypeField(c, n, i, ty) elif ty.kind == tyError: # 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: let t = n[0].typ.skipTypes(tyDotOpTransparent) result = tryReadingGenericParam(c, n, i, t) + flags.incl efCannotBeDotCall proc dotTransformation(c: PContext, n: PNode): PNode = if isSymChoice(n[1]): @@ -1474,9 +1478,11 @@ proc dotTransformation(c: PContext, n: PNode): PNode = proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = # this is difficult, because the '.' is used in many different contexts # in Nim. We first allow types in the semantic checking. - result = builtinFieldAccess(c, n, flags - {efIsDotCall}) - if result == nil or ((result.typ == nil or result.typ.skipTypes(abstractInst).kind != tyProc) and - efIsDotCall in flags and callOperator notin c.features): + var f = flags - {efIsDotCall} + result = builtinFieldAccess(c, n, f) + 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) proc buildOverloadedSubscripts(n: PNode, ident: PIdent): PNode = @@ -1744,7 +1750,8 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = # r.f = x # --> `f=` (r, x) let nOrig = n.copyTree - a = builtinFieldAccess(c, a, {efLValue}) + var flags = {efLValue} + a = builtinFieldAccess(c, a, flags) if a == nil: a = propertyWriteAccess(c, n, nOrig, n[0]) if a != nil: return a diff --git a/tests/overload/toverl4.nim b/tests/overload/toverl4.nim index 455a73515..21cedaa96 100644 --- a/tests/overload/toverl4.nim +++ b/tests/overload/toverl4.nim @@ -1,5 +1,6 @@ discard """ - output: '''true''' + output: '''true +5.0''' """ #bug #592 @@ -89,3 +90,12 @@ proc does_fail(): Foo = result.bar(5, a) doAssert does_fail().bar == 0 + +# bug #20645 + +type Zzz[Gen] = object + +proc testZ(z: Zzz) = + echo z.Gen(5) + +testZ(Zzz[float]()) |