www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - 2.068.0 regression?

reply "sigod" <sigod.mail gmail.com> writes:
Consider this code:

```
struct Test
{
	string to;

	void test()
	{
		import core.time;

		auto value = ["to": to]; // Error: can't have associative array 
of void
	}
}

void main() {}
```

In 2.068.0 compilation fails. Works in 2.065 and 2.067.1.
Aug 19 2015
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Wednesday, 19 August 2015 at 21:26:34 UTC, sigod wrote:
 Consider this code:
Not a regression per se - core.time just introduced a new `to` function that is conflicting with your variable name because you imported core.time in a more local scope. You can just do ["to": this.to] to disambiguate the name.
Aug 19 2015
parent reply "sigod" <sigod.mail gmail.com> writes:
On Wednesday, 19 August 2015 at 21:32:17 UTC, Adam D. Ruppe wrote:
 On Wednesday, 19 August 2015 at 21:26:34 UTC, sigod wrote:
 Consider this code:
Not a regression per se - core.time just introduced a new `to` function that is conflicting with your variable name because you imported core.time in a more local scope. You can just do ["to": this.to] to disambiguate the name.
``` T to(string units, T, D)(D td) ``` But what compiler does with this function? How `void` appears in the error message? Why does it even picks this function? `to` has required argument, apparently it can't be called without one.
Aug 19 2015
parent reply "Dicebot" <public dicebot.lv> writes:
On Wednesday, 19 August 2015 at 21:56:22 UTC, sigod wrote:
 ```
 T to(string units, T, D)(D td)
 ```

 But what compiler does with this function? How `void` appears 
 in the error message?
There are no arguments used thus `to` is resolved as plain template symbol, not a function. Template that does not resolve to any valid entity is treated as if it had type 'void' in error messages, even if it is not technically true.
 Why does it even picks this function? `to` has required 
 argument, apparently it can't be called without one.
When you shadow some symbol with a new declaration in more "local" scope, it gets shadow completely, not just added to overload set. No matter what arguments are used only the new symbol will get used.
Aug 19 2015
parent reply "Dicebot" <public dicebot.lv> writes:
And yes, this is indeed regression but of a kind unavoidable with 
D module system so there isn't anything that can be done here but 
adjusting your code, sadly.
Aug 19 2015
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 08/20/2015 12:04 AM, Dicebot wrote:
 And yes, this is indeed regression but of a kind unavoidable with D
 module system so there isn't anything that can be done here but
 adjusting your code, sadly.
It's a bug.
Aug 19 2015
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08/19/2015 11:26 PM, sigod wrote:
 Consider this code:

 ```
 struct Test
 {
      string to;

      void test()
      {
          import core.time;

          auto value = ["to": to]; // Error: can't have associative array
 of void
      }
 }

 void main() {}
 ```

 In 2.068.0 compilation fails. Works in 2.065 and 2.067.1.
It's a bug in local imports. This is the ticket: https://issues.dlang.org/show_bug.cgi?id=10378
Aug 19 2015
parent reply "Dicebot" <public dicebot.lv> writes:
On Wednesday, 19 August 2015 at 22:33:23 UTC, Timon Gehr wrote:
 It's a bug in local imports. This is the ticket:
 https://issues.dlang.org/show_bug.cgi?id=10378
Seems to fit into existing shadowing semantics. If this is a bug we may need a new spec.
Aug 19 2015
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08/20/2015 01:06 AM, Dicebot wrote:
 On Wednesday, 19 August 2015 at 22:33:23 UTC, Timon Gehr wrote:
 It's a bug in local imports. This is the ticket:
 https://issues.dlang.org/show_bug.cgi?id=10378
Seems to fit into existing shadowing semantics.
There's no precedent for symbols shadowed by imports.
 If this is a bug we may need a new spec.
I believe local imports were first implemented without paying any attention to shadowing. I think the broken semantics implemented in DMD without a sufficient up-front design were then back-ported into the documentation at some point. This still happens too often. This is the JavaScript style of language design.
Aug 19 2015
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Wednesday, 19 August 2015 at 23:18:04 UTC, Timon Gehr wrote:
 On 08/20/2015 01:06 AM, Dicebot wrote:
 On Wednesday, 19 August 2015 at 22:33:23 UTC, Timon Gehr wrote:
 It's a bug in local imports. This is the ticket:
 https://issues.dlang.org/show_bug.cgi?id=10378
Seems to fit into existing shadowing semantics.
There's no precedent for symbols shadowed by imports.
 If this is a bug we may need a new spec.
I believe local imports were first implemented without paying any attention to shadowing. I think the broken semantics implemented in DMD without a sufficient up-front design were then back-ported into the documentation at some point. This still happens too often. This is the JavaScript style of language design.
import should NEVER shadow local symbols.
Aug 19 2015
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08/20/2015 01:20 AM, deadalnix wrote:
 On Wednesday, 19 August 2015 at 23:18:04 UTC, Timon Gehr wrote:
 On 08/20/2015 01:06 AM, Dicebot wrote:
 On Wednesday, 19 August 2015 at 22:33:23 UTC, Timon Gehr wrote:
 It's a bug in local imports. This is the ticket:
 https://issues.dlang.org/show_bug.cgi?id=10378
