www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - opDispatch compiles fine, but still fails to resolve?

reply "Vlad Levenfeld" <vlevenfeld gmail.com> writes:
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).
Aug 08 2014
next sibling parent reply "Meta" <jared771 gmail.com> writes:
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.
Aug 08 2014
parent reply "Vlad Levenfeld" <vlevenfeld gmail.com> writes:
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.
Aug 08 2014
parent reply "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
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."
Aug 08 2014
parent "Vlad Levenfeld" <vlevenfeld gmail.com> writes:
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.
Aug 09 2014
prev sibling parent reply Artur Skawina via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
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
Aug 09 2014
parent "Vlad Levenfeld" <vlevenfeld gmail.com> writes:
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.
Aug 09 2014