Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
March 10, 2015 2.067 Beta: Behavior of enum and ref changed | ||||
---|---|---|---|---|
| ||||
Hi, following coding raises a compiler error with the beta of 2.067. Is this error intended or not? It is working if I change first line of main to: ulong bits; enum Bits: ulong { none = 0 } bool hasBit(ref ulong rBits, ulong rBit) { return cast(bool)(rBits & rBit); } void main() { Bits bits; hasBit(bits, Bits.none); } function app.hasBit (ref ulong rBits, ulong rBit) is not callable using argument types (Bits, Bits) Kind regards André |
March 10, 2015 Re: 2.067 Beta: Behavior of enum and ref changed | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andre | On Tuesday, 10 March 2015 at 07:04:48 UTC, Andre wrote:
> Hi,
>
> following coding raises a compiler error with the beta of 2.067.
> Is this error intended or not?
> It is working if I change first line of main to: ulong bits;
>
> enum Bits: ulong
> {
> none = 0
> }
>
> bool hasBit(ref ulong rBits, ulong rBit)
> {
> return cast(bool)(rBits & rBit);
> }
>
> void main()
> {
> Bits bits;
> hasBit(bits, Bits.none);
> }
>
> function app.hasBit (ref ulong rBits, ulong rBit) is not callable using argument types (Bits, Bits)
>
> Kind regards
> André
It's because enums are not implicitly convertible to their base type. It was probably a compiler bug that it worked before. It's a regression however, so I'll file an issue in Bugzilla. In the meantime you can do:
hasBit(cast(ulong)bits, Bits.none);
Or just use a ulong as you mentioned.
|
March 10, 2015 Re: 2.067 Beta: Behavior of enum and ref changed | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Tuesday, March 10, 2015 08:19:27 Meta via Digitalmars-d-learn wrote:
> On Tuesday, 10 March 2015 at 07:04:48 UTC, Andre wrote:
> > Hi,
> >
> > following coding raises a compiler error with the beta of 2.067.
> > Is this error intended or not?
> > It is working if I change first line of main to: ulong bits;
> >
> > enum Bits: ulong
> > {
> > none = 0
> > }
> >
> > bool hasBit(ref ulong rBits, ulong rBit)
> > {
> > return cast(bool)(rBits & rBit);
> > }
> >
> > void main()
> > {
> > Bits bits;
> > hasBit(bits, Bits.none);
> > }
> >
> > function app.hasBit (ref ulong rBits, ulong rBit) is not
> > callable using argument types (Bits, Bits)
> >
> > Kind regards
> > André
>
> It's because enums are not implicitly convertible to their base type. It was probably a compiler bug that it worked before. It's a regression however, so I'll file an issue in Bugzilla. In the meantime you can do:
>
> hasBit(cast(ulong)bits, Bits.none);
>
> Or just use a ulong as you mentioned.
enums _are_ implicitly convertible to their base type. e.g. this compiles just fine
void main()
{
enum S : string { a = "hello", b = "world" }
string s = S.a;
}
It's the base type that isn't implicitly convertible to the enum type.
However, the code in question still shouldn't compile because while a Bits variable may be implicitly convertible to ulong, it _isn't_ a ulong, so passing it as a ref argument of type ulong isn't legal. Implicit conversions aren't used with ref. With ref, the type must match exactly.
- Jonathan M Davis
|
March 10, 2015 Re: 2.067 Beta: Behavior of enum and ref changed | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Tuesday, 10 March 2015 at 08:37:46 UTC, Jonathan M Davis wrote: > It's the base type that isn't implicitly convertible to the enum type. Err, yes. I had that the wrong way around. Anyway, I filed an issue. https://issues.dlang.org/show_bug.cgi?id=14269 |
March 10, 2015 Re: 2.067 Beta: Behavior of enum and ref changed | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | Thanks a lot!
Kind regards
André
On Tuesday, 10 March 2015 at 09:25:02 UTC, Meta wrote:
> On Tuesday, 10 March 2015 at 08:37:46 UTC, Jonathan M Davis wrote:
>> It's the base type that isn't implicitly convertible to the enum type.
>
> Err, yes. I had that the wrong way around. Anyway, I filed an issue.
>
> https://issues.dlang.org/show_bug.cgi?id=14269
|
March 10, 2015 Re: 2.067 Beta: Behavior of enum and ref changed | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 03/10/2015 01:37 AM, Jonathan M Davis via Digitalmars-d-learn wrote: > However, the code in question still shouldn't compile because while a Bits > variable may be implicitly convertible to ulong, it _isn't_ a ulong, In other words, the result of the implicit conversion is an rvalue, created on the spot, not the actual lvalue. References cannot be bound to rvalues. Ali |
March 10, 2015 Re: 2.067 Beta: Behavior of enum and ref changed | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 03/10/2015 11:05 AM, Ali Çehreli wrote: > In other words, the result of the implicit conversion is an rvalue Steven Schveighoffer says there is no rvalue in this case; "an enum is a derivative": https://issues.dlang.org/show_bug.cgi?id=14269#c14 Ali |
March 11, 2015 Re: 2.067 Beta: Behavior of enum and ref changed | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Tuesday, March 10, 2015 13:26:00 Ali Çehreli via Digitalmars-d-learn wrote:
> On 03/10/2015 11:05 AM, Ali Çehreli wrote:
>
> > In other words, the result of the implicit conversion is an rvalue
>
> Steven Schveighoffer says there is no rvalue in this case; "an enum is a derivative":
>
> https://issues.dlang.org/show_bug.cgi?id=14269#c14
Implicit conversions result in rvalues, not lvalues. What's potentially
different about enums is that underneath the hood, there's no difference
between an enum and its base type - they're represented exactly the same in
terms of bits; it's just the type system that treats them differently. So,
the implicit conversion just changes how the type system treats it rather
than the object's representation. So, it's possible to make it work so that
a ref argument of the base type accepts a variable of the enum type, whereas
that doesn't work with something like classes or even different integral
types. An implicit conversion of an enum variable to its base type is
one of the few cases where you even _could_ have an implicit conversion
involving ref, but implicit conversions are supposed to result in rvalues as
far as D's type system is concerned, so the fact that you could pass an
enum value to a function taking its base type as a ref argument was
definitely a bug.
- Jonathan M Davis
|
Copyright © 1999-2021 by the D Language Foundation