Skip to content

Commit

Permalink
Merge pull request #3388 from 9rnsr/fix12242
Browse files Browse the repository at this point in the history
Issue 12242 - conflict error with public imports
  • Loading branch information
AndrewEdwards committed Jul 29, 2014
2 parents 02c6399 + 0a3d275 commit 79a406d
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 22 deletions.
80 changes: 58 additions & 22 deletions src/dsymbol.c
Expand Up @@ -915,7 +915,11 @@ Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags)
*/
Dsymbol *s2 = ss->search(loc, ident, ss->isModule() ? IgnorePrivateMembers : IgnoreNone);
if (!s)
{
s = s2;
if (s && s->isOverloadSet())
a = mergeOverloadSet(a, s);
}
else if (s2 && s != s2)
{
if (s->toAlias() == s2->toAlias() ||
Expand Down Expand Up @@ -956,28 +960,10 @@ Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags)
/* If both s2 and s are overloadable (though we only
* need to check s once)
*/
if (s2->isOverloadable() && (a || s->isOverloadable()))
if ((s2->isOverloadSet() || s2->isOverloadable()) &&
(a || s->isOverloadable()))
{
if (!a)
{
a = new OverloadSet(s->ident);
a->parent = this;
}
/* Don't add to a[] if s2 is alias of previous sym
*/
for (size_t j = 0; j < a->a.dim; j++)
{
Dsymbol *s3 = a->a[j];
if (s2->toAlias() == s3->toAlias())
{
if (s3->isDeprecated() ||
s2->prot() > s3->prot() && s2->prot() != PROTnone)
a->a[j] = s2;
goto Lcontinue;
}
}
a->push(s2);
Lcontinue:
a = mergeOverloadSet(a, s2);
continue;
}
if (flags & IgnoreAmbiguous) // if return NULL on ambiguity
Expand All @@ -996,7 +982,8 @@ Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags)
*/
if (a)
{
a->push(s);
if (!s->isOverloadSet())
a = mergeOverloadSet(a, s);
s = a;
}

Expand All @@ -1012,6 +999,55 @@ Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags)
return s1;
}

OverloadSet *ScopeDsymbol::mergeOverloadSet(OverloadSet *os, Dsymbol *s)
{
if (!os)
{
os = new OverloadSet(s->ident);
os->parent = this;
}
if (OverloadSet *os2 = s->isOverloadSet())
{
// Merge the cross-module overload set 'os2' into 'os'
if (os->a.dim == 0)
{
os->a.setDim(os2->a.dim);
memcpy(os->a.tdata(), os2->a.tdata(), sizeof(os->a[0]) * os2->a.dim);
}
else
{
for (size_t i = 0; i < os2->a.dim; i++)
{
os = mergeOverloadSet(os, os2->a[i]);
}
}
}
else
{
assert(s->isOverloadable());

/* Don't add to os[] if s is alias of previous sym
*/
for (size_t j = 0; j < os->a.dim; j++)
{
Dsymbol *s2 = os->a[j];
if (s->toAlias() == s2->toAlias())
{
if (s2->isDeprecated() ||
s->prot() > s2->prot() && s->prot() != PROTnone)
{
os->a[j] = s;
}
goto Lcontinue;
}
}
os->push(s);
Lcontinue:
;
}
return os;
}

void ScopeDsymbol::importScope(Dsymbol *s, PROT protection)
{
//printf("%s->ScopeDsymbol::importScope(%s, %d)\n", toChars(), s->toChars(), protection);
Expand Down
1 change: 1 addition & 0 deletions src/dsymbol.h
Expand Up @@ -291,6 +291,7 @@ class ScopeDsymbol : public Dsymbol
ScopeDsymbol(Identifier *id);
Dsymbol *syntaxCopy(Dsymbol *s);
Dsymbol *search(Loc loc, Identifier *ident, int flags = IgnoreNone);
OverloadSet *mergeOverloadSet(OverloadSet *os, Dsymbol *s);
void importScope(Dsymbol *s, PROT protection);
bool isforwardRef();
static void multiplyDefined(Loc loc, Dsymbol *s1, Dsymbol *s2);
Expand Down
17 changes: 17 additions & 0 deletions test/compilable/imports/imp12242a.d
@@ -0,0 +1,17 @@
module imports.imp12242a;

public:
import imports.imp12242a1; // std.string
import imports.imp12242a2; // std.algorithm


private mixin template MixTmp(T, int x)
{
template foo(U) if (is(U == T))
{
enum foo = x;
}
}

mixin MixTmp!(int, 1);
mixin MixTmp!(long, 2);
8 changes: 8 additions & 0 deletions test/compilable/imports/imp12242a1.d
@@ -0,0 +1,8 @@
module imports.imp12242a1;

// std.string.strip
int stripA(C)(C[] str) @safe pure
if (is(immutable C == immutable char))
{
return 1;
}
11 changes: 11 additions & 0 deletions test/compilable/imports/imp12242a2.d
@@ -0,0 +1,11 @@
module imports.imp12242a2;

// std.algorithm.strip
auto stripA(R, E)(R range, E element)
{
return 2;
}
auto stripA(alias pred, R)(R range)
{
return 3;
}
17 changes: 17 additions & 0 deletions test/compilable/imports/imp12242b.d
@@ -0,0 +1,17 @@
module imports.imp12242b;

public:
import imports.imp12242b1; // std.string
import imports.imp12242b2; // std.algorithm


private mixin template MixTmp(T, int x)
{
template foo(U) if (is(U == T))
{
enum foo = x;
}
}

mixin MixTmp!(float, 3);
mixin MixTmp!(real, 4);
8 changes: 8 additions & 0 deletions test/compilable/imports/imp12242b1.d
@@ -0,0 +1,8 @@
module imports.imp12242b1;

// std.string.strip
int stripB(C)(C[] str) @safe pure
if (is(immutable C == immutable char))
{
return 1;
}
11 changes: 11 additions & 0 deletions test/compilable/imports/imp12242b2.d
@@ -0,0 +1,11 @@
module imports.imp12242b2;

// std.algorithm.strip
auto stripB(R, E)(R range, E element)
{
return 2;
}
auto stripB(alias pred, R)(R range)
{
return 3;
}
26 changes: 26 additions & 0 deletions test/compilable/testimport12242.d
@@ -0,0 +1,26 @@
// PERMUTE_ARGS:

module testimport12242;

import imports.imp12242a; // test // stripA == OverloadSet
import imports.imp12242a1; // std.string // stripA == template

import imports.imp12242b1; // std.string // stripB == template
import imports.imp12242b; // test // stripB == OverloadSet

void main()
{
static assert(stripA(" af ") == 1);
static assert(" af ".stripA() == 1); // UFCS (1)
static assert(" af ".stripA == 1); // UFCS (2)

static assert(stripB(" af ") == 1);
static assert(" af ".stripB() == 1); // UFCS (1)
static assert(" af ".stripB == 1); // UFCS (2)


static assert(foo!int == 1);
static assert(foo!long == 2);
static assert(foo!float == 3);
static assert(foo!real == 4);
}

0 comments on commit 79a406d

Please sign in to comment.