nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.59k stars 1.47k forks source link

Type unification merges aliases for generic types with pointers for cpp backend #18876

Open zacharycarter opened 3 years ago

zacharycarter commented 3 years ago

Let's say you have some C++ code like:

typedef struct AliasOne_T *AliasOne;
typedef struct AliasTwo_T *AliasTwo;

std::vector<AliasOne> foo() {
  std::vector<AliasOne> f(1);
  return f;
};

std::vector<AliasTwo> bar() {
  std::vector<AliasTwo> b(1);
  return b;
};

And you want to wrap it with Nim.

You'd define some type definitions and proc signatures like:

type
  AliasOne {.importcpp.} = pointer
  AliasTwo {.importcpp.} = pointer

proc foo(): StdVector[AliasOne] {.importcpp.}
proc bar(): StdVector[AliasTwo] {.importcpp.}

What happens during compilation is the two alias type gets merged since they're both just a pointer to an opaque type, and you end up with only the type for the first used symbol in the generated C++ code.

So instead of seeing:

typedef std::vector<VkImage> TY__SomeRandomSuffix;
typedef std::vector<VkImageView> TY__SomeOtherRandomSuffix;

in the generated cpp source, you will only see something like:

typedef std::vector<VkImage> TY__SomeRandomSuffix;

And if you reference VkImageView first instead of VkImage you'd see the reverse - the alias for the VkImageView vector would be present but not the one for the VkImage vector.

This causes the generated C++ to fail to compile, and means one has to resort to hacks like {.emit.} which produces other side effects - like now there's the need to define the std::vector interface for each aliased type in Nim.

Issue is blocking my Vulkan renderer / game which you can see some of the WIP code for here: https://github.com/zacharycarter/FRAG/blob/master/src/fragpkg/app.nim#L52-L56 - in fact this is the section of code I'm blocked from progressing further on (barring resorting to emit).

I tested this and reproduced it on 1.4.8 and 1.5.1

Nim Compiler Version 1.5.1 [Windows: amd64]
Compiled at 2021-09-21
Copyright (c) 2006-2021 by Andreas Rumpf

git hash: 928ea6bb4c0cc791f1b81e55dbebd14d5c6a7315
active boot switches: -d:release
metagn commented 1 year ago

Related? #11797

metagn commented 5 days ago

Since #24313 distinct should maybe be usable here