diff options
Diffstat (limited to 'compiler/semexprs.nim')
-rw-r--r-- | compiler/semexprs.nim | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 0e1c5e9d3..80e04ead4 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -178,7 +178,7 @@ proc checkConvertible(c: PContext, targetTyp: PType, src: PNode): TConvStatus = else: discard -proc isCastable(conf: ConfigRef; dst, src: PType): bool = +proc isCastable(c: PContext; dst, src: PType): bool = ## Checks whether the source type can be cast to the destination type. ## Casting is very unrestrictive; casts are allowed as long as ## castDest.size >= src.size, and typeAllowed(dst, skParam) @@ -193,6 +193,7 @@ proc isCastable(conf: ConfigRef; dst, src: PType): bool = return false if skipTypes(dst, abstractInst).kind == tyBuiltInTypeClass: return false + let conf = c.config if conf.selectedGC in {gcArc, gcOrc}: let d = skipTypes(dst, abstractInst) let s = skipTypes(src, abstractInst) @@ -210,7 +211,7 @@ proc isCastable(conf: ConfigRef; dst, src: PType): bool = result = false elif srcSize < 0: result = false - elif typeAllowed(dst, skParam) != nil: + elif typeAllowed(dst, skParam, c) != nil: result = false elif dst.kind == tyProc and dst.callConv == ccClosure: result = src.kind == tyProc and src.callConv == ccClosure @@ -338,7 +339,7 @@ proc semCast(c: PContext, n: PNode): PNode = let castedExpr = semExprWithType(c, n[1]) if tfHasMeta in targetType.flags: localError(c.config, n[0].info, "cannot cast to a non concrete type: '$1'" % $targetType) - if not isCastable(c.config, targetType, castedExpr.typ): + if not isCastable(c, targetType, castedExpr.typ): let tar = $targetType let alt = typeToString(targetType, preferDesc) let msg = if tar != alt: tar & "=" & alt else: tar @@ -794,7 +795,7 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode = if callee.kind notin {skProc, skFunc, skConverter, skConst} or callee.isGenericRoutine: return - if n.typ != nil and typeAllowed(n.typ, skConst) != nil: return + if n.typ != nil and typeAllowed(n.typ, skConst, c) != nil: return var call = newNodeIT(nkCall, n.info, n.typ) call.add(n[0]) @@ -962,9 +963,9 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = # t.sym != nil # sfAnon notin t.sym.flags # t.kind != tySequence(It is tyProc) - if typ.sym != nil and sfAnon notin typ.sym.flags and + if typ.sym != nil and sfAnon notin typ.sym.flags and typ.kind == tyProc: - msg.add(" = " & + msg.add(" = " & typeToString(typ, preferDesc)) localError(c.config, n.info, msg) return errorNode(c, n) @@ -1600,7 +1601,7 @@ proc takeImplicitAddr(c: PContext, n: PNode; isLent: bool): PNode = proc asgnToResultVar(c: PContext, n, le, ri: PNode) {.inline.} = if le.kind == nkHiddenDeref: var x = le[0] - if x.typ.kind in {tyVar, tyLent} and x.kind == nkSym and x.sym.kind == skResult: + if (x.typ.kind in {tyVar, tyLent} or isViewType(x.typ)) and x.kind == nkSym and x.sym.kind == skResult: n[0] = x # 'result[]' --> 'result' n[1] = takeImplicitAddr(c, ri, x.typ.kind == tyLent) x.typ.flags.incl tfVarIsPtr @@ -1732,7 +1733,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = if cmpTypes(c, lhs.typ, rhsTyp) in {isGeneric, isEqual}: internalAssert c.config, c.p.resultSym != nil # Make sure the type is valid for the result variable - typeAllowedCheck(c.config, n.info, rhsTyp, skResult) + typeAllowedCheck(c, n.info, rhsTyp, skResult) lhs.typ = rhsTyp c.p.resultSym.typ = rhsTyp c.p.owner.typ[0] = rhsTyp @@ -1825,7 +1826,9 @@ proc semYieldVarResult(c: PContext, n: PNode, restype: PType) = tupleConstr[i] = takeImplicitAddr(c, tupleConstr[i], e.kind == tyLent) else: localError(c.config, n[0].info, errXExpected, "tuple constructor") - else: discard + else: + if isViewType(t): + n[0] = takeImplicitAddr(c, n[0], false) proc semYield(c: PContext, n: PNode): PNode = result = n |