summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2016-08-31 02:17:14 +0300
committerZahary Karadjov <zahary@gmail.com>2017-03-24 16:59:47 +0200
commitcbf66e99a85551021d768aa81858f9d7b6f55d6f (patch)
treed7cef4972c87575a98deb57a9ddd73b22ef5080b /compiler
parent52b241fd5703034066d9c9f3c3d514162c2c809e (diff)
downloadNim-cbf66e99a85551021d768aa81858f9d7b6f55d6f.tar.gz
Working test cases for the sophisticated matrix library example from the manual
Fixed the dot operator when used within return types (see tgenericdotrettype)
Fixed the matching of generic concepts aliases used with the implicit generics style
Diffstat (limited to 'compiler')
-rw-r--r--compiler/semexprs.nim28
-rw-r--r--compiler/semtypes.nim10
-rw-r--r--compiler/semtypinst.nim2
-rw-r--r--compiler/sigmatch.nim46
-rw-r--r--compiler/types.nim18
-rw-r--r--compiler/vmgen.nim3
6 files changed, 67 insertions, 40 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index b5e9e6dc4..9d0f4aef1 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -911,8 +911,7 @@ proc makeDeref(n: PNode): PNode =
     t = skipTypes(baseTyp, {tyGenericInst, tyAlias})
 
 const
-  tyTypeParamsHolders = {tyGenericInst, tyCompositeTypeClass,
-                         tyUserTypeClass, tyUserTypeClassInst}
+  tyTypeParamsHolders = {tyGenericInst, tyCompositeTypeClass}
   tyDotOpTransparent = {tyVar, tyPtr, tyRef, tyAlias}
 
 proc readTypeParameter(c: PContext, typ: PType,
@@ -1107,6 +1106,23 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
   var ty = n.sons[0].typ
   var f: PSym = nil
   result = nil
+
+  template tryReadingGenericParam(t: PType) =
+    case t.kind
+    of tyTypeParamsHolders:
+      return readTypeParameter(c, t, i, n.info)
+    of tyUserTypeClasses:
+      if t.isResolvedUserTypeClass:
+        return readTypeParameter(c, t, i, n.info)
+      else:
+        n.typ = makeTypeFromExpr(c, copyTree(n))
+        return n
+    of tyGenericParam:
+      n.typ = makeTypeFromExpr(c, copyTree(n))
+      return n
+    else:
+      discard
+
   if isTypeExpr(n.sons[0]) or (ty.kind == tyTypeDesc and ty.base.kind != tyNone):
     if ty.kind == tyTypeDesc: ty = ty.base
     ty = ty.skipTypes(tyDotOpTransparent)
@@ -1124,8 +1140,6 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
         markUsed(n.info, f, c.graph.usageSym)
         styleCheckUse(n.info, f)
         return
-    of tyTypeParamsHolders:
-      return readTypeParameter(c, ty, i, n.info)
     of tyObject, tyTuple:
       if ty.n != nil and ty.n.kind == nkRecList:
         let field = lookupInRecord(ty.n, i)
@@ -1134,8 +1148,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
           n.typ.n = copyTree(n)
           return n
     else:
-      # echo "TYPE FIELD ACCESS"
-      # debug ty
+      tryReadingGenericParam(ty)
       return
     # XXX: This is probably not relevant any more
     # reset to prevent 'nil' bug: see "tests/reject/tenumitems.nim":
@@ -1178,8 +1191,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
   # we didn't find any field, let's look for a generic param
   if result == nil:
     let t = n.sons[0].typ.skipTypes(tyDotOpTransparent)
-    if t.kind in tyTypeParamsHolders:
-      result = readTypeParameter(c, t, i, n.info)
+    tryReadingGenericParam(t)
 
 proc dotTransformation(c: PContext, n: PNode): PNode =
   if isSymChoice(n.sons[1]):
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 204641b74..42ffaa5fa 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -845,9 +845,9 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
 
     for i in 0 .. paramType.sonsLen - 2:
       if paramType.sons[i].kind == tyStatic:
-        var x = copyNode(ast.emptyNode)
-        x.typ = paramType.sons[i]
-        result.rawAddSon makeTypeFromExpr(c, x) # aka 'tyUnknown'
+        var staticCopy = paramType.sons[i].exactReplica
+        staticCopy.flags.incl tfInferrableStatic
+        result.rawAddSon staticCopy
       else:
         result.rawAddSon newTypeS(tyAnything, c)
 
@@ -891,7 +891,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
                                           allowMetaTypes = true)
       result = liftingWalk(expanded, true)
 
-  of tyUserTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot:
+  of tyUserTypeClasses, tyBuiltInTypeClass, tyAnd, tyOr, tyNot:
     result = addImplicitGeneric(copyType(paramType, getCurrOwner(c), true))
 
   of tyGenericParam:
@@ -1357,6 +1357,8 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
     else: result = semGeneric(c, n, s, prev)
   of nkDotExpr:
     let typeExpr = semExpr(c, n)
