D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 5123 - Cannot assign null to a class with 'alias this'
Summary: Cannot assign null to a class with 'alias this'
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: Other All
: P2 normal
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-10-26 13:34 UTC by osa8aso
Modified: 2011-10-23 04:15 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description osa8aso 2010-10-26 13:34:54 UTC
If class has 'alias this' for a struct member, attempt to assign null to a class instance fails:
------
struct Foo {}
class Bar {
    Foo foo_;
    alias foo_ this;
}
void main() {
    Bar a;
    a = null;
}
------
aliasthis1.d(8): Error: cannot implicitly convert expression (null) of type void* to Foo
Comment 1 bearophile_hugs 2010-10-26 13:43:16 UTC
Here alias this is doing its work of "let's pretend" a Bar instance is a Foo instance. To solve this problem you may need something more refined than alias this, something that allows a partial aliasing. I don't think it's an easy thing to do.

A related program shows a different outcome:

struct Foo {}
class Bar {
    Foo foo_;
    alias foo_ this;
}
void main() {
    Bar a;
    //a = null;
    Foo f;
    a = f; // Access violation!
}
Comment 2 osa8aso 2010-10-26 15:17:04 UTC
> A related program shows a different outcome:
>     Bar a;
>     Foo f;
>     a = f; // Access violation!

This is expected. 'a' is an uninitialized, and attempt to assign to a Foo part of null instance causes access violation. This is no different from

  Bar a;
  a.foo_ = Foo();

"Partial" assignment of Foo to a valid Bar instance is fine and works as expected:
-----
struct Foo { int x; }
class Bar {
    Foo foo_;
    alias foo_ this;
    int y;
}
void main() {
    Bar a = new Bar;
    a.x = 1;
    a.y = 42;
    assert( a.foo_.x == 1 && a.y == 42 );
    a = Foo( 2 );
    assert( a.foo_.x == 2 && a.y == 42 );
}
-----

My problem is only with special treatment of null: I want to nullify local reference to a Bar instance, not change Bar or Foo inside it.
Comment 3 bearophile_hugs 2010-10-26 15:36:13 UTC
(In reply to comment #2)
> This is expected. 'a' is an uninitialized, and attempt to assign to a Foo part
> of null instance causes access violation. This is no different from
> 
>   Bar a;
>   a.foo_ = Foo();

Right, sorry for the noise.
Comment 4 Kenji Hara 2011-10-23 04:15:28 UTC
This issue was already fixed by bug 2943.

And this was related to bug 6630.