Prevention of UFCS hijacking

Maxim Fomin maxim at maxim-fomin.ru
Tue Aug 27 11:40:16 PDT 2013


On Tuesday, 27 August 2013 at 18:02:27 UTC, Andrej Mitrovic wrote:
> I've run into a bit of an issue with UFCS today, take a look at 
> the
> reduced test-case:
>
> -----
> import std.conv;
>
> class Label
> {
>     // @property string text() {  }
>     // @property void text(string nText) {  }
> }
>
> void main()
> {
>     auto label = new Label;
>
>     label.text = "My label";
>     assert(label.text == "My label");  // fails at runtime
> }
> -----
>
> Because of the UFCS feature std.conv.text is called even though 
> I
> expected compilation to fail since I've commented out the .text
> properties in my class.

But commenting out "text" property is not order to compiler to 
ignore all UFCS involving "text". What commenting out has to do 
with UFCS?

> This is a problem since some of my classes might have a .text 
> field,
> while others might not. If the user imports std.conv he could 
> easily
> end up calling std.conv.text by mistake when a class object 
> doesn't
> implement such a property.

Then classes should implement member to disable UFCS hijacktion. 
If not, this is an allowance for such name hijacktion. This is by 
design.

> Has anyone else run into this sort of issue? I'm wondering 
> whether we
> should have some language support (through __traits, @disable, 
> or
> something else), to enable writing APIs which are safer to use, 
> where
> you can't by mistake call a UFCS function like that if there's 
> an
> equally named function introduced in another derived class.

@disable is a way to block this feature

> ---
>
> Btw, why exactly is the following allowed to compile?:
>
> -----
> import std.conv;
> import std.stdio;
>
> struct S { }
>
> void main()
> {
>     S s;
>     writeln(s.text = "foo");
> }
> -----
>
> This translates into std.conv.text(s, "foo"). I'm not a fan,
> especially since 'text' is not a @property. But we've already 
> reached
> the consensus that all functions can be called like properties 
> (for
> some reason..), so I guess it's too late to change this.

Let's start from basics:

writeln = 42;

and this is also by design.


More information about the Digitalmars-d mailing list