RejectedSoftware Forums

Sign up

Issue 404

Hello,

First of all congratulations for building such a nice framework. I love
D but now I love it even more. Am seriously thinking about using this
for our core web services.

During testing I had found some issues. Was trying to setup json
(de)serialization (with rest). After pasting the error string at google
I stumbled upon this:

https://github.com/rejectedsoftware/vibe.d/issues/404

Eventhough I got the error at line 233 of serialization.d, and Geod24,
who filed issue 404, got it on line 107, the fact that the code at both
lines is some similar made me conclude that the issue is related.

107: enum fname = getAttribute!(member,
NameAttribute)(NameAttribute(underscoreStrip(mname))).name;

233: enum fname =
getAttribute!(member)(NameAttribute(underscoreStrip(mname))).name;

I made a small file to reproduce the error, here it is:

import vibe.data.serialization;
import vibe.internal.meta.uda;
import std.typetuple;

struct Query
{

@name("this") int team;
@name("should") int limit;
@name("show") int skip;
@name("up") string search;

}

private static T getAttribute(alias decl, T)(T default_value)
{

enum val = findFirstUDA!(T, decl);
static if (val.found) return val.value;
else return default_value;

}

private string underscoreStrip(string field_name)
{

if( field_name.length < 1 || field_name[$-1] != '_' ) return field_name;
else return field_name[0 .. $-1];

}

private void test(T)()
{

foreach (i, mname; __traits(allMembers, T))
{
	alias member = TypeTuple!(__traits(getMember, T, mname))[0];
	enum fname = 

getAttribute!(member)(NameAttribute(underscoreStrip(mname))).name;

pragma(msg, fname);

}
}

unittest
{

alias T = Query;
test!T();

}

Re: Issue 404

private static T getAttribute(alias decl, T)(T default_value)
{

enum val = findFirstUDA!(T, decl);
static if (val.found) return val.value;
else return default_value;

}

alias member = TypeTuple!(__traits(getMember, T, mname))[0];
enum fname = 

getAttribute!(member)(NameAttribute(underscoreStrip(mname))).name;

I don't see this on the vibe.d master branch, it looks more like this now:

enum fname = getAttribute!(T, mname, NameAttribute)(NameAttribute(underscoreStrip(mname))).name;

and

private static T getAttribute(TT, string mname, T)(T default_value)
{
	enum val = findFirstUDA!(T, __traits(getMember, TT, mname));
	static if (val.found) return val.value;
	else return default_value;
}

Which leads me to believe that the cause of this error is because D expects this to be defined when passing a class / struct member alias instead of the type / member name as a template parameter. It could be a compiler bug... but I'm not so sure why the vibe.d master would trigger this sort of error, because I couldn't find your reproduction in the master branch. Did you use an older version?

Re: Issue 404

On 3/17/2014 7:07 AM, Etienne Cimon wrote:

I don't see this on the vibe.d master branch, it looks more like this now:

You are right, I am not on the master branch. I just wanted to do a
quick test; no need for the latest code. Or so I thought.

I have version v0.7.18, acquired via dub. I suppose I can change the
dependency to ~master in the dub.json

(side note, isn't it not supposed to be called package.json, that is
what the website says? for some reason I ended up with dub.json's)

enum fname = getAttribute!(T, mname, NameAttribute)(NameAttribute(underscoreStrip(mname))).name;

and

private static T getAttribute(TT, string mname, T)(T default_value)
{
	enum val = findFirstUDA!(T, __traits(getMember, TT, mname));
	static if (val.found) return val.value;
	else return default_value;
}

Which leads me to believe that the cause of this error is because D expects this to be defined when passing a class / struct member alias instead of the type / member name as a template parameter. It could be a compiler bug... but I'm not so sure why the vibe.d master would trigger this sort of error, because I couldn't find your reproduction in the master branch. Did you use an older version?

From the dlang website:

import std.stdio;

struct S {
int mx;
static int my;
}

void main() {
S s;

traits(getMember, s, "mx") = 1; // same as s.mx=1;
writeln(
traits(getMember, s, "m" ~ "x")); // 1

traits(getMember, S, "mx") = 1; // error, no this for S.mx <<---
traits(getMember, S, "my") = 2; // ok
}

What is being returned by __traits(getMember...) is an expression.
So, in my test snippet I basically did:

struct S
{

int mx;
static int my;

}

void main()
{

S s;
pragma(msg, __traits(getMember, S, "mx"));

}

Which, for reasons obvious to me now, is like calling a member variable
without a instance, therefor the error "need 'this' for ..."

Re: Issue 404

On Mon, 17 Mar 2014 17:33:58 GMT, Sebastiaan Koppe wrote:

On 3/17/2014 7:07 AM, Etienne Cimon wrote:

I don't see this on the vibe.d master branch, it looks more like this now:

You are right, I am not on the master branch. I just wanted to do a
quick test; no need for the latest code. Or so I thought.

I have version v0.7.18, acquired via dub. I suppose I can change the
dependency to ~master in the dub.json

Just an alternative for using ~master - you can also run dub upgrade --prerelease to let it use the latest release candidate of 0.7.19.

(side note, isn't it not supposed to be called package.json, that is
what the website says? for some reason I ended up with dub.json's)

It has recently been changed to "dub.json" to avoid ambiguities between other package managers (e.g. NPM also uses "package.json"). I'll update the website.