mirror of
https://github.com/dlang/dmd.git
synced 2025-04-25 20:50:41 +03:00
Merge remote-tracking branch 'upstream/stable' into merge_stable
This commit is contained in:
commit
48db76398c
26 changed files with 471 additions and 32 deletions
|
@ -93,6 +93,8 @@ macos12_task:
|
|||
OS: osx
|
||||
# 12 CPU cores and 24 GB of memory are available
|
||||
N: 12
|
||||
# FIXME: Temporarily use LDC until a release with a fix for issue 22942 is available (probably 2.101)
|
||||
HOST_DMD: ldc
|
||||
matrix:
|
||||
- TASK_NAME_SUFFIX: DMD (latest)
|
||||
- TASK_NAME_SUFFIX: DMD (coverage)
|
||||
|
|
33
changelog/TraitsParametersRevised.dd
Normal file
33
changelog/TraitsParametersRevised.dd
Normal file
|
@ -0,0 +1,33 @@
|
|||
Special case for `__traits(parameters)` in foreach loops was removed
|
||||
|
||||
Previously, when used inside a `foreach` using an overloaded `opApply`, the trait
|
||||
would yield the parameters to the delegate and not the function the foreach appears within.
|
||||
|
||||
This behaviour is unintuitive, especially when the type of the `foreach` aggregate
|
||||
depends on a template parameter. Hence `__traits(parameters)` was changed to consistently
|
||||
return the parameters of the lexically enclosing function.
|
||||
|
||||
---
|
||||
class Tree {
|
||||
int opApply(int delegate(size_t, Tree) dg) {
|
||||
if (dg(0, this)) return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
void useOpApply(Tree top, int x)
|
||||
{
|
||||
foreach(idx; 0..5)
|
||||
{
|
||||
static assert(is(typeof(__traits(parameters)) == AliasSeq!(Tree, int)));
|
||||
}
|
||||
|
||||
foreach(idx, elem; top)
|
||||
{
|
||||
// Previously:
|
||||
// static assert(is(typeof(__traits(parameters)) == AliasSeq!(size_t, Tree)));
|
||||
|
||||
// Now:
|
||||
static assert(is(typeof(__traits(parameters)) == AliasSeq!(Tree, int)));
|
||||
}
|
||||
}
|
||||
---
|
|
@ -547,7 +547,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
|
|||
if (overflow) assert(0);
|
||||
|
||||
// Skip no-op for noreturn without custom aligment
|
||||
if (memsize != 0 || !alignment.isDefault())
|
||||
if (memalignsize != 0 || !alignment.isDefault())
|
||||
alignmember(alignment, memalignsize, &ofs);
|
||||
|
||||
uint memoffset = ofs;
|
||||
|
|
|
@ -4553,6 +4553,38 @@ else
|
|||
{ // ES:DI points past what we want
|
||||
|
||||
cdb.genc2(0x81,(rex << 16) | modregrm(3,5,DI), type_size(e.ET)); // SUB DI,numbytes
|
||||
|
||||
const tym = tybasic(e.Ety);
|
||||
if (tym == TYucent && I64)
|
||||
{
|
||||
/* https://issues.dlang.org/show_bug.cgi?id=22175
|
||||
* The trouble happens when the struct size does not fit exactly into
|
||||
* 2 registers. Then the type of e becomes a TYucent, not a TYstruct,
|
||||
* and we need to dereference DI to get the ucent
|
||||
*/
|
||||
|
||||
// dereference DI
|
||||
code cs;
|
||||
cs.Iop = 0x8B;
|
||||
regm_t retregs = *pretregs;
|
||||
reg_t reg;
|
||||
allocreg(cdb,&retregs,®,tym);
|
||||
|
||||
reg_t msreg = findregmsw(retregs);
|
||||
buildEA(&cs,DI,-1,1,REGSIZE);
|
||||
code_newreg(&cs,msreg);
|
||||
cs.Irex |= REX_W;
|
||||
cdb.gen(&cs); // MOV msreg,REGSIZE[DI] // msreg is never DI
|
||||
|
||||
reg_t lsreg = findreglsw(retregs);
|
||||
buildEA(&cs,DI,-1,1,0);
|
||||
code_newreg(&cs,lsreg);
|
||||
cs.Irex |= REX_W;
|
||||
cdb.gen(&cs); // MOV lsreg,[DI];
|
||||
fixresult(cdb,e,retregs,pretregs);
|
||||
return;
|
||||
}
|
||||
|
||||
regm_t retregs = mDI;
|
||||
if (*pretregs & mMSW && !(config.exe & EX_flat))
|
||||
retregs |= mES;
|
||||
|
|
|
@ -871,7 +871,7 @@ version (SCPP)
|
|||
section_64 *psechdr = &SecHdrTab64[pseg.SDshtidx]; // corresponding section
|
||||
|
||||
// Do zero-fill the second time through this loop
|
||||
if (i ^ (psechdr.flags == S_ZEROFILL))
|
||||
if (i ^ (psechdr.flags == S_ZEROFILL || psechdr.flags == S_THREAD_LOCAL_ZEROFILL))
|
||||
continue;
|
||||
|
||||
int align_ = 1 << psechdr._align;
|
||||
|
@ -882,7 +882,7 @@ version (SCPP)
|
|||
}
|
||||
foffset = elf_align(align_, foffset);
|
||||
vmaddr = (vmaddr + align_ - 1) & ~(align_ - 1);
|
||||
if (psechdr.flags == S_ZEROFILL)
|
||||
if (psechdr.flags == S_ZEROFILL || psechdr.flags == S_THREAD_LOCAL_ZEROFILL)
|
||||
{
|
||||
psechdr.offset = 0;
|
||||
psechdr.size = pseg.SDoffset; // accumulated size
|
||||
|
@ -909,7 +909,7 @@ version (SCPP)
|
|||
section *psechdr = &SecHdrTab[pseg.SDshtidx]; // corresponding section
|
||||
|
||||
// Do zero-fill the second time through this loop
|
||||
if (i ^ (psechdr.flags == S_ZEROFILL))
|
||||
if (i ^ (psechdr.flags == S_ZEROFILL || psechdr.flags == S_THREAD_LOCAL_ZEROFILL))
|
||||
continue;
|
||||
|
||||
int align_ = 1 << psechdr._align;
|
||||
|
@ -920,7 +920,7 @@ version (SCPP)
|
|||
}
|
||||
foffset = elf_align(align_, foffset);
|
||||
vmaddr = (vmaddr + align_ - 1) & ~(align_ - 1);
|
||||
if (psechdr.flags == S_ZEROFILL)
|
||||
if (psechdr.flags == S_ZEROFILL || psechdr.flags == S_THREAD_LOCAL_ZEROFILL)
|
||||
{
|
||||
psechdr.offset = 0;
|
||||
psechdr.size = cast(uint)pseg.SDoffset; // accumulated size
|
||||
|
@ -1896,7 +1896,7 @@ int MachObj_getsegment(const(char)* sectname, const(char)* segname,
|
|||
|
||||
if (!pseg.SDbuf)
|
||||
{
|
||||
if (flags != S_ZEROFILL)
|
||||
if (flags != S_ZEROFILL && flags != S_THREAD_LOCAL_ZEROFILL)
|
||||
{
|
||||
pseg.SDbuf = cast(OutBuffer*) calloc(1, OutBuffer.sizeof);
|
||||
assert(pseg.SDbuf);
|
||||
|
@ -2421,7 +2421,9 @@ void MachObj_lidata(int seg,targ_size_t offset,targ_size_t count)
|
|||
{
|
||||
//printf("MachObj_lidata(%d,%x,%d)\n",seg,offset,count);
|
||||
size_t idx = SegData[seg].SDshtidx;
|
||||
if ((I64 ? SecHdrTab64[idx].flags : SecHdrTab[idx].flags) == S_ZEROFILL)
|
||||
|
||||
const flags = (I64 ? SecHdrTab64[idx].flags : SecHdrTab[idx].flags);
|
||||
if (flags == S_ZEROFILL || flags == S_THREAD_LOCAL_ZEROFILL)
|
||||
{ // Use SDoffset to record size of bss section
|
||||
SegData[seg].SDoffset += count;
|
||||
}
|
||||
|
|
|
@ -816,7 +816,7 @@ dmd -cov -unittest myprog.d
|
|||
Feature("field", "vfield",
|
||||
"list all non-mutable fields which occupy an object instance"),
|
||||
Feature("complex", "vcomplex",
|
||||
"give deprecation messages about all usages of complex or imaginary types", false, true),
|
||||
"give deprecation messages about all usages of complex or imaginary types", true, true),
|
||||
Feature("tls", "vtls",
|
||||
"list all variables going into thread local storage"),
|
||||
Feature("vmarkdown", "vmarkdown",
|
||||
|
@ -927,8 +927,6 @@ struct CLIUsage
|
|||
"Enables all available " ~ description)] ~ features;
|
||||
foreach (t; allTransitions)
|
||||
{
|
||||
if (t.deprecated_)
|
||||
continue;
|
||||
if (!t.documented)
|
||||
continue;
|
||||
buf ~= " =";
|
||||
|
@ -938,6 +936,8 @@ struct CLIUsage
|
|||
foreach (i; lineLength .. maxFlagLength)
|
||||
buf ~= " ";
|
||||
buf ~= t.helpText;
|
||||
if (t.deprecated_)
|
||||
buf ~= " [DEPRECATED]";
|
||||
buf ~= "\n";
|
||||
}
|
||||
return buf;
|
||||
|
|
|
@ -708,6 +708,31 @@ struct Scope
|
|||
return null;
|
||||
}
|
||||
|
||||
/********************************************
|
||||
* Find the lexically enclosing function (if any).
|
||||
*
|
||||
* This function skips through generated FuncDeclarations,
|
||||
* e.g. rewritten foreach bodies.
|
||||
*
|
||||
* Returns: the function or null
|
||||
*/
|
||||
inout(FuncDeclaration) getEnclosingFunction() inout
|
||||
{
|
||||
if (!this.func)
|
||||
return null;
|
||||
|
||||
auto fd = cast(FuncDeclaration) this.func;
|
||||
|
||||
// Look through foreach bodies rewritten as delegates
|
||||
while (fd.fes)
|
||||
{
|
||||
assert(fd.fes.func);
|
||||
fd = fd.fes.func;
|
||||
}
|
||||
|
||||
return cast(inout(FuncDeclaration)) fd;
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
* For TemplateDeclarations, we need to remember the Scope
|
||||
* where it was declared. So mark the Scope as not
|
||||
|
|
|
@ -1444,13 +1444,6 @@ private Type arrayExpressionToCommonType(Scope* sc, ref Expressions exps)
|
|||
Expression ex = condexp.expressionSemantic(sc);
|
||||
if (ex.op == EXP.error)
|
||||
e = ex;
|
||||
else if (e.op == EXP.function_ || e.op == EXP.delegate_)
|
||||
{
|
||||
// https://issues.dlang.org/show_bug.cgi?id=21285
|
||||
// Functions and delegates don't convert correctly with castTo below
|
||||
exps[i] = condexp.e1;
|
||||
e = condexp.e2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convert to common type
|
||||
|
@ -3743,7 +3736,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return setError();
|
||||
}
|
||||
|
||||
if (sd.hasRegularCtor() && nargs)
|
||||
// https://issues.dlang.org/show_bug.cgi?id=22639
|
||||
// If the new expression has arguments, we either should call a
|
||||
// regular constructor of a copy constructor if the first argument
|
||||
// is the same type as the struct
|
||||
if (nargs && (sd.hasRegularCtor() || (sd.ctor && (*exp.arguments)[0].type.mutableOf() == sd.type.mutableOf())))
|
||||
{
|
||||
FuncDeclaration f = resolveFuncCall(exp.loc, sc, sd.ctor, null, tb, exp.arguments, FuncResolveFlag.standard);
|
||||
if (!f || f.errors)
|
||||
|
@ -4504,7 +4501,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
If all constructors are copy constructors, then
|
||||
try default construction.
|
||||
*/
|
||||
if (!sd.hasRegularCtor)
|
||||
if (!sd.hasRegularCtor &&
|
||||
// https://issues.dlang.org/show_bug.cgi?id=22639
|
||||
// we might still have a copy constructor that could be called
|
||||
(*exp.arguments)[0].type.mutableOf != sd.type.mutableOf())
|
||||
goto Lx;
|
||||
|
||||
auto sle = new StructLiteralExp(exp.loc, sd, null, exp.e1.type);
|
||||
|
|
|
@ -2761,9 +2761,15 @@ bool stcToBuffer(OutBuffer* buf, StorageClass stc)
|
|||
bool result = false;
|
||||
|
||||
if (stc & STC.scopeinferred)
|
||||
{
|
||||
//buf.writestring("scope-inferred ");
|
||||
stc &= ~(STC.scope_ | STC.scopeinferred);
|
||||
}
|
||||
if (stc & STC.returninferred)
|
||||
{
|
||||
//buf.writestring("return-inferred ");
|
||||
stc &= ~(STC.return_ | STC.returninferred);
|
||||
}
|
||||
|
||||
/* Put scope ref return into a standard order
|
||||
*/
|
||||
|
|
|
@ -564,7 +564,12 @@ private int tryMain(size_t argc, const(char)** argv, ref Param params)
|
|||
}
|
||||
|
||||
if (params.addMain && !global.hasMainFunction)
|
||||
modules.push(moduleWithEmptyMain());
|
||||
{
|
||||
auto mainModule = moduleWithEmptyMain();
|
||||
modules.push(mainModule);
|
||||
if (!params.oneobj || modules.length == 1)
|
||||
params.objfiles.push(mainModule.objfile.toChars());
|
||||
}
|
||||
|
||||
generateCodeAndWrite(modules[], libmodules[], params.libname, params.objdir,
|
||||
params.lib, params.obj, params.oneobj, params.multiobj,
|
||||
|
|
|
@ -6272,9 +6272,6 @@ extern (C++) final class TypeClass : Type
|
|||
|
||||
override MOD deduceWild(Type t, bool isRef)
|
||||
{
|
||||
// If sym is forward referenced:
|
||||
if (sym.semanticRun < PASS.semanticdone && !sym.isBaseInfoComplete())
|
||||
sym.dsymbolSemantic(null);
|
||||
ClassDeclaration cd = t.isClassHandle();
|
||||
if (cd && (sym == cd || cd.isBaseOf(sym, null)))
|
||||
return Type.deduceWild(t, isRef);
|
||||
|
@ -7030,6 +7027,17 @@ extern (C++) final class Parameter : ASTNode
|
|||
|
||||
extern (D) private static bool isCovariantScope(bool returnByRef, StorageClass from, StorageClass to) pure nothrow @nogc @safe
|
||||
{
|
||||
// Workaround for failing covariance when finding a common type of delegates,
|
||||
// some of which have parameters with inferred scope
|
||||
// https://issues.dlang.org/show_bug.cgi?id=21285
|
||||
// The root cause is that scopeinferred is not part of the mangle, and mangle
|
||||
// is used for type equality checks
|
||||
if (to & STC.returninferred)
|
||||
to &= ~STC.return_;
|
||||
// note: f(return int* x) currently 'infers' scope without inferring `return`, in that case keep STC.scope
|
||||
if (to & STC.scopeinferred && !(to & STC.return_))
|
||||
to &= ~STC.scope_;
|
||||
|
||||
if (from == to)
|
||||
return true;
|
||||
|
||||
|
|
|
@ -3651,7 +3651,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
|
||||
case TOK.traits:
|
||||
if (AST.TraitsExp te = cast(AST.TraitsExp) parsePrimaryExp())
|
||||
if (te.ident && te.args)
|
||||
if (te.ident)
|
||||
{
|
||||
t = new AST.TypeTraits(token.loc, te);
|
||||
break;
|
||||
|
|
|
@ -2101,13 +2101,14 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
|
|||
return ErrorExp.get();
|
||||
}
|
||||
|
||||
if (sc.func is null)
|
||||
auto fd = sc.getEnclosingFunction();
|
||||
if (!fd)
|
||||
{
|
||||
e.error("`__traits(parameters)` may only be used inside a function");
|
||||
return ErrorExp.get();
|
||||
}
|
||||
assert(sc.func && sc.parent.isFuncDeclaration());
|
||||
auto tf = sc.parent.isFuncDeclaration.type.isTypeFunction();
|
||||
|
||||
auto tf = fd.type.isTypeFunction();
|
||||
assert(tf);
|
||||
auto exps = new Expressions(0);
|
||||
int addParameterDG(size_t idx, Parameter x)
|
||||
|
|
|
@ -1793,6 +1793,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
|
|||
mtype.exp.ident != Id.derivedMembers &&
|
||||
mtype.exp.ident != Id.getMember &&
|
||||
mtype.exp.ident != Id.parent &&
|
||||
mtype.exp.ident != Id.parameters &&
|
||||
mtype.exp.ident != Id.child &&
|
||||
mtype.exp.ident != Id.toType &&
|
||||
mtype.exp.ident != Id.getOverloads &&
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// REQUIRED_ARGS: -unittest
|
||||
// PERMUTE_ARGS: -preview=dip1000
|
||||
// Issue 21285 - Delegate covariance broken between 2.092 and 2.094 (git master).
|
||||
unittest
|
||||
{
|
||||
|
@ -25,3 +26,36 @@ unittest
|
|||
static assert(is(typeof(a[0]) == dg));
|
||||
static assert(is(typeof(ab[0]) == fn));
|
||||
}
|
||||
|
||||
int f(string s) { throw new Exception(""); }
|
||||
void main()
|
||||
{
|
||||
string path;
|
||||
int bank, preset;
|
||||
void delegate(string value)[string] aa = [
|
||||
"path": (string arg) {
|
||||
path = arg;
|
||||
},
|
||||
"bank": (string arg) {
|
||||
bank = f(arg);
|
||||
},
|
||||
"preset": (string arg) {
|
||||
preset = f(arg);
|
||||
},
|
||||
];
|
||||
|
||||
string delegate(string value)[string] aa2 = [
|
||||
"path": (string arg) {
|
||||
path = arg;
|
||||
return arg;
|
||||
},
|
||||
"bank": (string arg) {
|
||||
bank = f(arg);
|
||||
return arg;
|
||||
},
|
||||
"preset": (string arg) {
|
||||
preset = f(arg);
|
||||
return arg;
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
|
@ -20,6 +20,33 @@ int echoPlusOne(int x)
|
|||
return x;
|
||||
}
|
||||
static assert(echoPlusOne(1) == 2);
|
||||
|
||||
void nesting(double d, int i)
|
||||
{
|
||||
alias EXP = AliasSeq!(d, i);
|
||||
|
||||
if (d)
|
||||
{
|
||||
static assert(__traits(isSame, __traits(parameters), EXP));
|
||||
|
||||
while (d)
|
||||
{
|
||||
static assert(__traits(isSame, __traits(parameters), EXP));
|
||||
switch (i)
|
||||
{
|
||||
static assert(__traits(isSame, __traits(parameters), EXP));
|
||||
case 1:
|
||||
static assert(__traits(isSame, __traits(parameters), EXP));
|
||||
break;
|
||||
|
||||
default:
|
||||
static assert(__traits(isSame, __traits(parameters), EXP));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Tree {
|
||||
int opApply(int delegate(size_t, Tree) dg) {
|
||||
if (dg(0, this)) return 1;
|
||||
|
@ -34,7 +61,22 @@ void useOpApply(Tree top, int x)
|
|||
}
|
||||
foreach(idx, elem; top)
|
||||
{
|
||||
static assert(is(typeof(__traits(parameters)) == AliasSeq!(size_t, Tree)));
|
||||
static assert(is(typeof(__traits(parameters)) == AliasSeq!(Tree, int)));
|
||||
}
|
||||
|
||||
foreach(idx, elem; top)
|
||||
{
|
||||
foreach (idx2, elem2; elem)
|
||||
static assert(is(typeof(__traits(parameters)) == AliasSeq!(Tree, int)));
|
||||
}
|
||||
|
||||
foreach(idx, elem; top)
|
||||
{
|
||||
static void foo(char[] text)
|
||||
{
|
||||
foreach (const char c; text)
|
||||
static assert(is(typeof(__traits(parameters)) == AliasSeq!(char[])));
|
||||
}
|
||||
}
|
||||
}
|
||||
class Test
|
||||
|
@ -131,3 +173,65 @@ T testTemplate(T)(scope T input)
|
|||
}
|
||||
|
||||
static assert(testTemplate!long(420) == 0);
|
||||
|
||||
void qualifiers(immutable int a, const bool b)
|
||||
{
|
||||
static assert(is(typeof(__traits(parameters)) == AliasSeq!(immutable int, const bool)));
|
||||
}
|
||||
|
||||
int makeAggregate(int a, bool b)
|
||||
{
|
||||
struct S
|
||||
{
|
||||
typeof(__traits(parameters)) members;
|
||||
}
|
||||
|
||||
S s = S(__traits(parameters));
|
||||
assert(s.members[0] == a);
|
||||
assert(s.members[1] == b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static assert(makeAggregate(5, true));
|
||||
|
||||
int makeAlias(int a, bool b)
|
||||
{
|
||||
alias Params = __traits(parameters);
|
||||
assert(Params[0] == 3);
|
||||
assert(Params[1] == true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static assert(makeAlias(3, true));
|
||||
|
||||
|
||||
mixin template nestedCheckParameters(int unique)
|
||||
{
|
||||
alias NestedNames = __traits(parameters);
|
||||
version (Fixed)
|
||||
alias Types = typeof(Names);
|
||||
}
|
||||
|
||||
mixin template checkParameters(int unique)
|
||||
{
|
||||
mixin nestedCheckParameters!unique;
|
||||
|
||||
alias Names = __traits(parameters);
|
||||
alias Types = typeof(Names);
|
||||
}
|
||||
|
||||
int makeAggregateMixin(immutable int a, const bool b)
|
||||
{
|
||||
mixin checkParameters!0;
|
||||
|
||||
struct S
|
||||
{
|
||||
mixin checkParameters!1;
|
||||
typeof(Names) members;
|
||||
}
|
||||
|
||||
S s = S(Names);
|
||||
assert(s.members[0] == a);
|
||||
assert(s.members[1] == b);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -229,3 +229,19 @@ struct EmptyStruct2
|
|||
|
||||
static assert(EmptyStruct2.sizeof == 1);
|
||||
static assert(EmptyStruct2.noRet.offsetof == 0);
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=22858
|
||||
// Shouldn't mess with the alignment of other zero-sized types.
|
||||
|
||||
struct S22858
|
||||
{
|
||||
int a;
|
||||
void*[0] arr;
|
||||
char c;
|
||||
noreturn[0] arr2;
|
||||
char c2;
|
||||
}
|
||||
|
||||
static assert (S22858.arr.offsetof % size_t.sizeof == 0);
|
||||
static assert (S22858.arr2.offsetof == S22858.c.offsetof + 1);
|
||||
static assert (S22858.arr2.offsetof == S22858.c2.offsetof);
|
||||
|
|
26
test/compilable/test22639.d
Normal file
26
test/compilable/test22639.d
Normal file
|
@ -0,0 +1,26 @@
|
|||
// https://issues.dlang.org/show_bug.cgi?id=22639
|
||||
|
||||
struct A
|
||||
{
|
||||
this(ref return scope A rhs) inout {}
|
||||
this(ref return scope const A rhs, int b = 7) inout
|
||||
{
|
||||
if (b != 7) {
|
||||
this.b = b;
|
||||
}
|
||||
}
|
||||
|
||||
this(this) @disable;
|
||||
|
||||
int a=4;
|
||||
int b=3;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
A a = A();
|
||||
A c = A(a, 10);
|
||||
A d = void;
|
||||
d.__ctor(a, 200);
|
||||
A* b = new A(a, 10);
|
||||
}
|
|
@ -1,2 +1,3 @@
|
|||
// EXTRA_FILES: imports/test22714a.d imports/test22714b.d
|
||||
// https://issues.dlang.org/show_bug.cgi?id=22714
|
||||
import imports.test22714a;
|
||||
|
|
40
test/compilable/test22859.d
Normal file
40
test/compilable/test22859.d
Normal file
|
@ -0,0 +1,40 @@
|
|||
// https://issues.dlang.org/show_bug.cgi?id=22859
|
||||
private struct __InoutWorkaroundStruct {}
|
||||
@property T rvalueOf(T)(T val) { return val; }
|
||||
@property T rvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init);
|
||||
@property ref T lvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init);
|
||||
|
||||
// taken from std.traits.isAssignable
|
||||
template isAssignable(Lhs, Rhs = Lhs)
|
||||
{
|
||||
enum isAssignable = __traits(compiles, lvalueOf!Lhs = rvalueOf!Rhs) && __traits(compiles, lvalueOf!Lhs = lvalueOf!Rhs);
|
||||
}
|
||||
|
||||
// taken from std.meta.allSatisfy
|
||||
template allSatisfy(alias F, T...)
|
||||
{
|
||||
static foreach (Ti; T)
|
||||
{
|
||||
static if (!is(typeof(allSatisfy) == bool) && // not yet defined
|
||||
!F!(Ti))
|
||||
{
|
||||
enum allSatisfy = false;
|
||||
}
|
||||
}
|
||||
static if (!is(typeof(allSatisfy) == bool)) // if not yet defined
|
||||
{
|
||||
enum allSatisfy = true;
|
||||
}
|
||||
}
|
||||
|
||||
struct None{}
|
||||
|
||||
class C1
|
||||
{
|
||||
static if(allSatisfy!(isAssignable, None, C2)) {}
|
||||
}
|
||||
|
||||
class C2
|
||||
{
|
||||
static if(allSatisfy!(isAssignable, None, C1, C2)) {}
|
||||
}
|
62
test/compilable/test22860.d
Normal file
62
test/compilable/test22860.d
Normal file
|
@ -0,0 +1,62 @@
|
|||
// https://issues.dlang.org/show_bug.cgi?id=22860
|
||||
class C1
|
||||
{
|
||||
SumType!(C1, C2) field;
|
||||
}
|
||||
|
||||
class C2
|
||||
{
|
||||
SumType!(SumType!(C1, C2)) field;
|
||||
}
|
||||
|
||||
alias AliasSeq(TList...) = TList;
|
||||
|
||||
template allSatisfy(alias F, T...)
|
||||
{
|
||||
static foreach (Ti; T)
|
||||
{
|
||||
static if (!F!Ti)
|
||||
enum allSatisfy = false;
|
||||
}
|
||||
}
|
||||
|
||||
struct This {}
|
||||
|
||||
enum isAssignableTo(T) = isAssignable!T;
|
||||
enum isHashable(T) = __traits(compiles, { T.init; });
|
||||
|
||||
struct SumType(Types...)
|
||||
{
|
||||
alias Types = AliasSeq!(ReplaceTypeUnless!(isSumTypeInstance, This, typeof(this), TemplateArgsOf!SumType));
|
||||
|
||||
static foreach (T; Types)
|
||||
{
|
||||
static if (isAssignableTo!T)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
static if (allSatisfy!(isAssignableTo, Types))
|
||||
{
|
||||
}
|
||||
|
||||
static if (allSatisfy!(isHashable, Types))
|
||||
size_t toHash;
|
||||
}
|
||||
|
||||
bool isSumTypeInstance;
|
||||
|
||||
alias TemplateArgsOf(T : Base!Args, alias Base, Args...) = Args;
|
||||
enum isAssignable(Lhs, Rhs = Lhs) = isRvalueAssignable!(Lhs, Rhs) ;
|
||||
enum isRvalueAssignable(Lhs, Rhs ) = __traits(compiles, { lvalueOf!Lhs = Rhs; });
|
||||
|
||||
struct __InoutWorkaroundStruct{}
|
||||
T lvalueOf(T)(__InoutWorkaroundStruct );
|
||||
|
||||
template ReplaceTypeUnless(alias pred, From, To, T...)
|
||||
{
|
||||
static if (T.length == 1)
|
||||
alias ReplaceTypeUnless = T;
|
||||
static if (T.length > 1)
|
||||
alias ReplaceTypeUnless = AliasSeq!(ReplaceTypeUnless!(pred, From, To, T[1 ]));
|
||||
}
|
|
@ -6,6 +6,7 @@ TEST_OUTPUT:
|
|||
Language transitions listed by -transition=name:
|
||||
=all Enables all available language transitions
|
||||
=field list all non-mutable fields which occupy an object instance
|
||||
=complex give deprecation messages about all usages of complex or imaginary types [DEPRECATED]
|
||||
=tls list all variables going into thread local storage
|
||||
=vmarkdown list instances of Markdown replacements in Ddoc
|
||||
=in list all usages of 'in' on parameter
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/imports/foo10727a.d(34): Error: undefined identifier `Frop`
|
||||
fail_compilation/imports/foo10727a.d(26): Error: template instance `foo10727a.CirBuff!(Foo)` error instantiating
|
||||
fail_compilation/imports/foo10727a.d(31): instantiated from here: `Bar!(Foo)`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/imports/foo10727b.d(25): Error: undefined identifier `Frop`
|
||||
fail_compilation/imports/foo10727b.d(17): Error: template instance `foo10727b.CirBuff!(Foo)` error instantiating
|
||||
fail_compilation/imports/foo10727b.d(22): instantiated from here: `Bar!(Foo)`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
32
test/runnable/test22175.d
Normal file
32
test/runnable/test22175.d
Normal file
|
@ -0,0 +1,32 @@
|
|||
// https://issues.dlang.org/show_bug.cgi?id=22175
|
||||
|
||||
struct Struct
|
||||
{
|
||||
short a = 24, b = 25, c = 26, d = 27;
|
||||
ubyte e = 28;
|
||||
}
|
||||
|
||||
Struct foo() { Struct s; s.a = 60; s.b = 61; s.c = 62, s.d = 63; s.e = 64; return s; }
|
||||
|
||||
Struct test(int i) {
|
||||
Struct var = i ? Struct() : foo();
|
||||
Struct nest() { return var; }
|
||||
return nest();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
auto s = test(0);
|
||||
assert(s.a == 60);
|
||||
assert(s.b == 61);
|
||||
assert(s.c == 62);
|
||||
assert(s.d == 63);
|
||||
assert(s.e == 64);
|
||||
s = test(1);
|
||||
assert(s.a == 24);
|
||||
assert(s.b == 25);
|
||||
assert(s.c == 26);
|
||||
assert(s.d == 27);
|
||||
assert(s.e == 28);
|
||||
return 0;
|
||||
}
|
12
test/runnable/test22863.sh
Normal file
12
test/runnable/test22863.sh
Normal file
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# -main doesn't work anymore when used for linking only (without source modules)
|
||||
# https://issues.dlang.org/show_bug.cgi?id=22863
|
||||
|
||||
set -e
|
||||
|
||||
FOO=${OUTPUT_BASE}/foo${OBJ}
|
||||
|
||||
$DMD -m"${MODEL}" -c ${TEST_DIR}/testmain.d -of=$FOO
|
||||
$DMD -m"${MODEL}" -main $FOO -of=${OUTPUT_BASE}/result
|
||||
rm_retry -r ${OUTPUT_BASE}
|
Loading…
Add table
Add a link
Reference in a new issue