Seems to fit into existing shadowing semantics.
There's no precedent for symbols shadowed by imports.
 If this is a bug we may need a new spec.
I believe local imports were first implemented without paying any attention to shadowing. I think the broken semantics implemented in DMD without a sufficient up-front design were then back-ported into the documentation at some point. This still happens too often. This is the JavaScript style of language design.
import should NEVER shadow local symbols.
And yet for some reason this obviously broken behaviour is now documented as intended in the official language documentation. http://dlang.org/module.html, look for "Scoped Imports". "The imports are looked up to satisfy any unresolved symbols at that scope. Imported symbols may hide symbols from outer scopes." On that same page: "Modules offer several guarantees: [...] ● If a module C imports modules A and B, any modifications to B will not silently change code in C that is dependent on A."
Aug 19 2015
next sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Wednesday, 19 August 2015 at 23:29:26 UTC, Timon Gehr wrote:
 On 08/20/2015 01:20 AM, deadalnix wrote:
 On Wednesday, 19 August 2015 at 23:18:04 UTC, Timon Gehr wrote:
 On 08/20/2015 01:06 AM, Dicebot wrote:
 On Wednesday, 19 August 2015 at 22:33:23 UTC, Timon Gehr 
 wrote:
 It's a bug in local imports. This is the ticket:
 https://issues.dlang.org/show_bug.cgi?id=10378
Seems to fit into existing shadowing semantics.
There's no precedent for symbols shadowed by imports.
 If this is a bug we may need a new spec.
I believe local imports were first implemented without paying any attention to shadowing. I think the broken semantics implemented in DMD without a sufficient up-front design were then back-ported into the documentation at some point. This still happens too often. This is the JavaScript style of language design.
import should NEVER shadow local symbols.
And yet for some reason this obviously broken behaviour is now documented as intended in the official language documentation. http://dlang.org/module.html, look for "Scoped Imports". "The imports are looked up to satisfy any unresolved symbols at that scope. Imported symbols may hide symbols from outer scopes." On that same page: "Modules offer several guarantees: [...] ● If a module C imports modules A and B, any modifications to B will not silently change code in C that is dependent on A."
WTF are we backporting implementation madness in the spec rather than fixing it ?
Aug 19 2015
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 8/19/15 7:29 PM, Timon Gehr wrote:
 On 08/20/2015 01:20 AM, deadalnix wrote:
 On Wednesday, 19 August 2015 at 23:18:04 UTC, Timon Gehr wrote:
 On 08/20/2015 01:06 AM, Dicebot wrote:
 On Wednesday, 19 August 2015 at 22:33:23 UTC, Timon Gehr wrote:
 It's a bug in local imports. This is the ticket:
 https://issues.dlang.org/show_bug.cgi?id=10378
Seems to fit into existing shadowing semantics.
There's no precedent for symbols shadowed by imports.
 If this is a bug we may need a new spec.
I believe local imports were first implemented without paying any attention to shadowing. I think the broken semantics implemented in DMD without a sufficient up-front design were then back-ported into the documentation at some point. This still happens too often. This is the JavaScript style of language design.
import should NEVER shadow local symbols.
And yet for some reason this obviously broken behaviour is now documented as intended in the official language documentation. http://dlang.org/module.html, look for "Scoped Imports". "The imports are looked up to satisfy any unresolved symbols at that scope. Imported symbols may hide symbols from outer scopes." On that same page: "Modules offer several guarantees: [...] ● If a module C imports modules A and B, any modifications to B will not silently change code in C that is dependent on A."
We need to fix the implementation. We can't promote imports that hide local symbols. -- Andrei
Aug 19 2015
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08/20/2015 05:55 AM, Andrei Alexandrescu wrote:
 We need to fix the implementation. We can't promote imports that hide
 local symbols. -- Andrei
Great! We should probably agree on the precise new semantics first though. The current viable proposals in the bug report are: - The symbols declared in the module at any scope nesting depth hide the symbols in the local import, but all symbols in imports in enclosing scopes overload against each other. - No hiding of imported symbols by less deeply nested ones; enclosing scopes are treated the same way as imports. I'm not sure what's better. I think Scala does something similar to the second proposal.
Aug 20 2015
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 08/20/2015 12:46 PM, Timon Gehr wrote:
 - No hiding of imported symbols by less deeply nested ones; enclosing
 scopes are treated the same way as imports.
(for overloading, not for lookup.)
Aug 20 2015
prev sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Thursday, 20 August 2015 at 10:46:18 UTC, Timon Gehr wrote:
 On 08/20/2015 05:55 AM, Andrei Alexandrescu wrote:
 We need to fix the implementation. We can't promote imports 
 that hide
 local symbols. -- Andrei
