December 14, 2020
On 12/13/20 4:54 PM, kdevel wrote:
> On Friday, 11 December 2020 at 01:38:44 UTC, Adam D. Ruppe wrote:
> 
> [...]
> 
>> With a normal import, the module name is the only thing actually added to the scope. Everything in that module is found by walking the import chains after not finding it locally (unless you use `static import` which means it does not add it to the chain).
> 
> Just 'implemented' the following bug:
> 
> ~~~
> import std.conv;
> 
> class B {
> }
> 
> class D : B {
>     string text;
> }
> 
> void main ()
> {
>     B b = new D;
>     string s = b.text;
> }
> ~~~
> 
> Due to UFCS std.conv.text grabs the object. Only a `static import`
> or a selective import would reveal the problem during compile time.

This is expected behavior. B does not have a member named "text", and so it looks for a UFCS function to call and finds one.

Note that a static import means you have to use the FQN to call text (but text is perfectly fine via UFCS). However, a selective import would still call text as expected.

-Steve
December 14, 2020
On Monday, 14 December 2020 at 16:21:56 UTC, Steven Schveighoffer wrote:
[...]
>> Just 'implemented' the following bug:
>> 
>> ~~~
>> import std.conv;
>> 
>> class B {
>> }
>> 
>> class D : B {
>>     string text;
>> }
>> 
>> void main ()
>> {
>>     B b = new D;
>>     string s = b.text;
>> }
>> ~~~
>> 
>> Due to UFCS std.conv.text grabs the object. Only a `static import`
>> or a selective import would reveal the problem during compile time.
>
> This is expected behavior.

Sure. In the original code the missing downcast was not that easily
discernible.

> B does not have a member named "text", and so it looks for a UFCS function to call and finds one.
>
> Note that a static import means you have to use the FQN to call text (but text is perfectly fine via UFCS). However, a selective import would still call text as expected.

The original code accessed only std.conv.to. A selective import
of `to` would have complained and helped to spot the error:

q.d(13): Error: no property text for type q.B, perhaps import std.conv; is needed?

BTW: Most of the time dmd's guess is accurate.
December 14, 2020
On 12/14/20 12:59 PM, kdevel wrote:
> On Monday, 14 December 2020 at 16:21:56 UTC, Steven Schveighoffer wrote:

>> This is expected behavior.
> 
> Sure. In the original code the missing downcast was not that easily
> discernible.

I understand. There is sometimes confusion when a ufcs "member" is found. I've seen a lot of weird things like this.

But the compiler can only tell what you want from the code you write, it can't look at the intentions behind it. Especially when you make a mistake.

I've had countless times where I reach for something.to!somethingelse and I forgot to import std.conv, but I've happened to import std.datetime (which has a similar ufcs `to` function). And the error message is always confusing.

I don't think this is fixable. You just have to live with it. It's unfortunate that it compiles, and doesn't give an error. "Best effort" functions like text that *always* compile can be hard to diagnose when you call them by accident.

>> B does not have a member named "text", and so it looks for a UFCS function to call and finds one.
>>
>> Note that a static import means you have to use the FQN to call text (but text is perfectly fine via UFCS). However, a selective import would still call text as expected.
> 
> The original code accessed only std.conv.to. A selective import
> of `to` would have complained and helped to spot the error:

OK, I thought you meant a selective import of std.conv.text.

> 
> q.d(13): Error: no property text for type q.B, perhaps import std.conv; is needed?
> 
> BTW: Most of the time dmd's guess is accurate.

Those suggestions are hard-coded into the compiler, and I sometimes wish they were more comprehensive. But I don't see any future in which the compiler is going to suggest "maybe you meant to downcast to type D". It just can't see what you were thinking.

-Steve
December 14, 2020
On Monday, 14 December 2020 at 18:54:58 UTC, Steven Schveighoffer wrote:

> But the compiler can only tell what you want from the code you write, it can't look at the intentions behind it. Especially when you make a mistake.

Until AI takes over this is clearly the case. I just wonder if selective
imports are worth the additional typing. They obviously prevent the
namespace pollution with greedy function templates like text.

> I've had countless times where I reach for something.to!somethingelse and I forgot to import std.conv, but I've happened to import std.datetime (which has a similar ufcs `to` function).

Thanks for this warning ;-)

1 2
Next ›   Last »