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