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
21 changes: 21 additions & 0 deletions changelog/fix17630.dd
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Fix Issue 17630 - selective imports find symbols in private imports of other modules

Selectively importing a symbol should work only if the symbol
imported is defined or publicly imported in the imported module.
Due to a compiler bug, selectively importing a symbol works even
if the symbol is defined in a privately imported module in the
imported module.
-----------------------------------------------------------
//a.d
int bar;

//b.d
import a;

//c.d
import b : bar;
------------------------------------------------------------
The above code will now result in a deprecation message
which states that `bar` cannot be accessed since it is
privately imported in `b`.

3 changes: 2 additions & 1 deletion src/dmd/backend/global.d
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import core.stdc.stdint;

import dmd.backend.cdef;
import dmd.backend.cc;
import dmd.backend.cc : Symbol, block, Classsym, Blockx, code;
import dmd.backend.cc : Symbol, block, Classsym, Blockx;
import dmd.backend.code_x86 : code;
import dmd.backend.code;
import dmd.backend.el;
import dmd.backend.el : elem;
Expand Down
14 changes: 12 additions & 2 deletions src/dmd/dsymbolsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -1145,10 +1145,12 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
sc.protection = imp.protection;
for (size_t i = 0; i < imp.aliasdecls.dim; i++)
{
bool flag;
AliasDeclaration ad = imp.aliasdecls[i];
//printf("\tImport %s alias %s = %s, scope = %p\n", toPrettyChars(), aliases[i].toChars(), names[i].toChars(), ad._scope);
if (imp.mod.search(imp.loc, imp.names[i]))
if (imp.mod.search(imp.loc, imp.names[i]) /*, IgnorePrivateImports*/)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this comment here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When the deprecation is over, that argument should ne uncommented

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok.

{
flag = true;
ad.dsymbolSemantic(sc);
// If the import declaration is in non-root module,
// analysis of the aliased symbol is deferred.
Expand All @@ -1158,11 +1160,19 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
{
Dsymbol s = imp.mod.search_correct(imp.names[i]);
if (s)
imp.mod.error(imp.loc, "import `%s` not found, did you mean %s `%s`?", imp.names[i].toChars(), s.kind(), s.toChars());
imp.mod.error(imp.loc, "import `%s` not found, did you mean %s `%s`?", imp.names[i].toChars(), s.kind(), s.toPrettyChars());
else
imp.mod.error(imp.loc, "import `%s` not found", imp.names[i].toChars());
ad.type = Type.terror;
}

// Deprecated in 2018-01.
// Change to error in 2019-01 by deleteting the following 3 lines and uncommenting
// the IgnorePrivateImports parameter from above.
// @@@DEPRECATED_2019-01@@@.
Dsymbol s = imp.mod.search(imp.loc, imp.names[i], IgnorePrivateImports);
if (!s && flag)
.deprecation(imp.loc, "Symbol `%s` is not visible because it is privately imported", imp.names[i].toChars());
}
sc = sc.pop();
}
Expand Down
2 changes: 1 addition & 1 deletion src/dmd/gluelayer.d
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ else version (MARS)
public import dmd.backend.cc : block, Blockx, Symbol;
public import dmd.backend.type : type;
public import dmd.backend.el : elem;
public import dmd.backend.code : code;
public import dmd.backend.code_x86 : code;

extern (C++)
{
Expand Down
14 changes: 14 additions & 0 deletions test/fail_compilation/fail17630.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// REQUIRED_ARGS: -de
// EXTRA_SOURCES: imports/b17630.d
/*
TEST_OUTPUT:
---
fail_compilation/fail17630.d(12): Deprecation: Symbol `Erase` is not visible because it is privately imported
---
*/

void main()
{
import imports.a17630 : Erase;
assert(Erase == 2);
}
3 changes: 3 additions & 0 deletions test/fail_compilation/imports/a17630.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module a17630;

import b17630;
3 changes: 3 additions & 0 deletions test/fail_compilation/imports/b17630.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module b17630;

int Erase;