www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - opCast fails when this is null.

reply Mike Wey <mike-wey example.com> writes:
The following code runs correctly when compiled with ldc (1.4.0) but 
fails with an assert error when compiled with dmd (2.076 and ldc 1.2.0)


```
class A
{

}

class B
{
	T opCast(T)()
	{
		return this;
	}
}

void main()
{
	A a = null;
	B b = null;

	auto c = cast(Object)a;
	auto d = cast(Object)b; // Fails with: 
core.exception.AssertError test.d(8): null this
}
```

How would you write an opCast that would handle this case correctly?

Testing if this is null at the start of the opCast doesn't help since 
the assert is thrown before that happens.
Making the opCast static leaves us without access to this, which would 
be needed in my use case.
We can't relay on ufcs since the rewrite to opCast doesn't happen when 
it's not a member function.

-- 
Mike Wey
Oct 28
next sibling parent Basile B. <b2.temp gmx.com> writes:
On Saturday, 28 October 2017 at 13:24:49 UTC, Mike Wey wrote:
 The following code runs correctly when compiled with ldc 
 (1.4.0) but fails with an assert error when compiled with dmd 
 (2.076 and ldc 1.2.0)


 ```
 class A
 {

 }

 class B
 {
 	T opCast(T)()
 	{
 		return this;
 	}
 }

 void main()
 {
 	A a = null;
 	B b = null;

 	auto c = cast(Object)a;
 	auto d = cast(Object)b; // Fails with: 
 core.exception.AssertError test.d(8): null this
 }
 ```

 How would you write an opCast that would handle this case 
 correctly?
Compiler change is required. This doesn't happen in -release mode. The assert is automatically generated by the compiler. It could be disabled, as done here for ctors and dtors https://github.com/dlang/dmd/pull/6982
Oct 28
prev sibling parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Saturday, 28 October 2017 at 13:24:49 UTC, Mike Wey wrote:
 The following code runs correctly when compiled with ldc 
 (1.4.0) but fails with an assert error when compiled with dmd 
 (2.076 and ldc 1.2.0)


 ```
 class A
 {

 }

 class B
 {
 	T opCast(T)()
 	{
 		return this;
 	}
 }

 void main()
 {
 	A a = null;
 	B b = null;

 	auto c = cast(Object)a;
 	auto d = cast(Object)b; // Fails with: 
 core.exception.AssertError test.d(8): null this
 }
 ```

 How would you write an opCast that would handle this case 
 correctly?

 Testing if this is null at the start of the opCast doesn't help 
 since the assert is thrown before that happens.
 Making the opCast static leaves us without access to this, 
 which would be needed in my use case.
 We can't relay on ufcs since the rewrite to opCast doesn't 
 happen when it's not a member function.
As Basile mentioned, this is compiler sticking checks in behind your back. The reason it works on new LDC is because #6982 was cherry picked to LDC (1.3?) before it was merged into dmd (not sure what version, I though it was 2.076, but it might have been one of the betas of 2.077) because I needed it for DCompute to build without -release. The only course is to use recent compilers.
Oct 28
parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Saturday, 28 October 2017 at 14:19:01 UTC, Nicholas Wilson 
wrote:
 As Basile mentioned, this is compiler sticking checks in behind 
 your back.
 The reason it works on new LDC is because #6982 was cherry 
 picked to LDC (1.3?) before it was merged into dmd (not sure 
 what version, I though it was 2.076, but it might have been one 
 of the betas of 2.077) because I needed it for DCompute to 
 build without -release.

 The only course is to use recent compilers.
Erm, 2.077 is not a thing yet. Does it work with 2.076.1?
Oct 28
parent Mike Wey <mike-wey example.com> writes:
On 28-10-17 16:22, Nicholas Wilson wrote:
 On Saturday, 28 October 2017 at 14:19:01 UTC, Nicholas Wilson wrote:
 As Basile mentioned, this is compiler sticking checks in behind your 
 back.
 The reason it works on new LDC is because #6982 was cherry picked to 
 LDC (1.3?) before it was merged into dmd (not sure what version, I 
 though it was 2.076, but it might have been one of the betas of 2.077) 
 because I needed it for DCompute to build without -release.

 The only course is to use recent compilers.
Erm, 2.077 is not a thing yet. Does it work with 2.076.1?
No, it does work with the 2.077 beta tough. -- Mike Wey
Oct 28