From b428da2cc2e7785ed9cb9a7efa1d2fa219603b59 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Sat, 13 May 2017 15:46:08 +0300 Subject: [PATCH] work-around for defining imported types with weak covariance --- compiler/semstmts.nim | 16 ++++++++++++++++ tests/typerel/tcovariancerules.nim | 11 +++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 4c1fbede31..10fc6fb6d6 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -867,6 +867,22 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = s.typ.sons[sonsLen(s.typ) - 1] = body if sfCovariant in s.flags: checkCovariantParamsUsages(s.typ) + # XXX: This is a temporary limitation: + # The codegen currently produces various failures with + # generic imported types that have fields, but we need + # the fields specified in order to detect weak covariance. + # The proper solution is to teach the codegen how to handle + # such types, because this would offer various interesting + # possibilities such as instantiating C++ generic types with + # garbage collected Nim types. + if sfImportc in s.flags: + var body = s.typ.lastSon + if body.kind == tyObject: + # erases all declared fields + body.n.sons = nil + + debug s.typ + echo s.typ[0].sym.flags popOwner(c) closeScope(c) diff --git a/tests/typerel/tcovariancerules.nim b/tests/typerel/tcovariancerules.nim index 7cd5d50669..dfe4cb941d 100644 --- a/tests/typerel/tcovariancerules.nim +++ b/tests/typerel/tcovariancerules.nim @@ -44,7 +44,7 @@ template acceptWithCovariance(x, otherwise): typed = skipElse(otherwise) type - Animal = object of TObject + Animal = object of RootObj x: string Dog = object of Animal @@ -302,12 +302,15 @@ reject wantsVarPointer2(pcat) {.emit: """ template struct FN { typedef void (*type)(T); }; -template struct ARR { typedef T type[2]; }; +template struct ARR { typedef T DataType[2]; DataType data; }; """.} type - MyPtr {.importcpp: "'0 *"} [out T] = distinct ptr T - MySeq {.importcpp: "ARR<'0>::type"} [out T] = object + MyPtr {.importcpp: "'0 *"} [out T] = object + + MySeq {.importcpp: "ARR<'0>", nodecl} [out T] = object + data: array[2, T] + MyAction {.importcpp: "FN<'0>::type"} [in T] = object var