summary refs log tree commit diff stats
path: root/compiler/semexprs.nim
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2014-03-19 02:52:48 +0200
committerZahary Karadjov <zahary@gmail.com>2014-03-20 01:16:50 +0200
commit4b7655fd10d81ea50d0af41152df07ec21b05232 (patch)
treea437c41d515806717de7737d065098a91e13a3b7 /compiler/semexprs.nim
parenta66d059accc9db4c376fdb1220ee2c5ca8daf311 (diff)
downloadNim-4b7655fd10d81ea50d0af41152df07ec21b05232.tar.gz
reference implementation of a vector swizzle library
This also provides the initial steps towards support for type class "filtered" type inference
fixes an "ordinal type expected" ICE, related to the use of static params
Diffstat (limited to 'compiler/semexprs.nim')
-rw-r--r--compiler/semexprs.nim43
1 files changed, 29 insertions, 14 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index a6e2eaa23..b8c4f3297 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -121,6 +121,8 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
       return n
   of skType:
     markUsed(n, s)
+    if s.typ.kind == tyStatic and s.typ.n != nil:
+      return s.typ.n
     result = newSymNode(s, n.info)
     result.typ = makeTypeDesc(c, s.typ)
   else:
@@ -191,15 +193,35 @@ proc isCastable(dst, src: PType): bool =
 proc isSymChoice(n: PNode): bool {.inline.} =
   result = n.kind in nkSymChoices
 
+proc maybeLiftType(t: var PType, c: PContext, info: TLineInfo) =
+  # XXX: liftParamType started to perform addDecl
+  # we could do that instead in semTypeNode by snooping for added
+  # gnrc. params, then it won't be necessary to open a new scope here
+  openScope(c)
+  var lifted = liftParamType(c, skType, newNodeI(nkArgList, info),
+                         t, ":anon", info)
+  closeScope(c)
+  if lifted != nil: t = lifted
+
 proc semConv(c: PContext, n: PNode): PNode =
   if sonsLen(n) != 2:
     localError(n.info, errConvNeedsOneArg)
     return n
+
   result = newNodeI(nkConv, n.info)
-  result.typ = semTypeNode(c, n.sons[0], nil).skipTypes({tyGenericInst})
-  addSon(result, copyTree(n.sons[0]))
-  addSon(result, semExprWithType(c, n.sons[1]))
-  var op = result.sons[1]
+  var targetType = semTypeNode(c, n.sons[0], nil)
+  maybeLiftType(targetType, c, n[0].info)
+  result.addSon copyTree(n.sons[0])
+  var op = semExprWithType(c, n.sons[1])
+  
+  if targetType.isMetaType:
+    let final = inferWithMetatype(c, targetType, op, true)
+    result.addSon final
+    result.typ = final.typ
+    return
+
+  result.typ = targetType
+  addSon(result, op)
   
   if not isSymChoice(op):
     let status = checkConvertible(c, result.typ, op.typ)
@@ -221,7 +243,7 @@ proc semConv(c: PContext, n: PNode): PNode =
     for i in countup(0, sonsLen(op) - 1):
       let it = op.sons[i]
       let status = checkConvertible(c, result.typ, it.typ)
-      if status == convOK:
+      if status in {convOK, convNotNeedeed}:
         markUsed(n, it.sym)
         markIndirect(c, it.sym)
         return it
@@ -325,14 +347,7 @@ proc isOpImpl(c: PContext, n: PNode): PNode =
                                         tfIterator notin t.flags))
   else:
     var t2 = n[2].typ.skipTypes({tyTypeDesc})
-    # XXX: liftParamType started to perform addDecl
-    # we could do that instead in semTypeNode by snooping for added
-    # gnrc. params, then it won't be necessary to open a new scope here
-    openScope(c)
-    let lifted = liftParamType(c, skType, newNodeI(nkArgList, n.info),
-                               t2, ":anon", n.info)
-    closeScope(c)
-    if lifted != nil: t2 = lifted
+    maybeLiftType(t2, c, n.info)
     var m: TCandidate
     initCandidate(c, m, t2)
     let match = typeRel(m, t2, t1) != isNone
@@ -1202,7 +1217,7 @@ proc semAsgn(c: PContext, n: PNode): PNode =
         if lhsIsResult: {efAllowDestructor} else: {})
     if lhsIsResult:
       n.typ = enforceVoidContext
-      if resultTypeIsInferrable(lhs.sym.typ):
+      if c.p.owner.kind != skMacro and resultTypeIsInferrable(lhs.sym.typ):
         if cmpTypes(c, lhs.typ, rhs.typ) == isGeneric:
           internalAssert c.p.resultSym != nil
           lhs.typ = rhs.typ