Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.
/ druntime Public archive
Closed
Show file tree
Hide file tree
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
94 changes: 47 additions & 47 deletions src/object.d
Original file line number Diff line number Diff line change
Expand Up @@ -969,10 +969,10 @@ class TypeInfo
}

/// Compares two instances for equality.
bool equals(in void* p1, in void* p2) const { return p1 == p2; }
bool equals(const scope void* p1, const scope void* p2) const { return p1 == p2; }

/// Compares two instances for <, ==, or >.
int compare(in void* p1, in void* p2) const { return _xopCmp(p1, p2); }
int compare(const scope void* p1, const scope void* p2) const { return _xopCmp(p1, p2); }

/// Returns size of the type.
@property size_t tsize() nothrow pure const @safe @nogc { return 0; }
Expand Down Expand Up @@ -1044,8 +1044,8 @@ class TypeInfo_Enum : TypeInfo
}

override size_t getHash(scope const void* p) const { return base.getHash(p); }
override bool equals(in void* p1, in void* p2) const { return base.equals(p1, p2); }
override int compare(in void* p1, in void* p2) const { return base.compare(p1, p2); }
override bool equals(const scope void* p1, const scope void* p2) const { return base.equals(p1, p2); }
override int compare(const scope void* p1, const scope void* p2) const { return base.compare(p1, p2); }
override @property size_t tsize() nothrow pure const { return base.tsize; }
override void swap(void* p1, void* p2) const { return base.swap(p1, p2); }

Expand Down Expand Up @@ -1097,12 +1097,12 @@ class TypeInfo_Pointer : TypeInfo
return addr ^ (addr >> 4);
}

override bool equals(in void* p1, in void* p2) const
override bool equals(const scope void* p1, const scope void* p2) const
{
return *cast(void**)p1 == *cast(void**)p2;
}

override int compare(in void* p1, in void* p2) const
override int compare(const scope void* p1, const scope void* p2) const
{
if (*cast(void**)p1 < *cast(void**)p2)
return -1;
Expand Down Expand Up @@ -1153,7 +1153,7 @@ class TypeInfo_Array : TypeInfo
return getArrayHash(value, a.ptr, a.length);
}

override bool equals(in void* p1, in void* p2) const
override bool equals(const scope void* p1, const scope void* p2) const
{
void[] a1 = *cast(void[]*)p1;
void[] a2 = *cast(void[]*)p2;
Expand All @@ -1168,7 +1168,7 @@ class TypeInfo_Array : TypeInfo
return true;
}

override int compare(in void* p1, in void* p2) const
override int compare(const scope void* p1, const scope void* p2) const
{
void[] a1 = *cast(void[]*)p1;
void[] a2 = *cast(void[]*)p2;
Expand Down Expand Up @@ -1251,7 +1251,7 @@ class TypeInfo_StaticArray : TypeInfo
return getArrayHash(value, p, len);
}

override bool equals(in void* p1, in void* p2) const
override bool equals(const scope void* p1, const scope void* p2) const
{
size_t sz = value.tsize;

Expand All @@ -1263,7 +1263,7 @@ class TypeInfo_StaticArray : TypeInfo
return true;
}

override int compare(in void* p1, in void* p2) const
override int compare(const scope void* p1, const scope void* p2) const
{
size_t sz = value.tsize;

Expand Down Expand Up @@ -1370,7 +1370,7 @@ class TypeInfo_AssociativeArray : TypeInfo
this.value == c.value;
}

override bool equals(in void* p1, in void* p2) @trusted const
override bool equals(const scope void* p1, const scope void* p2) @trusted const
{
return !!_aaEqual(this, *cast(const AA*) p1, *cast(const AA*) p2);
}
Expand Down Expand Up @@ -1423,8 +1423,8 @@ class TypeInfo_Vector : TypeInfo
}

override size_t getHash(scope const void* p) const { return base.getHash(p); }
override bool equals(in void* p1, in void* p2) const { return base.equals(p1, p2); }
override int compare(in void* p1, in void* p2) const { return base.compare(p1, p2); }
override bool equals(const scope void* p1, const scope void* p2) const { return base.equals(p1, p2); }
override int compare(const scope void* p1, const scope void* p2) const { return base.compare(p1, p2); }
override @property size_t tsize() nothrow pure const { return base.tsize; }
override void swap(void* p1, void* p2) const { return base.swap(p1, p2); }

Expand Down Expand Up @@ -1523,14 +1523,14 @@ class TypeInfo_Delegate : TypeInfo
return hashOf(*cast(void delegate()*)p);
}

