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
20 changes: 20 additions & 0 deletions changelog/fqn-bypass-deprecation.dd
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Deprecate a case of using fully-qualified names to bypass imports

Since v2.084 it is no longer possible to bypass private imports by using fully-qualified names,
this was deprecated in v2.071 but when fully-qualified names are used as a type
(vs an expression) the code is accepted without any warning.

Starting with this release the compiler will now properly deprecate the previous omitted case.

The issue is best described in the following example:

```d
import std.algorithm;

// deprecated in v2.071, error since v2.084
auto a = std.range.Take!(int[]); // Error: undefined identifier `range` in package `std`...

// now it's deprecated, will be error from v2.106
std.range.Take!(int[]) s;

````
1 change: 1 addition & 0 deletions src/dmd/todt.d
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import dmd.errors;
import dmd.expression;
import dmd.func;
import dmd.globals;
import dmd.glue;
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this a result of fixing the bug?

Copy link
Member Author

Choose a reason for hiding this comment

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

Well, it's to fix a instance of the bug in DMD.

Copy link
Member Author

Choose a reason for hiding this comment

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

There are two lines a little below:

alias toSymbol = dmd.tocsym.toSymbol;
alias toSymbol = dmd.glue.toSymbol;

dmd.glue is not imported but is working because of the bug.

import dmd.init;
import dmd.mtype;
import dmd.target;
Expand Down
20 changes: 16 additions & 4 deletions src/dmd/typesem.d
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import dmd.declaration;
import dmd.denum;
import dmd.dimport;
import dmd.dmangle;
import dmd.dmodule : Module;
import dmd.dmodule;
import dmd.dscope;
import dmd.dstruct;
import dmd.dsymbol;
Expand Down Expand Up @@ -255,10 +255,22 @@ private void resolveHelper(TypeQualified mt, const ref Loc loc, Scope* sc, Dsymb
int flags = t is null ? SearchLocalsOnly : IgnorePrivateImports;

Dsymbol sm = s.searchX(loc, sc, id, flags);
if (sm && !(sc.flags & SCOPE.ignoresymbolvisibility) && !symbolIsVisible(sc, sm))
if (sm)
{
.error(loc, "`%s` is not visible from module `%s`", sm.toPrettyChars(), sc._module.toChars());
sm = null;
if (!(sc.flags & SCOPE.ignoresymbolvisibility) && !symbolIsVisible(sc, sm))
{
.error(loc, "`%s` is not visible from module `%s`", sm.toPrettyChars(), sc._module.toChars());
sm = null;
}
// Same check as in Expression.semanticY(DotIdExp)
else if (sm.isPackage() && checkAccess(sc, cast(Package)sm))
{
// @@@DEPRECATED_2.096@@@
// Should be an error in 2.106. Just remove the deprecation call
// and uncomment the null assignment
deprecation(loc, "%s %s is not accessible here, perhaps add 'static import %s;'", sm.kind(), sm.toPrettyChars(), sm.toPrettyChars());
Copy link
Contributor

Choose a reason for hiding this comment

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

here does not sound very professional. I suggest replacing it with the module name.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, is the static really necessary?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is the exact message of the original deprecation.

Copy link
Contributor

Choose a reason for hiding this comment

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

Fair enough.

//sm = null;
}
}
if (global.errors != errorsave)
{
Expand Down
8 changes: 7 additions & 1 deletion test/compilable/extra-files/serenity7190/core/Controller.d
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ class Controller {
enum _s_pkg = __traits(parent, __traits(parent, __traits(parent, T))).stringof["package ".length .. $];

enum _s_model = T.stringof[0 .. $-`Controller`.length] ~ `Model`;

import serenity7190.core.Model;
// expands to "import example7190.models.HomeModel;"
mixin(q{import } ~ _s_pkg ~ q{.models.} ~ _s_model ~ q{;});

// "enum _ = is(example7190.models.HomeModel.HomeModel : serenity7190.core.Model.Model);"
mixin(q{enum _ = is(} ~ _s_pkg ~ q{.models.} ~ _s_model ~ q{.} ~ _s_model ~ q{ : serenity7190.core.Model.Model);});
}
}
}
3 changes: 0 additions & 3 deletions test/compilable/ice10598.d

This file was deleted.

10 changes: 10 additions & 0 deletions test/fail_compilation/ice10598.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// REQUIRED_ARGS: -de
// EXTRA_SOURCES: imports/ice10598a.d imports/ice10598b.d
/* TEST_OUTPUT:
---
fail_compilation/imports/ice10598a.d(5): Deprecation: module imports.ice10598b is not accessible here, perhaps add 'static import imports.ice10598b;'
fail_compilation/imports/ice10598a.d(5): Deprecation: module imports.ice10598b is not accessible here, perhaps add 'static import imports.ice10598b;'
---
*/

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

alias T = int;
11 changes: 11 additions & 0 deletions test/fail_compilation/test21651.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// REQUIRED_ARGS: -de
// EXTRA_SOURCES: imports/test21651b.d
/* TEST_OUTPUT:
---
fail_compilation/test21651.d(11): Deprecation: module imports.test21651b is not accessible here, perhaps add 'static import imports.test21651b;'
---
*/

module imports.test21651;

imports.test21651b.T a;