Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/dmd/access.d
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,20 @@ extern (C++) bool symbolIsVisible(Dsymbol origin, Dsymbol s)
extern (C++) bool symbolIsVisible(Scope *sc, Dsymbol s)
{
s = mostVisibleOverload(s);
return checkSymbolAccess(sc, s);
}

/**
* Check if a symbol is visible from a given scope without taking
* into account the most visible overload.
*
* Params:
* sc = lookup scope
* s = symbol to check for visibility
* Returns: true if s is visible by origin
*/
extern (C++) bool checkSymbolAccess(Scope *sc, Dsymbol s)
{
final switch (s.prot().kind)
{
case Prot.Kind.undefined: return true;
Expand Down
2 changes: 1 addition & 1 deletion src/dmd/dtemplate.d
Original file line number Diff line number Diff line change
Expand Up @@ -2766,7 +2766,7 @@ void functionResolve(Match* m, Dsymbol dstart, Loc loc, Scope* sc, Objects* tiar
if (auto td = s.isTemplateDeclaration())
return applyTemplate(td);
return 0;
});
}, sc);

//printf("td_best = %p, m.lastf = %p\n", td_best, m.lastf);
if (td_best && ti_best && m.count == 1)
Expand Down
38 changes: 33 additions & 5 deletions src/dmd/func.d
Original file line number Diff line number Diff line change
Expand Up @@ -2326,11 +2326,17 @@ extern (C++) Expression addInvariant(Loc loc, Scope* sc, AggregateDeclaration ad
/***************************************************
* Visit each overloaded function/template in turn, and call dg(s) on it.
* Exit when no more, or dg(s) returns nonzero.
*
* Params:
* fstart = symbol to start from
* dg = the delegate to be called on the overload
* sc = the initial scope from the calling context
*
* Returns:
* ==0 continue
* !=0 done
*/
extern (D) int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg)
extern (D) int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg, Scope* sc = null)
{
Dsymbol next;
for (Dsymbol d = fstart; d; d = next)
Expand All @@ -2339,7 +2345,22 @@ extern (D) int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg)
{
if (od.hasOverloads)
{
if (int r = overloadApply(od.aliassym, dg))
/* The scope is needed here to check whether a function in
an overload set was added by means of a private alias (or a
selective import). If the scope where the alias is created
is imported somewhere, the overload set is visible, but the private
alias is not.
*/
if (sc)
{
import dmd.access : checkSymbolAccess;
if (checkSymbolAccess(sc, od))
{
if (int r = overloadApply(od.aliassym, dg, sc))
return r;
}
}
else if (int r = overloadApply(od.aliassym, dg, sc))
return r;
}
else
Expand All @@ -2353,7 +2374,7 @@ extern (D) int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg)
{
if (fa.hasOverloads)
{
if (int r = overloadApply(fa.funcalias, dg))
if (int r = overloadApply(fa.funcalias, dg, sc))
return r;
}
else if (auto fd = fa.toAliasFunc())
Expand All @@ -2370,7 +2391,14 @@ extern (D) int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg)
}
else if (auto ad = d.isAliasDeclaration())
{
next = ad.toAlias();
if (sc)
{
import dmd.access : checkSymbolAccess;
if (checkSymbolAccess(sc, ad))
next = ad.toAlias();
}
else
next = ad.toAlias();
if (next == ad)
break;
if (next == fstart)
Expand Down Expand Up @@ -2631,7 +2659,7 @@ extern (C++) FuncDeclaration resolveFuncCall(Loc loc, Scope* sc, Dsymbol s,
if (num > 0)
.errorSupplemental(loc, "... (%d more, -v to show) ...", num);
return 1; // stop iterating
});
}, sc);
}
}
else if (m.nextf)
Expand Down
15 changes: 15 additions & 0 deletions test/fail_compilation/fail18243.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail18243.d(14): Error: none of the overloads of `isNaN` are callable using argument types `!()(float)`
---
*/

module fail18243;

import imports.a18243;

void main()
{
bool b = isNaN(float.nan);
}
5 changes: 5 additions & 0 deletions test/fail_compilation/imports/a18243.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module a18243;

import std.math : isNaN;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Selective imports creatingalias in the current scope is really an annoyance, and violates the principle of least surprise. I wish we could change that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a small project on its own which will propagate cascade changes throughout a large number of components.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although I agree that the current state is hackish and messy.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last time I checked with Walter, it was by design. Maybe that changed since. If you have any way to find out, it would be appreciated.


public bool isNaN() { return false; }