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

Fix #20601 - hasIndirections does not handle static arrays of length 0 correctly #20602

Merged
merged 1 commit into from
Dec 25, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 102 additions & 1 deletion druntime/src/core/internal/traits.d
Original file line number Diff line number Diff line change
Expand Up @@ -543,13 +543,114 @@ template hasIndirections(T)
else static if (__traits(isAssociativeArray, T) || is(T == class) || is(T == interface))
enum hasIndirections = true;
else static if (is(T == E[N], E, size_t N))
enum hasIndirections = T.sizeof && is(E == void) ? true : hasIndirections!(BaseElemOf!E);
enum hasIndirections = T.sizeof && (is(E == void) || hasIndirections!(BaseElemOf!E));
else static if (isFunctionPointer!T)
enum hasIndirections = false;
else
enum hasIndirections = isPointer!T || isDelegate!T || isDynamicArray!T;
}

@safe unittest
{
static assert(!hasIndirections!int);
static assert(!hasIndirections!(const int));

static assert( hasIndirections!(int*));
static assert( hasIndirections!(const int*));

static assert( hasIndirections!(int[]));
static assert(!hasIndirections!(int[42]));
static assert(!hasIndirections!(int[0]));

static assert( hasIndirections!(int*));
static assert( hasIndirections!(int*[]));
static assert( hasIndirections!(int*[42]));
static assert(!hasIndirections!(int*[0]));

static assert( hasIndirections!string);
static assert( hasIndirections!(string[]));
static assert( hasIndirections!(string[42]));
static assert(!hasIndirections!(string[0]));

static assert( hasIndirections!(void[]));
static assert( hasIndirections!(void[17]));
static assert(!hasIndirections!(void[0]));

static assert( hasIndirections!(string[int]));
static assert( hasIndirections!(string[int]*));
static assert( hasIndirections!(string[int][]));
static assert( hasIndirections!(string[int][12]));
static assert(!hasIndirections!(string[int][0]));

static assert(!hasIndirections!(int function(string)));
static assert( hasIndirections!(int delegate(string)));
static assert(!hasIndirections!(const(int function(string))));
static assert( hasIndirections!(const(int delegate(string))));
static assert(!hasIndirections!(immutable(int function(string))));
static assert( hasIndirections!(immutable(int delegate(string))));

static class C {}
static assert( hasIndirections!C);

static interface I {}
static assert( hasIndirections!I);

{
static struct S {}
static assert(!hasIndirections!S);
}
{
static struct S { int i; }
static assert(!hasIndirections!S);
}
{
static struct S { C c; }
static assert( hasIndirections!S);
}
{
static struct S { int[] arr; }
static assert( hasIndirections!S);
}
{
int local;
struct S { void foo() { ++local; } }
static assert( hasIndirections!S);
}

{
static union U {}
static assert(!hasIndirections!U);
}
{
static union U { int i; }
static assert(!hasIndirections!U);
}
{
static union U { C c; }
static assert( hasIndirections!U);
}
{
static union U { int[] arr; }
static assert( hasIndirections!U);
}
}

// https://issues.dlang.org/show_bug.cgi?id=12000
@safe unittest
{
static struct S(T)
{
static assert(hasIndirections!T);
}

static class A(T)
{
S!A a;
}

A!int dummy;
}

template hasUnsharedIndirections(T)
{
static if (is(T == immutable))
Expand Down
Loading