Deprecate use of private variables from other modules#6676
Deprecate use of private variables from other modules#6676dlang-bot merged 3 commits intodlang:masterfrom
Conversation
mathias-lang-sociomantic
left a comment
There was a problem hiding this comment.
Needs test and release notes entry
src/ddmd/dimport.d
Outdated
| { | ||
| // This deprecation should turn into an error as soon as possible | ||
| if (importedSymbol.prot().kind == PROTprivate) | ||
| mod.deprecation(loc, "member '%s' is private", names[i].toChars()); |
There was a problem hiding this comment.
I'd rephrase as something like "Accessing private member FQN is deprecated"
There was a problem hiding this comment.
How does "module $module member $name is not accessible because it is private". I think having the word "deprecated" in the message is redundant since the phrase starts with "Deprecation: ".
There was a problem hiding this comment.
Sounds good 👍
145c14b to
b37d7c1
Compare
|
@mathias-lang-sociomantic I've never done a release entry. Could you guide me with the process of doing it? Thanks |
b37d7c1 to
7052cba
Compare
|
Any ideas on how to solve the continous-integration/jenkins error in vibe.d ? I see that the deprecation message causes some linking errors and I think that vibe.d should be updated to not use/import private members from other modules |
No need to worry, these linker errors are not caused by your pull request, see #6682 (comment) |
|
Shouldn't the mechanism for bug34 catch this - or am I misremembering this morning and that only affects protection for non-local imports? Also what about protected and package? |
|
@ibuclaw I don't think that protected and package have anything to do with this PR. anyway, how do we move forward from here? |
|
If they suffer from the same bug, then they must be fixed also. |
There was a problem hiding this comment.
-
I think the fix should be in access.d, not where you currently have it.
-
Consider the following example for fail15896:
import imp15896 : publicbar, privatebar, packagebar;
int func()
{
publicbar += 1;
privatebar += 1;
packagebar +=1;
return 0;
}
This should throw a compile-time error where marked with NG below:
int bar = 4;
public ref int publicbar() { return bar; } // OK
private ref int privatebar() { return bar; } // NG
package ref int packagebar() { return bar; } // NG
Therefore this PR should also ensure the same behaviour for variables:
public int publicbar = 4; // OK
private int privatebar = 4; // OK (but should be NG)
package int packagebar = 4; // OK (but should be NG)
|
@ibuclaw That is what this PR does for private members. I think that package should be the subject of a different PR. |
|
It's the same bug, so they should be fixed together. |
|
@MartinNowak should decide on this. Do we fix all in one deprecation shot, or do we stagger fixes? |
|
@RazvanN7 please rebase |
src/ddmd/dimport.d
Outdated
| if (importedSymbol) | ||
| { | ||
| // This deprecation should turn into an error as soon as possible | ||
| if (importedSymbol.prot().kind == PROTprivate) |
There was a problem hiding this comment.
I think it would be better if you used one of these functions.
Lines 481 to 525 in 8d6efa5
There was a problem hiding this comment.
Probably
if (!symbolIsVisible(sc, importedSymbol) { error; }
|
Thanks for your pull request, @RazvanN7! We are looking forward to reviewing it, and you should be hearing from a maintainer soon. Some tips to help speed things up:
Bear in mind that large or tricky changes may require multiple rounds of review and revision. Please see CONTRIBUTING.md for more information. Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. |
1443839 to
40ca250
Compare
|
@ibuclaw @mathias-lang-sociomantic I rebased and updated the code. Is this cool now? |
changelog/private.dd
Outdated
| imported private members were visible from other modules. This | ||
| represents a severe violation of the private keyword specification. | ||
| At this point the use of selectively imported private members has | ||
| been deprecated and should be transformed into an error as soon |
There was a problem hiding this comment.
Then again the wording in general could be improved.
There was a problem hiding this comment.
Proposed wordsmithing:
$(LINK2 $ (ROOT_DIR)spec/attribute.html#visibility_attributes, The specification states) that aprivatemember is visible only from within the same module. Prior to this release, due to a bug, some importedprivatemembers were visible from other modules, violating the specification. Beginning with this release, accessing saidprivatemembers from outside the module in which they are declared will result in a deprecation message which has been scheduled to be changed to an error in approximately 1 year.
There was a problem hiding this comment.
Thanks. I copy-pasted your words.
src/dmd/dsymbolsem.d
Outdated
| { | ||
| import dmd.access : symbolIsVisible; | ||
| if (!symbolIsVisible(sc, importedSymbol)) | ||
| imp.mod.deprecation(imp.loc, "member '%s' is not accessible", imp.names[i].toChars()); |
There was a problem hiding this comment.
Please add the following comments to make it easier to follow up on changing it to an error.
// @@@DEPRECATED_2018-01@@@
// Deprecation for 1 year after which this should be changed to an errorThere was a problem hiding this comment.
It was deprecated in 2018-01. It will be changed to an error in 2019-01. I read the comment as the date is was deprecated, not the date it should be changed to an error.
There was a problem hiding this comment.
That's not how we use this pattern at Phobos. The string is intended to be greppable in the future, i.e. you can do grep "@@@DEPRECATED_2019" for everything that needs maintenance action in 2019 and grep "@@@DEPRECATED_2019_01" for everything within a specific month.
There was a problem hiding this comment.
That doesn't seem right to me, but I'll play along. It probably needs to be disambiguated somehow. Please offer @RazvanN7 a suggestion so we can get this merged.
There was a problem hiding this comment.
Well it's the existing practice to document deprecations, see e.g. https://github.com/wilzbach/phobos/blob/complex/std/datetime/timezone.d#L145
How else are you going to find them? I already did -> Just change to 2018 -> 2019
|
Is there a bug report for this? |
|
@JinShil There was a bug report which closed when I fixed the issue to issue an error. Later when the PR was reverted so that the error could be transformed into a deprecation the bug report was no longer opened. It's this one : https://issues.dlang.org/show_bug.cgi?id=15896. If this PR is merged then we will be ok. |
60a6d7b to
01d934e
Compare
01d934e to
7b556cb
Compare
MartinNowak
left a comment
There was a problem hiding this comment.
Please don't merge before I reviewed this.
|
I don't quite follow the action in BlackEdder/ggplotd#45, seems like noone figured out why the compiler runs into an infinite loop. Clearly this is not allowed alias T = int;
alias T = T;and so import std.stdio : writeln;
alias writeln = writeln;
void main()
{
writeln("Hello");
}should print an error about writeln aliasing itself, but it currently compiles. Unfortunately there is no explanation for the infinite loop introduced with this PR. I can reproduce an ICE for the following similar case. import std.stdio : writeln;
import bar;
alias writeln = writeln; // <- should error, as the selectively imported writeln already is an alias
alias writeln = bar.writeln; // OK, overload set of selectively imported writeln and bar.writeln
void main()
{
writeln();
}This is the profile I get from the inifite loop in the compiler with this PR and testing ggplotd. |
There was a problem hiding this comment.
Looks OKish, only just found the other half in #7760, please fix the infinite loop though.
changelog/private.dd
Outdated
| @@ -0,0 +1,3 @@ | |||
| Deprecate the use of private selectively imported members | |||
|
|
|||
| $(LINK2 $(ROOT_DIR)spec/attribute.html#visibility_attributes, The specification states) that a private member is visible only from within the same module. Prior to this release, due to a bug, some imported private members were visible from other modules, violating the specification. Beginning with this release, accessing said private members from outside the module in which they are declared will result in a deprecation message which has been scheduled to be changed to an error in approximately 1 year. | |||
There was a problem hiding this comment.
s/some imported private members/private selective imports/
Also just mention that it has been deprecated, we have a general schedule for deprecations (6 months), but deviate from that when it seems too disturbing.
test/fail_compilation/fail15896.d
Outdated
| /* | ||
| TEST_OUTPUT: | ||
| --- | ||
| fail_compilation/fail15896.d(11): Deprecation: module `imports.imp15896` member `thebar` is not accessible |
There was a problem hiding this comment.
s/accessible/visible/
Accessibility is the old protection scheme that will soon be removed.
Also check the other visibility messages, they should be more sth. like X of mod M is not visible from mod N or so.
src/dmd/dsymbolsem.d
Outdated
| 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]) /*, IgnorePrivateImports*/) | ||
| Dsymbol importedSymbol = imp.mod.search(imp.loc, imp.names[i] /*, IgnorePrivateImports */); |
There was a problem hiding this comment.
The comment was added with #7760.
We should at some point change the logic from pulling out a symbol and then checking it's visibility, to passing the visibility level to search and reduce it with according to import protection (like a funnel).
This would also be necessary to fix package import pkg.common;, but requires quite some changes and partial order of visibility.
|
@MartinNowak The infinte loop introduced by this PR in ggplotd is due to the function |
|
@MartinNowak @ibuclaw anything else to do here? |
|
Restarting Jenkins due to dlang/ci#151 |
|
That usually doesn't help. Often you need to give Jenkins a git commit sha to reload the config - though in this case it might work... |
But you did call it in a situation where it wasn't previously called, that counts as introducing a bug ;). @RazvanN7 I think the way forward here is very clear and simple, make import std.stdio : writeln;
alias writeln = writeln;an error (maybe even without deprecation as it seems extremely rare in commited code). The reason why should fix this in advance is because overload sets are rather complex, and this looks like a plausible syntax to combine the selectively imported I'll try to work on a PR later today, but at latest for the 2.079.0 beta on 2018-02-14, so that we don't release with that bug. |
To clarify this, by design, hitting replay on Jenkins checks out the same repo versions that were used last time. This does only apply to those repositories for which we use Jenkin's internal checkout mechanism. |
48bee80 to
b662e2a
Compare
|
(closed and reopened for Semaphore to know about this PR) |
|
@MartinNowak applied your comments to the changelog and fixed a few other nits in the changelog message. |
|
wrote #7930 to fix issue with alias X=X making compiler hang |
Since #6660 (the work of the devil) was reverted, this PR implements the same feature except this time a deprecation message is issued and not an error