override bool equals(in void* p1, in void* p2) const
override bool equals(const scope void* p1, const scope void* p2) const
{
auto dg1 = *cast(void delegate()*)p1;
auto dg2 = *cast(void delegate()*)p2;
return dg1 == dg2;
}

override int compare(in void* p1, in void* p2) const
override int compare(const scope void* p1, const scope void* p2) const
{
auto dg1 = *cast(void delegate()*)p1;
auto dg2 = *cast(void delegate()*)p2;
Expand Down Expand Up @@ -1598,15 +1598,15 @@ class TypeInfo_Class : TypeInfo
return o ? o.toHash() : 0;
}

override bool equals(in void* p1, in void* p2) const
override bool equals(const scope void* p1, const scope void* p2) const
{
Object o1 = *cast(Object*)p1;
Object o2 = *cast(Object*)p2;

return (o1 is o2) || (o1 && o1.opEquals(o2));
}

override int compare(in void* p1, in void* p2) const
override int compare(const scope void* p1, const scope void* p2) const
{
Object o1 = *cast(Object*)p1;
Object o2 = *cast(Object*)p2;
Expand Down Expand Up @@ -1681,7 +1681,7 @@ class TypeInfo_Class : TypeInfo
* Search all modules for TypeInfo_Class corresponding to classname.
* Returns: null if not found
*/
static const(TypeInfo_Class) find(in char[] classname)
static const(TypeInfo_Class) find(const scope char[] classname)
{
foreach (m; ModuleInfo)
{
Expand Down Expand Up @@ -1759,7 +1759,7 @@ class TypeInfo_Interface : TypeInfo
return o.toHash();
}

override bool equals(in void* p1, in void* p2) const
override bool equals(const scope void* p1, const scope void* p2) const
{
Interface* pi = **cast(Interface ***)*cast(void**)p1;
Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);
Expand All @@ -1769,7 +1769,7 @@ class TypeInfo_Interface : TypeInfo
return o1 == o2 || (o1 && o1.opCmp(o2) == 0);
}

override int compare(in void* p1, in void* p2) const
override int compare(const scope void* p1, const scope void* p2) const
{
Interface* pi = **cast(Interface ***)*cast(void**)p1;
Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);
Expand Down Expand Up @@ -1834,7 +1834,7 @@ class TypeInfo_Struct : TypeInfo
}
}

override bool equals(in void* p1, in void* p2) @trusted pure nothrow const
override bool equals(const scope void* p1, const scope void* p2) @trusted pure nothrow const
{
import core.stdc.string : memcmp;

Expand All @@ -1849,7 +1849,7 @@ class TypeInfo_Struct : TypeInfo
return memcmp(p1, p2, initializer().length) == 0;
}

