diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/semexprs.nim | 28 | ||||
-rw-r--r-- | compiler/semstmts.nim | 20 |
2 files changed, 45 insertions, 3 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 8c4f25e12..c839d04d9 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -54,7 +54,8 @@ proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = semExpr(c, n, flags + {efOperand}) if result.typ != nil: # XXX tyGenericInst here? - if result.typ.kind == tyProc and tfUnresolved in result.typ.flags: + if result.typ.kind == tyProc and hasUnresolvedParams(result, {efOperand}): + #and tfUnresolved in result.typ.flags: localError(c.config, n.info, errProcHasNoConcreteType % n.renderTree) if result.typ.kind in {tyVar, tyLent}: result = newDeref(result) elif {efWantStmt, efAllowStmt} * flags != {}: @@ -2649,6 +2650,23 @@ proc shouldBeBracketExpr(n: PNode): bool = n[0] = be return true +proc asBracketExpr(c: PContext; n: PNode): PNode = + proc isGeneric(c: PContext; n: PNode): bool = + if n.kind in {nkIdent, nkAccQuoted}: + let s = qualifiedLookUp(c, n, {}) + result = s != nil and isGenericRoutineStrict(s) + + assert n.kind in nkCallKinds + if n.len > 1 and isGeneric(c, n[1]): + let b = n[0] + if b.kind in nkSymChoices: + for i in 0..<b.len: + if b[i].kind == nkSym and b[i].sym.magic == mArrGet: + result = newNodeI(nkBracketExpr, n.info) + for i in 1..<n.len: result.add(n[i]) + return result + return nil + proc hoistParamsUsedInDefault(c: PContext, call, letSection, defExpr: var PNode) = # This takes care of complicated signatures such as: # proc foo(a: int, b = a) @@ -2820,8 +2838,14 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # the 'newSeq[T](x)' bug setGenericParams(c, n[0]) result = semDirectOp(c, n, flags) - elif isSymChoice(n[0]) or nfDotField in n.flags: + elif nfDotField in n.flags: result = semDirectOp(c, n, flags) + elif isSymChoice(n[0]): + let b = asBracketExpr(c, n) + if b != nil: + result = semExpr(c, b, flags) + else: + result = semDirectOp(c, n, flags) else: result = semIndirectOp(c, n, flags) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 085146f7f..a2401b376 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -385,6 +385,23 @@ proc hasEmpty(typ: PType): bool = for s in typ.sons: result = result or hasEmpty(s) +proc hasUnresolvedParams(n: PNode; flags: TExprFlags): bool = + result = tfUnresolved in n.typ.flags + when false: + case n.kind + of nkSym: + result = isGenericRoutineStrict(n.sym) + of nkSymChoices: + for ch in n: + if hasUnresolvedParams(ch, flags): + return true + result = false + else: + result = false + if efOperand in flags: + if tfUnresolved notin n.typ.flags: + result = false + proc makeDeref(n: PNode): PNode = var t = n.typ if t.kind in tyUserTypeClasses and t.isResolvedUserTypeClass: @@ -517,7 +534,8 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = typ = typ.lastSon if hasEmpty(typ): localError(c.config, def.info, errCannotInferTypeOfTheLiteral % typ.kind.toHumanStr) - elif typ.kind == tyProc and tfUnresolved in typ.flags: + elif typ.kind == tyProc and hasUnresolvedParams(def, {}): + # tfUnresolved in typ.flags: localError(c.config, def.info, errProcHasNoConcreteType % def.renderTree) when false: # XXX This typing rule is neither documented nor complete enough to |