Skip to content

Commit

Permalink
factor out isRvalueConstructor() (#16877)
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright authored Sep 24, 2024
1 parent b856040 commit 2d437de
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 28 deletions.
12 changes: 2 additions & 10 deletions compiler/src/dmd/clone.d
Original file line number Diff line number Diff line change
Expand Up @@ -1637,16 +1637,8 @@ bool needCopyCtor(StructDeclaration sd, out bool hasCpCtor)
return 0;
}

auto tf = ctorDecl.type.toTypeFunction();
const dim = tf.parameterList.length;
if (dim == 1 || (dim > 1 && tf.parameterList[1].defaultArg))
{
auto param = tf.parameterList[0];
if (param.type.mutableOf().unSharedOf() == sd.type.mutableOf().unSharedOf())
{
rvalueCtor = ctorDecl;
}
}
if (isRvalueConstructor(sd, ctorDecl))
rvalueCtor = ctorDecl;
return 0;
});

Expand Down
49 changes: 32 additions & 17 deletions compiler/src/dmd/dsymbolsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -242,38 +242,53 @@ package bool allowsContractWithoutBody(FuncDeclaration funcdecl)
}

/*
Tests whether the `ctor` that is part of `ti` is an rvalue constructor
(i.e. a constructor that receives a single parameter of the same type as
`Unqual!typeof(this)`). If that is the case and `sd` contains a copy
constructor, than an error is issued.
If sd has a copy constructor and ctor is an rvalue constructor,
issue an error.
Params:
sd = struct declaration that may contin both an rvalue and copy constructor
ctor = constructor that will be checked if it is an evalue constructor
sd = struct declaration that may contain both an rvalue and copy constructor
ctor = constructor that will be checked if it is an rvalue constructor
ti = template instance the ctor is part of
Return:
`false` if ctor is not an rvalue constructor or if `sd` does not contain a
copy constructor. `true` otherwise
`true` if sd has a copy constructor and ctor is an rvalue constructor
*/
bool checkHasBothRvalueAndCpCtor(StructDeclaration sd, CtorDeclaration ctor, TemplateInstance ti)
{
auto loc = ctor.loc;
auto tf = cast(TypeFunction)ctor.type;
auto dim = tf.parameterList.length;
if (sd && sd.hasCopyCtor && (dim == 1 || (dim > 1 && tf.parameterList[1].defaultArg)))
if (sd && sd.hasCopyCtor && isRvalueConstructor(sd, ctor))
{
.error(ctor.loc, "cannot define both an rvalue constructor and a copy constructor for `struct %s`", sd.toChars());
.errorSupplemental(ti.loc, "Template instance `%s` creates an rvalue constructor for `struct %s`",
ti.toPrettyChars(), sd.toChars());

return true;
}

return false;
}

/************************************************
* Check if ctor is an rvalue constructor.
* A constructor that receives a single parameter of the same type as
* `Unqual!typeof(this)` is an rvalue constructor.
* Params:
* sd = struct that ctor is a member of
* ctor = constructor to test
* Returns:
* true if it is an rvalue constructor
*/
bool isRvalueConstructor(StructDeclaration sd, CtorDeclaration ctor)
{
auto tf = ctor.type.isTypeFunction();
const dim = tf.parameterList.length;
if (dim == 1 || (dim > 1 && tf.parameterList[1].defaultArg))
{
auto param = tf.parameterList[0];
if (!(param.storageClass & STC.ref_) && param.type.mutableOf().unSharedOf() == sd.type.mutableOf().unSharedOf())
{
.error(loc, "cannot define both an rvalue constructor and a copy constructor for `struct %s`", sd.toChars());
.errorSupplemental(ti.loc, "Template instance `%s` creates an rvalue constructor for `struct %s`",
ti.toPrettyChars(), sd.toChars());

return true;
}
}

return false;
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dmd/target.d
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ extern (C++) struct Target
{
// isX86_64 and cpu are initialized in parseCommandLine
isX86 = !isX86_64;
assert(isX86 + isX86_64 + isAArch64 == 1); // there can be only one
assert(isX86 + isX86_64 + isAArch64 == 1); // there can be only one

this.params = &params;

Expand Down

0 comments on commit 2d437de

Please sign in to comment.