override int compare(in void* p1, in void* p2) @trusted pure nothrow const
override int compare(const scope void* p1, const scope void* p2) @trusted pure nothrow const
{
import core.stdc.string : memcmp;

Expand Down Expand Up @@ -1908,10 +1908,10 @@ class TypeInfo_Struct : TypeInfo

@safe pure nothrow
{
size_t function(in void*) xtoHash;
bool function(in void*, in void*) xopEquals;
int function(in void*, in void*) xopCmp;
string function(in void*) xtoString;
size_t function(const scope void*) xtoHash;
bool function(const scope void*, const scope void*) xopEquals;
int function(const scope void*, const scope void*) xopCmp;
string function(const scope void*) xtoString;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pedantically speaking, I don't think those function parameters can be neither scope nor const :(

Only when the TypeInfo generation is fully template-driven we can have true guarantees about const/scope/insert your favorite function attribute here correctness.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you recommend?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two options:

  1. Use honest function signature and change those parameters to void* as in reality even the const-ness can't be guaranteed. This means that TypeInfo_Struct.{equals,compare} must also take void* parameters which is likely a breaking change.

  2. Continue with the deceit and deal with problems somehow later down the line, when we can be technically honest.

@jmdavis @schveiguy @atilaneves What's your point of view?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure. I agree we can't make them scope or const though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ZombineDev Why can't these be const? They shouldn't be modifying p.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JinShil Because they are function pointers to arbitrary user code. The pointer itself may not be modified (as it will be copied), but the object pointed by p may be. And it can also escape p without any issues.

Here's the sort of techniques that we need to use in order to be type safe:
https://gist.github.com/ZombineDev/ac19e93dff4f7b251be0c7af8e8d150d#file-proper_type_info-d-L62-L73

Live demo: https://run.dlang.io/gist/ZombineDev/ac19e93dff4f7b251be0c7af8e8d150d?compiler=dmd&args=-dip1000


enum StructFlags : uint
{
Expand Down Expand Up @@ -1998,12 +1998,12 @@ class TypeInfo_Tuple : TypeInfo
assert(0);
}

override bool equals(in void* p1, in void* p2) const
override bool equals(const scope void* p1, const scope void* p2) const
{
assert(0);
}

override int compare(in void* p1, in void* p2) const
override int compare(const scope void* p1, const scope void* p2) const
{
assert(0);
}
Expand Down Expand Up @@ -2065,8 +2065,8 @@ class TypeInfo_Const : TypeInfo
}

override size_t getHash(scope const void *p) const { return base.getHash(p); }
override bool equals(in void *p1, in void *p2) const { return base.equals(p1, p2); }
override int compare(in void *p1, in void *p2) const { return base.compare(p1, p2); }
override bool equals(const scope void *p1, const scope void *p2) const { return base.equals(p1, p2); }
override int compare(const scope void *p1, const scope void *p2) const { return base.compare(p1, p2); }
Copy link
Member

@PetarKirov PetarKirov Jul 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

base can be the TypeInfo for a class or struct which implements opEquals|opCompare without having the scope attribute on the parameter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you recommend?

override @property size_t tsize() nothrow pure const { return base.tsize; }
override void swap(void *p1, void *p2) const { return base.swap(p1, p2); }

Expand Down Expand Up @@ -2145,7 +2145,7 @@ struct ModuleInfo
version (all)
{
deprecated("ModuleInfo cannot be copy-assigned because it is a variable-sized struct.")
void opAssign(in ModuleInfo m) { _flags = m._flags; _index = m._index; }
void opAssign(const scope ModuleInfo m) { _flags = m._flags; _index = m._index; }
}
else
{
Expand Down Expand Up @@ -2512,7 +2512,7 @@ class Throwable : Object
override string toString()
{
string s;
toString((buf) { s ~= buf; });
toString((const scope char[] buf) { s ~= buf; });
return s;
}

Expand All @@ -2522,7 +2522,7 @@ class Throwable : Object
* performed in certain error situations. Override this $(D
* toString) method to customize the error message.
*/
void toString(scope void delegate(in char[]) sink) const
void toString(scope void delegate(const scope char[]) sink) const
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be a breaking change for callers, but that should only affect their @safe code, when they compile with -preview=dip1000.

{
import core.internal.string : unsignedToTempString;

Expand Down Expand Up @@ -2738,13 +2738,13 @@ extern (C)
// from druntime/src/rt/aaA.d

private struct AA { void* impl; }
// size_t _aaLen(in AA aa) pure nothrow @nogc;
private void* _aaGetY(AA* paa, const TypeInfo_AssociativeArray ti, in size_t valsz, in void* pkey) pure nothrow;
private void* _aaGetX(AA* paa, const TypeInfo_AssociativeArray ti, in size_t valsz, in void* pkey, out bool found) pure nothrow;
// inout(void)* _aaGetRvalueX(inout AA aa, in TypeInfo keyti, in size_t valsz, in void* pkey);
inout(void[]) _aaValues(inout AA aa, in size_t keysz, in size_t valsz, const TypeInfo tiValueArray) pure nothrow;
inout(void[]) _aaKeys(inout AA aa, in size_t keysz, const TypeInfo tiKeyArray) pure nothrow;
void* _aaRehash(AA* paa, in TypeInfo keyti) pure nothrow;
// size_t _aaLen(const scope AA aa) pure nothrow @nogc;
private void* _aaGetY(AA* paa, const TypeInfo_AssociativeArray ti, const size_t valsz, const scope void* pkey) pure nothrow;
private void* _aaGetX(AA* paa, const TypeInfo_AssociativeArray ti, const size_t valsz, const scope void* pkey, out bool found) pure nothrow;
// inout(void)* _aaGetRvalueX(inout AA aa, const scope TypeInfo keyti, const size_t valsz, const scope void* pkey);
inout(void[]) _aaValues(inout AA aa, const size_t keysz, const size_t valsz, const TypeInfo tiValueArray) pure nothrow;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only used const for size_t as I believe scope is not applicable to value types.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is ignored to make generic code agnostic to valueness.

inout(void[]) _aaKeys(inout AA aa, const size_t keysz, const TypeInfo tiKeyArray) pure nothrow;
void* _aaRehash(AA* paa, const scope TypeInfo keyti) pure nothrow;
void _aaClear(AA aa) pure nothrow;

// alias _dg_t = extern(D) int delegate(void*);
Expand All @@ -2760,8 +2760,8 @@ extern (C)
void* _aaRangeFrontValue(AARange r) pure nothrow @nogc @safe;
void _aaRangePopFront(ref AARange r) pure nothrow @nogc @safe;

int _aaEqual(in TypeInfo tiRaw, in AA aa1, in AA aa2);
hash_t _aaGetHash(in AA* aa, in TypeInfo tiRaw) nothrow;
int _aaEqual(const scope TypeInfo tiRaw, const scope AA aa1, const scope AA aa2);
hash_t _aaGetHash(const scope AA* aa, const scope TypeInfo tiRaw) nothrow;

/*
_d_assocarrayliteralTX marked as pure, because aaLiteral can be called from pure code.
Expand Down Expand Up @@ -3658,7 +3658,7 @@ version (none)
return value;
}

private void _bailOut(string file, int line, in char[] msg)
private void _bailOut(string file, int line, const scope char[] msg)
{
char[21] buf = void;
throw new Exception(cast(string)(file ~ "(" ~ ulongToString(buf[], line) ~ "): " ~ (msg ? msg : "Enforcement failed")));
Expand Down Expand Up @@ -3728,12 +3728,12 @@ else
}
}

bool _xopEquals(in void*, in void*)
bool _xopEquals(const scope void*, const scope void*)
{
throw new Error("TypeInfo.equals is not implemented");
}

bool _xopCmp(in void*, in void*)
bool _xopCmp(const scope void*, const scope void*)
{
throw new Error("TypeInfo.compare is not implemented");
}
Expand Down Expand Up @@ -3975,7 +3975,7 @@ private inout(TypeInfo) getElement(inout TypeInfo value) @trusted pure nothrow
return cast(inout) element;
}

private size_t getArrayHash(in TypeInfo element, in void* ptr, in size_t count) @trusted nothrow
private size_t getArrayHash(const scope TypeInfo element, const scope void* ptr, const size_t count) @trusted nothrow
{
if (!count)
return 0;
Expand All @@ -3984,7 +3984,7 @@ private size_t getArrayHash(in TypeInfo element, in void* ptr, in size_t count)
if (!elementSize)
return 0;

static bool hasCustomToHash(in TypeInfo value) @trusted pure nothrow
static bool hasCustomToHash(const scope TypeInfo value) @trusted pure nothrow
{
const element = getElement(value);

Expand Down
6 changes: 3 additions & 3 deletions src/rt/dmain2.d
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ extern (C) int _d_run_main(int argc, char **argv, MainFunc mainFunc)
return result;
}

private void formatThrowable(Throwable t, scope void delegate(in char[] s) nothrow sink)
private void formatThrowable(Throwable t, scope void delegate(const scope char[] s) nothrow sink)
{
foreach (u; t)
{
Expand Down Expand Up @@ -595,7 +595,7 @@ extern (C) void _d_print_throwable(Throwable t)
{
WCHAR* ptr; size_t len;

void sink(in char[] s) scope nothrow
void sink(const scope char[] s) scope nothrow
{
if (!s.length) return;
int swlen = MultiByteToWideChar(
Expand Down Expand Up @@ -683,7 +683,7 @@ extern (C) void _d_print_throwable(Throwable t)
}
}

void sink(in char[] buf) scope nothrow
void sink(const scope char[] buf) scope nothrow
{
fprintf(stderr, "%.*s", cast(int)buf.length, buf.ptr);
}
Expand Down
4 changes: 2 additions & 2 deletions src/rt/typeinfo/ti_Acdouble.d
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ class TypeInfo_Ar : TypeInfo_Array
return Array!F.hashOf(*cast(F[]*)p);
}

override bool equals(in void* p1, in void* p2) const
override bool equals(const scope void* p1, const scope void* p2) const
{
return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);
}

override int compare(in void* p1, in void* p2) const
override int compare(const scope void* p1, const scope void* p2) const
{
return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);
}
Expand Down
4 changes: 2 additions & 2 deletions src/rt/typeinfo/ti_Acfloat.d
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ class TypeInfo_Aq : TypeInfo_Array
return Array!F.hashOf(*cast(F[]*)p);
}

override bool equals(in void* p1, in void* p2) const
override bool equals(const scope void* p1, const scope void* p2) const
{
return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);
}

override int compare(in void* p1, in void* p2) const
override int compare(const scope void* p1, const scope void* p2) const
{
return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);
}
Expand Down
4 changes: 2 additions & 2 deletions src/rt/typeinfo/ti_Acreal.d
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ class TypeInfo_Ac : TypeInfo_Array
return Array!F.hashOf(*cast(F[]*)p);
}

override bool equals(in void* p1, in void* p2) const
override bool equals(const scope void* p1, const scope void* p2) const
{
return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);
}

override int compare(in void* p1, in void* p2) const
override int compare(const scope void* p1, const scope void* p2) const
{
return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);
}
Expand Down
Loading