Bug 21539 – [REG 2.084] symbols from import inside template mixin cannot be accessed using module scope dot operator

Status
RESOLVED
Resolution
INVALID
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2021-01-10T14:46:17Z
Last change time
2021-01-22T13:41:05Z
Keywords
pull
Assigned to
No Owner
Creator
Steven Schveighoffer

Comments

Comment #0 by schveiguy — 2021-01-10T14:46:17Z
Normally, the dot operator finds symbols at module scope, even when imported from other modules. However, if the import is done inside a template mixin, the dot operator does not find the symbol. Regression since 2.084 example: mixin template T() { import std.stdio; alias X = .File; } mixin T; Error: undefined identifier `File` in module `onlineapp`
Comment #1 by bugzilla — 2021-01-11T07:18:50Z
This gets a little curiouser: extern (C++, Nspace) { enum Sid = 3; } mixin template T() { alias A = .Sid; // ok as expected alias B = Nspace.Sid; // ok as expected import std.stdio; alias X = .File; // fails } mixin T; as the looking up of a member of Nspace should follow exactly the same rules as looking up a name in a module.
Comment #2 by bugzilla — 2021-01-11T07:35:39Z
Looks like: https://github.com/dlang/dmd/pull/9078 is the cause. Rewriting the example to: import std.stdio; mixin template T() { alias X = .File; } mixin T; and it works.
Comment #3 by razvan.nitu1305 — 2021-01-20T14:37:34Z
Imports inside mixin templates should be seen as local to the mixin template. Even if it is inserted at module level, it doesn't change the fact that its visibility is restricted to the mixin unit. By using the dot operator, you are bypassing the import inside the mixin and this is intended behavior. All you have to do is not use the dot and the code will compile. As a good practice mixin templates should be self-contained. I think that this bug report is invalid.
Comment #4 by schveiguy — 2021-01-20T15:03:33Z
At first, I thought I had an easy counter-case, but this also doesn't work: void main() { import std.stdio; .writeln("hello"); // error, no symbol writeln } And this case is not a regression (at least back to 2.060). I understand the point here, but I need something that mixes in the symbols AS IF they were in the module. A mixin string works, but I need it to be a template to avoid a complete mess in documentation and code maintenance. As you probably are aware, the real case is not this simple. What I'm trying to do is migrate a phobos module from a standard module to one that is configurable based on a template parameter. I would like the entire module to be copied as-is, just inside a mixin template (with certain pieces using the template parameter instead). Any usage of the dot operator is going to be troublesome (and of course, the reason it's used is not on a whim). The problem is, I don't have a universal substitute for the dot operator in this case. I need something that says "at mixin scope" If I use: mixin template T() { import std.stdio; alias X = T.File; } It doesn't work. I may have to remove all . scope operators in Phobos to get this to work (and instead use FQN).
Comment #5 by razvan.nitu1305 — 2021-01-21T07:30:15Z
(In reply to Steven Schveighoffer from comment #4) > If I use: > > mixin template T() > { > import std.stdio; > alias X = T.File; > } > > It doesn't work. > > I may have to remove all . scope operators in Phobos to get this to work > (and instead use FQN). Another option would be to simply alias the global imports. For example, this works: mixin template T() { import std.stdio; alias Y = std.stdio; aliax X = Y.File; } I know that this would require to alias every single import, but it is close in spirit with the sample that you have given. Is it ok to close this as INVALID?
Comment #6 by dlang-bot — 2021-01-21T16:56:30Z
@BorisCarvajal created dlang/dmd pull request #12145 "Fix Issue 21539 - [REG 2.084] symbols from import inside template mix…" fixing this issue: - Fix Issue 21539 - [REG 2.084] symbols from import inside template mixin cannot be accessed using module scope dot operator https://github.com/dlang/dmd/pull/12145
Comment #7 by schveiguy — 2021-01-22T13:41:05Z
I think Razvan is right, and unfortunately, we can't break code that might depend on this quirk. And it is consistent with imports inside functions.