Bug 8995 – `is(<Type> <Identifier> == function)` creates tuple with parameter storage classes

Status
NEW
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-11-10T23:28:55Z
Last change time
2024-12-13T18:02:45Z
Keywords
spec
Assigned to
No Owner
Creator
Denis Shelomovskii
Moved to GitHub: dmd#18491 →

Comments

Comment #0 by verylonglogin.reg — 2012-11-10T23:28:55Z
Function parameter types tuple retrieved with `IsExpression` contains parameter storage classes unless indexed (slicing remains storage classes). It is not documented that typetuple can contain parameter storage classes so it may lead to unexpected behavior and looks inconsistent because `is(typetuple1 == typetuple2)` is `true` for tuples with different storage classes. --- template TypeTuple(T...) { alias T TypeTuple; } template t(alias func) { static if (is(typeof(func) Args == function)) { static assert(is(Args == TypeTuple!(int, int, int, int))); // passes pragma(msg, "Args: ", Args); // (int, ref int, out int, auto int) pragma(msg, "Args[1..2]: ", Args[1..2]); // (ref int) pragma(msg, "Args[1]: ", Args[1]); // int void g1(Args[0 .. 3]) { } // void(int, ref int, out int) pragma(msg, "typeof(g1): ", typeof(g1)); void g2(Args[3]) { } // void(int) pragma(msg, "typeof(g2): ", typeof(g2)); void g3(Args[3 .. 4]) { } // void(auto ref int), error, line 20 } else static assert(0); } void f(T)(int, ref int, out int, auto ref T) { alias t!f tf; } void main() { int i; f(0, i, i, 0); } --- Compiler output: --- Args: (int, ref int, out int, auto int) Args[1..2]: (ref int) Args[1]: int typeof(g1): void(int, ref int, out int) typeof(g2): void(int) main.d(20): Error: auto can only be used for template function parameters main.d(29): Error: template instance main.t!(f) error instantiating main.d(36): instantiated from here: f!(int) main.d(36): Error: template instance main.f!(int) error instantiating ---
Comment #1 by verylonglogin.reg — 2012-11-10T23:34:15Z
Workaround to remove storage classes: --- import std.typetuple; template DeStorage(T) { alias T DeStorage; } alias staticMap!(DeStorage, ArgsWithStorageClasses) Args; --- Note, it it's not documented, that `staticMap` will use indexing (`A[x]`) instead of slicing (`A[x .. x+1]`) and in latter case this workaround will not work so you have to copy/paste `staticMap` with current behavior to you code.
Comment #2 by robert.schadek — 2024-12-13T18:02:45Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18491 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB