Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
August 09, 2014 opDispatch compiles fine, but still fails to resolve? | ||||
---|---|---|---|---|
| ||||
More opDispatch woes. This feature keeps biting me, yet I keep trying to use it. This time I'm trying to access elements of a vector GLSL-style (without swizzling... for now). Here's the relevant code: struct Vector (uint length, Element = double) { ref @property component (string c)() { enum mat = q{xyzw}; enum col = q{rgba}; enum tex = q{uv}; static if (mat.canFind (c)) return components[mat.countUntil (c)]; else static if (col.canFind (c)) return components[col.countUntil (c)]; else static if (tex.canFind (c)) return components[tex.countUntil (c)]; else static assert (0); } ref @property opDispatch (string c)() if (c.length == 1) { auto v = component!c; pragma(msg, typeof(v)); // this outputs the expected result return v; // so everything is fine, right? wrong... } Element[length] components; } Calling vector.component!`x` or something works fine, but calling vector.x fails with "Error: no property" etc. Now, I'm used to opDispatch silently failing when it can't compile (very annoying btw), but in this case, I tested every line with a pragma (msg, __traits(compiles...)) and everything checks out. All expressions are verified CTFE-able. The compiler apparently makes it all the way through the method without a hitch, but then just fails symbol resolution anyway. Is this just a bug? Does anyone have any advice on what else to try? I'm out of ideas (short of falling back on generating property methods by string mixin). |
August 09, 2014 Re: opDispatch compiles fine, but still fails to resolve? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vlad Levenfeld | On Saturday, 9 August 2014 at 01:20:33 UTC, Vlad Levenfeld wrote:
> More opDispatch woes. This feature keeps biting me, yet I keep trying to use it.
>
> This time I'm trying to access elements of a vector GLSL-style (without swizzling... for now).
>
> Here's the relevant code:
>
> struct Vector (uint length, Element = double)
> {
> ref @property component (string c)()
> {
> enum mat = q{xyzw};
> enum col = q{rgba};
> enum tex = q{uv};
>
> static if (mat.canFind (c))
> return components[mat.countUntil (c)];
> else static if (col.canFind (c))
> return components[col.countUntil (c)];
> else static if (tex.canFind (c))
> return components[tex.countUntil (c)];
> else static assert (0);
> }
>
> ref @property opDispatch (string c)()
> if (c.length == 1)
> {
> auto v = component!c;
> pragma(msg, typeof(v)); // this outputs the expected result
> return v; // so everything is fine, right? wrong...
> }
>
> Element[length] components;
> }
>
> Calling vector.component!`x` or something works fine, but calling vector.x fails with "Error: no property" etc.
>
> Now, I'm used to opDispatch silently failing when it can't compile (very annoying btw), but in this case, I tested every line with a pragma (msg, __traits(compiles...)) and everything checks out. All expressions are verified CTFE-able. The compiler apparently makes it all the way through the method without a hitch, but then just fails symbol resolution anyway.
>
> Is this just a bug? Does anyone have any advice on what else to try? I'm out of ideas (short of falling back on generating property methods by string mixin).
Have you tried it without @property? It's probably that which is causing the "Error: no property" message. As far as I know, opDispatch *only* works for variable-like access (i.e., vector.x), so making it @property is unnecessary and probably, in this case, buggy.
|
August 09, 2014 Re: opDispatch compiles fine, but still fails to resolve? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | Yep, replacing @property with auto did the trick. The lack of error messages in opDispatch is frustrating. I realize that, due to tricks like __traits(compiles, Foo.testing_for_some_function), having opDispatch stop compilation if it fails is not going to work, but there's gotta be some way to expose what's going on with it when it fails. Maybe some kind of pragma to cause opDispatch to report its failures, I don't know. |
August 09, 2014 Re: opDispatch compiles fine, but still fails to resolve? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vlad Levenfeld | On Sat, Aug 09, 2014 at 05:34:40AM +0000, Vlad Levenfeld via Digitalmars-d-learn wrote: > Yep, replacing @property with auto did the trick. > > The lack of error messages in opDispatch is frustrating. I realize that, due to tricks like __traits(compiles, Foo.testing_for_some_function), having opDispatch stop compilation if it fails is not going to work, but there's gotta be some way to expose what's going on with it when it fails. Maybe some kind of pragma to cause opDispatch to report its failures, I don't know. Why would having opDispatch actually generate compile errors cause problems for __traits(compiles,...)? __traits(compiles...) already works fine with a whole bunch of other non-compiling stuff (by gagging errors while it attempts them). The problem with opDispatch is that it gags too much, even when the resolution ultimately fails, so you're left with mysterious "disappearances" of opDispatch with no hint as to what went wrong. I'm not familiar with this part of DMD, but surely there's a way to make this behave better?? T -- "The number you have dialed is imaginary. Please rotate your phone 90 degrees and try again." |
August 09, 2014 Re: opDispatch compiles fine, but still fails to resolve? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vlad Levenfeld | On 08/09/14 03:20, Vlad Levenfeld via Digitalmars-d-learn wrote:
> More opDispatch woes. This feature keeps biting me, yet I keep trying to use it.
>
> This time I'm trying to access elements of a vector GLSL-style (without swizzling... for now).
>
> Here's the relevant code:
>
> struct Vector (uint length, Element = double)
> {
> ref @property component (string c)()
> {
> enum mat = q{xyzw};
> enum col = q{rgba};
> enum tex = q{uv};
>
> static if (mat.canFind (c))
> return components[mat.countUntil (c)];
> else static if (col.canFind (c))
> return components[col.countUntil (c)];
> else static if (tex.canFind (c))
> return components[tex.countUntil (c)];
> else static assert (0);
> }
>
> ref @property opDispatch (string c)()
> if (c.length == 1)
> {
> auto v = component!c;
> pragma(msg, typeof(v)); // this outputs the expected result
> return v; // so everything is fine, right? wrong...
> }
>
> Element[length] components;
> }
>
> Calling vector.component!`x` or something works fine, but calling vector.x fails with "Error: no property" etc.
>
> Now, I'm used to opDispatch silently failing when it can't compile (very annoying btw), but in this case, I tested every line with a pragma (msg, __traits(compiles...)) and everything checks out. All expressions are verified CTFE-able. The compiler apparently makes it all the way through the method without a hitch, but then just fails symbol resolution anyway.
>
> Is this just a bug? Does anyone have any advice on what else to try?
v.opDispatch!`x`;
Your opDispatch is returning a reference to a local stack-allocated variable. D does not support real references; that 'auto v=...' declaration creates a copy.
ref @property opDispatch (string c)() { return component!c; }
[opDispatch works for every kind of symbol, there's no problem with
@property]
artur
|
August 09, 2014 Re: opDispatch compiles fine, but still fails to resolve? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Artur Skawina | On Saturday, 9 August 2014 at 10:36:55 UTC, Artur Skawina via Digitalmars-d-learn wrote:
> On 08/09/14 03:20, Vlad Levenfeld via Digitalmars-d-learn wrote:
>> More opDispatch woes. This feature keeps biting me, yet I keep trying to use it.
>>
>> This time I'm trying to access elements of a vector GLSL-style (without swizzling... for now).
>>
>> Here's the relevant code:
>>
>> struct Vector (uint length, Element = double)
>> {
>> ref @property component (string c)()
>> {
>> enum mat = q{xyzw};
>> enum col = q{rgba};
>> enum tex = q{uv};
>>
>> static if (mat.canFind (c))
>> return components[mat.countUntil (c)];
>> else static if (col.canFind (c))
>> return components[col.countUntil (c)];
>> else static if (tex.canFind (c))
>> return components[tex.countUntil (c)];
>> else static assert (0);
>> }
>>
>> ref @property opDispatch (string c)()
>> if (c.length == 1)
>> {
>> auto v = component!c;
>> pragma(msg, typeof(v)); // this outputs the expected result
>> return v; // so everything is fine, right? wrong...
>> }
>>
>> Element[length] components;
>> }
>>
>> Calling vector.component!`x` or something works fine, but calling vector.x fails with "Error: no property" etc.
>>
>> Now, I'm used to opDispatch silently failing when it can't compile (very annoying btw), but in this case, I tested every line with a pragma (msg, __traits(compiles...)) and everything checks out. All expressions are verified CTFE-able. The compiler apparently makes it all the way through the method without a hitch, but then just fails symbol resolution anyway.
>>
>> Is this just a bug? Does anyone have any advice on what else to try?
>
> v.opDispatch!`x`;
>
> Your opDispatch is returning a reference to a local stack-allocated
> variable. D does not support real references; that 'auto v=...'
> declaration creates a copy.
>
> ref @property opDispatch (string c)() { return component!c; }
>
> [opDispatch works for every kind of symbol, there's no problem with
> @property]
>
> artur
Yeah, sorry, I made that change last-minute to verify, with the pragma, that I was indeed getting the correct type. The problem must have been something else. I just made a complete oversight in the process of throwing everything but the kitchen sink into debugging it.
|
August 09, 2014 Re: opDispatch compiles fine, but still fails to resolve? | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Saturday, 9 August 2014 at 05:42:09 UTC, H. S. Teoh via Digitalmars-d-learn wrote:
> Why would having opDispatch actually generate compile errors cause
> problems for __traits(compiles,...)? __traits(compiles...) already works
> fine with a whole bunch of other non-compiling stuff (by gagging errors
> while it attempts them).
>
> The problem with opDispatch is that it gags too much, even when the
> resolution ultimately fails, so you're left with mysterious
> "disappearances" of opDispatch with no hint as to what went wrong. I'm
> not familiar with this part of DMD, but surely there's a way to make
> this behave better??
>
>
> T
You're right, between you and Artur and a night's rest I'm realizing what an utter mess my post was. At that point I had lost half a day debugging this and hadn't slept much so my thought process was not particularly coherent.
The only thing I've ever really managed to get out of opDispatch in terms of errors is to litter the thing with pragma(msg, ...) and hope that, on visual inspection, something clicks and I can figure out where I went wrong.
I think the real crux of my issue was misunderstanding "auto ref". After I noticed that I could use "const" or "@property" or some other qualifier instead of auto, I assumed that it implied auto, so that ref @property => auto ref @property. Evidently not. I was looking inside the method body for the issue when it was on that first line the whole time.
|
Copyright © 1999-2021 by the D Language Foundation