Great! We should probably agree on the precise new semantics first though. The current viable proposals in the bug report are: - The symbols declared in the module at any scope nesting depth hide the symbols in the local import, but all symbols in imports in enclosing scopes overload against each other. - No hiding of imported symbols by less deeply nested ones; enclosing scopes are treated the same way as imports. I'm not sure what's better. I think Scala does something similar to the second proposal.
Yes, I'd advocate for the first one for 2 reasons: - User has full control over module symbol, but may not have the same over imported ones. We'd like to avoid hijacking local symbols from imports as much as possible. - We'd like to be able to lazy import as much as possible. If import can hijack, then it is necessary to process them at least enough to be able to do first level lookup, even if the import is not used.
Aug 20 2015
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08/20/2015 10:06 PM, deadalnix wrote:
 On Thursday, 20 August 2015 at 10:46:18 UTC, Timon Gehr wrote:
 On 08/20/2015 05:55 AM, Andrei Alexandrescu wrote:
 We need to fix the implementation. We can't promote imports that hide
 local symbols. -- Andrei
Great! We should probably agree on the precise new semantics first though. The current viable proposals in the bug report are: - The symbols declared in the module at any scope nesting depth hide the symbols in the local import, but all symbols in imports in enclosing scopes overload against each other. - No hiding of imported symbols by less deeply nested ones; enclosing scopes are treated the same way as imports. I'm not sure what's better. I think Scala does something similar to the second proposal.
Yes, I'd advocate for the first one for 2 reasons: - User has full control over module symbol, but may not have the same over imported ones. We'd like to avoid hijacking local symbols from imports as much as possible.
The second proposal allows for strictly fewer cases of hijacking (it also avoid those cases where a local symbol in an outer scope hides a locally imported symbol), and the usual cross-scope overload resolution semantics would apply. (So even if there is a name clash, it usually wouldn't matter for functions and/or templates.) I do think it can be confusing if a symbol in a less deeply nested scope can hide a symbol imported in a more deeply nested scope.
   - We'd like to be able to lazy import as much as possible. If import
 can hijack,
I assume what you mean is if it can cause a compiler error due to ambiguity in cross-scope overloading.
 then it is necessary to process them at least enough to be
 able to do first level lookup, even if the import is not used.
Makes sense. So the scenario we are looking at here is basically local imports in aggregate scopes, such that the imported symbols are not used in method signatures? Are those common enough to improve performance sufficiently to justify influencing the choice of best semantics? (There are 0 cases in my own code.)
Aug 20 2015
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Thursday, 20 August 2015 at 20:27:58 UTC, Timon Gehr wrote:
   - We'd like to be able to lazy import as much as possible. 
 If import
 can hijack,
I assume what you mean is if it can cause a compiler error due to ambiguity in cross-scope overloading.
Yes, but eve if it doesn't, one need to do a lookup in the imports to check, which is undesirable.
 then it is necessary to process them at least enough to be
 able to do first level lookup, even if the import is not used.
Makes sense. So the scenario we are looking at here is basically local imports in aggregate scopes, such that the imported symbols are not used in method signatures? Are those common enough to improve performance sufficiently to justify influencing the choice of best semantics? (There are 0 cases in my own code.)
On the long run, it is typical for code to have unused imports, especially since we have no linter to warn about them.
Aug 20 2015
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08/20/2015 11:00 PM, deadalnix wrote:
 On Thursday, 20 August 2015 at 20:27:58 UTC, Timon Gehr wrote:
   - We'd like to be able to lazy import as much as possible. If import
 can hijack,
I assume what you mean is if it can cause a compiler error due to ambiguity in cross-scope overloading.
Yes, but eve if it doesn't, one need to do a lookup in the imports to check, which is undesirable.
 then it is necessary to process them at least enough to be
 able to do first level lookup, even if the import is not used.
Makes sense. So the scenario we are looking at here is basically local imports in aggregate scopes, such that the imported symbols are not used in method signatures? Are those common enough to improve performance sufficiently to justify influencing the choice of best semantics? (There are 0 cases in my own code.)
On the long run, it is typical for code to have unused imports, especially since we have no linter to warn about them.
I think this is a very weak point, so I didn't consider it. Even if an import is unused, if there is at least one lookup of some identifier from any different module, it will have to be analyzed. Also, in the long run, we'll have the linter. Given a front end, it's exceedingly simple to create.
Aug 20 2015
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08/21/2015 03:51 AM, Timon Gehr wrote:
 Even if an import is unused, if there is at least one lookup of some
 identifier from any different module, it will have to be analyzed.
(But not /transitively/. I think this is where the gains of lazy imports come from.)
Aug 20 2015
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 8/20/15 9:53 PM, Timon Gehr wrote:
 On 08/21/2015 03:51 AM, Timon Gehr wrote:
 Even if an import is unused, if there is at least one lookup of some
 identifier from any different module, it will have to be analyzed.
(But not /transitively/. I think this is where the gains of lazy imports come from.)
Yah, that's exactly right. -- Andrei
Aug 21 2015