Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Template args to UDA's #18589

Closed
dlangBugzillaToGithub opened this issue May 28, 2013 · 7 comments
Closed

Template args to UDA's #18589

dlangBugzillaToGithub opened this issue May 28, 2013 · 7 comments

Comments

@dlangBugzillaToGithub
Copy link

Manu reported this on 2013-05-28T06:45:05Z

Transferred from https://issues.dlang.org/show_bug.cgi?id=10193

CC List

  • Andrei Alexandrescu (@andralex)
  • Diggory
  • Nicholas Wilson

Description

So I've run into an expression I need to implement std.simd properly for GDC/LDC.

Doesn't work:
  @attribute("target", T) void func(string T)(...);

In this case, currently, the UDA can't receive the template arg that was given to the function.

I require that attributes on templates be able to make use of the template args, since the template arg given may affect the attribute in some circumstances.

This is blocking cross-platform support in std.simd.
@dlangBugzillaToGithub
Copy link
Author

k.hara.pg commented on 2013-05-28T08:48:27Z

(In reply to comment #0)
> Doesn't work:
>   @attribute("target", T) void func(string T)(...);

You can write it as follows.

string attribute(string, string s) { return s; }
template func(string T)
{
    @attribute("target", T) void func() {}
}

void main()
{
    alias f1 = func!"a";
    alias f2 = func!"b";
    pragma(msg, __traits(getAttributes, f1));   // "a"
    pragma(msg, __traits(getAttributes, f2));   // "b"
    f1();
    f2();
}

----

It looks reasonable enhancement, but in general case it would introduce not trivial semantic issue.

Based on the current D language spec, prefix attribute is just rewritten to blocked attribute.

@attribute("target", T) void func(string T)() {}

to:
@attribute("target", T) { void func(string T)() {} }

And block attribute can contain other declarations.

@attribute("target", T) {

    enum str = T.stringof;

    void func(string T)() {}
}

Well, if the enhancement is implemented, T would be deduced by the each call of template function foo. Then the enum value would become undeterministic.

I think it is not implementable.

@dlangBugzillaToGithub
Copy link
Author

turkeyman commented on 2013-05-28T16:56:57Z

(In reply to comment #1)
> Based on the current D language spec, prefix attribute is just rewritten to
> blocked attribute.
> 
> @attribute("target", T) void func(string T)() {}
> 
> to:
> @attribute("target", T) { void func(string T)() {} }
> 
> And block attribute can contain other declarations.
> 
> @attribute("target", T) {
> 
>     enum str = T.stringof;
> 
>     void func(string T)() {}
> }
> 
> Well, if the enhancement is implemented, T would be deduced by the each call of
> template function foo. Then the enum value would become undeterministic.
> 
> I think it is not implementable.

I see. Although I wonder if this is what users would expect. It seems more like an implementation detail.

I would assume a very distinct difference between:

@attribute("target", T) void func(string T)() {}
@attribute("target", T) { ...stuff... void func(string T)() {} ...stuff... }

The obvious outer scope being the difference.
In the first case, it is all (or appears to be) one declaration, and T should be usable across the declaration.
In the second, there is clearly an outer scope, and no sane programmer would expect that you should be able to access arguments to an inner declaration within the outer scope.

So I guess the question becomes, does the lowering of attributes to a scoped attribute actually make sense anymore with the possibility of UDA's?
It never mattered before since no hard attributes received arguments, but times are different now...
The behaviour is no longer transparent, and kinda counter-intuitive.

@dlangBugzillaToGithub
Copy link
Author

diggsey commented on 2013-05-28T20:49:48Z

It could be implemented by making the template rewrite rule happen before the attribute rewrite rule, so that this:

@attribute("target", T) void func(string T)(...);

Goes to:

template func(string T) {
    @attribute("target", T) void func(...);
}

And then this:

template func(string T) {
    @attribute("target", T) {
        void func(...);
    }
}

Rather than the other way around like it does currently.

Block attributes would be unaffected as they are already expanded.

@dlangBugzillaToGithub
Copy link
Author

turkeyman commented on 2013-05-28T22:10:42Z

(In reply to comment #3)
> It could be implemented by making the template rewrite rule happen before the
> attribute rewrite rule, so that this:
> 
> @attribute("target", T) void func(string T)(...);
> 
> Goes to:
> 
> template func(string T) {
>     @attribute("target", T) void func(...);
> }
> 
> And then this:
> 
> template func(string T) {
>     @attribute("target", T) {
>         void func(...);
>     }
> }
> 
> Rather than the other way around like it does currently.
> 
> Block attributes would be unaffected as they are already expanded.

I like the way this man thinks! :)

@dlangBugzillaToGithub
Copy link
Author

turkeyman commented on 2014-05-22T10:40:03Z

Can we have some movement on this?
std.simd is blocked on this issue.

Here's the thing:

enum targets[] = [ "hello", "world" ];

@attribute("target", targets[Target])
T func(int Target, T)(T arg)
{
  return arg;
}


The UDA is based on a template arg, and this doesn't work.
I try and expand it manually:

template func(int Target, T)
{
  @attribute("target", targets[Target])
  T func(T arg)
  {
    return arg;
  }
}

But this doesn't work either, it complains:
  Error: template func cannot deduce function from argument types !()(__vector(int[4])), candidates are: ...


Is there a workaround solution available?
It'd be nice to support this directly as in the OP.

@dlangBugzillaToGithub
Copy link
Author

andrei (@andralex) commented on 2015-12-16T17:59:46Z

More discussion with an application: http://forum.dlang.org/thread/n4s66a$i9u$1@digitalmars.com

@dlangBugzillaToGithub
Copy link
Author

iamthewilsonator commented on 2021-03-21T12:02:01Z

Does https://github.com/dlang/dmd/pull/5314 fix this well enough?

It enables void func(string T)() @attribute("target", T) {};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants