From 21ce7b2af4163b2513f3c6cbf2f52929d684bcb3 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Mon, 19 Jun 2017 22:45:15 +0300 Subject: [PATCH] Fix #5888 --- compiler/semexprs.nim | 2 +- compiler/semstmts.nim | 2 ++ compiler/semtypes.nim | 5 ++++- tests/concepts/t5888.nim | 26 ++++++++++++++++++++++++++ tests/concepts/t5888lib/ca.nim | 4 ++++ tests/concepts/t5888lib/opt.nim | 6 ++++++ 6 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 tests/concepts/t5888.nim create mode 100644 tests/concepts/t5888lib/ca.nim create mode 100644 tests/concepts/t5888lib/opt.nim diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 7c4fcd881..8169e359a 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1129,9 +1129,9 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = # reset to prevent 'nil' bug: see "tests/reject/tenumitems.nim": ty = n.sons[0].typ return nil - ty = skipTypes(ty, {tyGenericInst, tyVar, tyPtr, tyRef, tyAlias}) if ty.kind in tyUserTypeClasses and ty.isResolvedUserTypeClass: ty = ty.lastSon + ty = skipTypes(ty, {tyGenericInst, tyVar, tyPtr, tyRef, tyAlias}) while tfBorrowDot in ty.flags: ty = ty.skipTypes({tyDistinct}) var check: PNode = nil if ty.kind == tyObject: diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 56435bbf1..ee4203299 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -467,6 +467,8 @@ proc hasEmpty(typ: PType): bool = proc makeDeref(n: PNode): PNode = var t = skipTypes(n.typ, {tyGenericInst, tyAlias}) + if t.kind in tyUserTypeClasses and t.isResolvedUserTypeClass: + t = t.lastSon result = n if t.kind == tyVar: result = newNodeIT(nkHiddenDeref, n.info, t.sons[0]) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 4c7786f61..0c2dd2f96 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -1415,7 +1415,10 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result = errorType(c) else: result = typeExpr.typ.base - if result.isMetaType: + if result.isMetaType and + result.kind != tyUserTypeClass: + # the dot expression may refer to a concept type in + # a different module. allow a normal alias then. let preprocessed = semGenericStmt(c, n) result = makeTypeFromExpr(c, preprocessed.copyTree) else: diff --git a/tests/concepts/t5888.nim b/tests/concepts/t5888.nim new file mode 100644 index 000000000..dbbab8c4c --- /dev/null +++ b/tests/concepts/t5888.nim @@ -0,0 +1,26 @@ +discard """ +output: ''' +true +true +true +f +0 +''' +""" + +import t5888lib/ca, t5888lib/opt + +type LocalCA = ca.CA + +proc f(c: CA) = + echo "f" + echo c.x + +var o = new(Opt) + +echo o is CA +echo o is LocalCA +echo o is ca.CA + +o.f() + diff --git a/tests/concepts/t5888lib/ca.nim b/tests/concepts/t5888lib/ca.nim new file mode 100644 index 000000000..4a811f797 --- /dev/null +++ b/tests/concepts/t5888lib/ca.nim @@ -0,0 +1,4 @@ +type + CA* = concept c + c.x is int + diff --git a/tests/concepts/t5888lib/opt.nim b/tests/concepts/t5888lib/opt.nim new file mode 100644 index 000000000..65d16addc --- /dev/null +++ b/tests/concepts/t5888lib/opt.nim @@ -0,0 +1,6 @@ +import ca + +type + Opt* = object + x*: int +