diff --git a/compiler/mir/proto_mir.nim b/compiler/mir/proto_mir.nim index 13e8982c2e5..b0c1784b553 100644 --- a/compiler/mir/proto_mir.nim +++ b/compiler/mir/proto_mir.nim @@ -800,12 +800,7 @@ proc exprToPmir(c: TranslateCtx, result: var seq[ProtoItem], n: PNode, sink: boo recurse(selectWhenBranch(n, c.pickVm), sink) of nkStmtListExpr: recurse(n.lastSon, sink) - # HACK: inherit the type from the child node. This prevents incorrectly - # typed array constructions (a sem bug) from appearing to work - # correctly (see - # tests/lang_exprs/tempty_typed_expressions_issues.nim) - result.add ProtoItem(orig: n, typ: result[^1].typ, kind: pirStmtList) - #node pirStmtList + node pirStmtList of nkPragmaBlock: # the pragma is uninteresting here, just skip it recurse(n.lastSon, sink) diff --git a/compiler/sem/semcall.nim b/compiler/sem/semcall.nim index f9646ed0352..f46b1d65bbf 100644 --- a/compiler/sem/semcall.nim +++ b/compiler/sem/semcall.nim @@ -570,7 +570,10 @@ proc semResolvedCall(c: PContext, x: TCandidate, instGenericConvertersSons(c, result, x) result[0] = newSymNode(finalCallee, getCallLineInfo(result[0])) result.typ = finalCallee.typ[0] - result = updateDefaultParams(c.config, result) + if gp.isGenericParams: + # default parameters only need to be updated for instantiated generic + # routines. For normal routines they're already correct + result = updateDefaultParams(c.config, result) proc semOverloadedCall(c: PContext, n, nOrig: PNode, filter: TSymKinds, flags: TExprFlags): PNode {.nosinks.} = @@ -748,7 +751,11 @@ proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym = x.addSonSkipIntLit(t.baseOfDistinct(c.graph, c.idgen), c.idgen) else: x = t.baseOfDistinct(c.graph, c.idgen) - call.add(newNodeIT(nkEmpty, fn.info, x)) + let arg = newNodeIT(nkEmpty, fn.info, x) + # mark the node as analysed so that operand analysis doesn't analyze it + # again + arg.flags.incl nfSem + call.add(arg) if hasDistinct: let filter = if fn.kind in {skProc, skFunc}: {skProc, skFunc} else: {fn.kind} var resolved = semOverloadedCall(c, call, call, filter, {}) diff --git a/compiler/sem/semexprs.nim b/compiler/sem/semexprs.nim index 66dbc8bac7e..03ab3b507c2 100644 --- a/compiler/sem/semexprs.nim +++ b/compiler/sem/semexprs.nim @@ -56,6 +56,7 @@ proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = c.config.newError(n, PAstDiag(kind: adSemProcHasNoConcreteType)) elif result.typ.kind in {tyVar, tyLent}: result = newDeref(result) + result.flags.incl nfSem elif {efWantStmt, efAllowStmt} * flags != {}: result.typ = newTypeS(tyVoid, c) else: @@ -93,6 +94,7 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = elif result.typ.kind in {tyVar, tyLent}: result = newDeref(result) + result.flags.incl nfSem proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = semExprCheck(c, n, flags) @@ -1840,7 +1842,8 @@ proc dotTransformation(c: PContext, n: PNode): PNode = PAstDiag(kind: adSemExpectedIdentifierWithExprContext, expr: n)) - result.add copyTree(n[0]) + # the operand was already sem'ed immediately prior. No need to copy it + result.add n[0] if result[0].kind == nkError: # handle the potential ident error result = c.config.wrapError(result) @@ -2807,6 +2810,8 @@ proc setMs(n: PNode, s: PSym): PNode = n[0] = newSymNode(s) n[0].info = n.info +proc asBracketExpr(c: PContext; n: PNode): PNode + proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = # this is a hotspot in the compiler! result = n @@ -2891,6 +2896,14 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = of mSizeOf: markUsed(c, n.info, s) result = semSizeOf(c, setMs(n, s)) + of mArrGet: + # this could be a rewritten subscript operation + let b = asBracketExpr(c, n) + if b.isNil: + # it's not + result = semDirectOp(c, n, flags) + else: + result = semArrayAccess(c, b, flags) else: result = semDirectOp(c, n, flags) @@ -3407,22 +3420,25 @@ proc semExport(c: PContext, n: PNode): PNode = s = nextOverloadIter(o, c, a) +func containsArrGet(n: PNode): bool = + ## Analyses `n` for whether it is or could be the ``mArrGet`` magic. + case n.kind + of nkSymChoices: + for it in n.items: + if it.kind == nkSym and it.sym.magic == mArrGet: + result = true + break + of nkSym: + # can happen in rare cases + result = n.sym.magic == mArrGet + else: + result = false proc shouldBeBracketExpr(n: PNode): bool = assert n.kind in nkCallKinds let a = n[0] if a.kind in nkCallKinds: - let b = a[0] - if b.kind in nkSymChoices: - for i in 0.. 1 and isGeneric(c, n[1]): let b = n[0] - if b.kind in nkSymChoices: - for i in 0..