+    if typeExpr.typ.kind == tyFromExpr:
+      return typeExpr.typ
     if typeExpr.typ.kind != tyTypeDesc:
       localError(n.info, errTypeExpected)
       result = errorType(c)
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim
index ac8a5ff82..fddcc7a24 100644
--- a/compiler/semtypinst.nim
+++ b/compiler/semtypinst.nim
@@ -404,6 +404,8 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
   case t.kind
   of tyGenericInvocation:
     result = handleGenericInvocation(cl, t)
+    if result.lastSon.kind == tyUserTypeClass:
+      result.kind = tyUserTypeClassInst
 
   of tyGenericBody:
     localError(cl.info, errCannotInstantiateX, typeToString(t))
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 5a6f4e015..a40f8ee66 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -613,26 +613,34 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
       template paramSym(kind): untyped =
         newSym(kind, typeParamName, Concept.sym, Concept.sym.info)
 
-      case typ.kind
-      of tyStatic:
-        param = paramSym skConst
-        param.typ = typ.exactReplica
-        if typ.n == nil:
-          param.typ.flags.incl tfInferrableStatic
+      block addTypeParam:
+        for prev in typeParams:
+          if prev[1].id == typ.id:
+            param = paramSym prev[0].kind
+            param.typ = prev[0].typ
+            break addTypeParam
+
+        case typ.kind
+        of tyStatic:
+          param = paramSym skConst
+          param.typ = typ.exactReplica
+          if typ.n == nil:
+            param.typ.flags.incl tfInferrableStatic
+          else:
+            param.ast = typ.n
+        of tyUnknown:
+          param = paramSym skVar
+          param.typ = typ.exactReplica
         else:
-          param.ast = typ.n
-      of tyUnknown:
-        param = paramSym skVar
-        param.typ = typ.exactReplica
-      else:
-        param = paramSym skType
-        param.typ = if typ.isMetaType:
-                      c.newTypeWithSons(tyInferred, @[typ])
-                    else:
-                      makeTypeDesc(c, typ)
+          param = paramSym skType
+          param.typ = if typ.isMetaType:
+                        c.newTypeWithSons(tyInferred, @[typ])
+                      else:
+                        makeTypeDesc(c, typ)
 
+        typeParams.safeAdd((param, typ))
+      
       addDecl(c, param)
-      typeParams.safeAdd((param, typ))
 
   for param in Concept.n[0]:
     var
@@ -682,7 +690,7 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
       diagnostics.add msg
    
   var checkedBody = c.semTryExpr(c, body.copyTree, flags)
-  
+
   if collectDiagnostics:
     writelnHook = oldWriteHook
     for msg in diagnostics: m.diagnostics.safeAdd msg
@@ -696,7 +704,7 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
     put(m.bindings, p[1], p[0].typ)
 
   if ff.kind == tyUserTypeClassInst:
-    result = generateTypeInstance(c, m.bindings, ff.sym.info, ff)
+    result = generateTypeInstance(c, m.bindings, Concept.sym.info, ff)
   else:
     result = copyType(ff, ff.owner, true)
 
diff --git a/compiler/types.nim b/compiler/types.nim
index 65eb6de61..3f84548a1 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -183,7 +183,7 @@ proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter,
   if result: return
   if not containsOrIncl(marker, t.id):
     case t.kind
-    of tyGenericInst, tyGenericBody, tyAlias:
+    of tyGenericInst, tyGenericBody, tyAlias, tyInferred:
       result = iterOverTypeAux(marker, lastSon(t), iter, closure)
     else:
       for i in countup(0, sonsLen(t) - 1):
@@ -1320,6 +1320,9 @@ proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt =
     if result < 0: return
     if a < maxAlign: a = maxAlign
     result = align(result, a)
+  of tyInferred:
+    if typ.len > 1:
+      result = computeSizeAux(typ.lastSon, a)
   of tyGenericInst, tyDistinct, tyGenericBody, tyAlias:
     result = computeSizeAux(lastSon(typ), a)
   of tyTypeClasses:
@@ -1351,18 +1354,17 @@ proc getSize(typ: PType): BiggestInt =
   if result < 0: internalError("getSize: " & $typ.kind)
 
 proc containsGenericTypeIter(t: PType, closure: RootRef): bool =
-  if t.kind == tyStatic:
+  case t.kind
+  of tyStatic:
     return t.n == nil
-
-  if t.kind == tyTypeDesc:
+  of tyTypeDesc:
     if t.base.kind == tyNone: return true
     if containsGenericTypeIter(t.base, closure): return true
     return false
-
-  if t.kind in GenericTypes + tyTypeClasses + {tyFromExpr}:
+  of GenericTypes + tyTypeClasses + {tyFromExpr}:
     return true
-
-  return false
+  else:
+    return false
 
 proc containsGenericType*(t: PType): bool =
   result = iterOverType(t, containsGenericTypeIter, nil)
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index 125fe8ae0..c7d9be48c 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -1678,7 +1678,8 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
       elif sfImportc in s.flags: c.importcSym(n.info, s)
       genLit(c, n, dest)
     of skConst:
-      gen(c, s.ast, dest)
+      let constVal = if s.ast != nil: s.ast else: s.typ.n
+      gen(c, constVal, dest)
     of skEnumField:
       if dest < 0: dest = c.getTemp(n.typ)
       if s.position >= low(int16) and s.position <= high(int16):
='n655' href='#n655'>655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846