Skip to content

Commit

Permalink
isCopyConstructable should call isCopyable
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Oct 6, 2024
1 parent cbc0183 commit 970bc05
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 17 deletions.
5 changes: 3 additions & 2 deletions compiler/src/dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -3280,9 +3280,10 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
}
else if (p.storageClass & STC.ref_)
{
FuncDeclaration f;
if (global.params.rvalueRefParam == FeatureState.enabled &&
!arg.isLvalue() &&
targ.isCopyable())
targ.isCopyable(f))
{ /* allow rvalues to be passed to ref parameters by copying
* them to a temp, then pass the temp as the argument
*/
Expand Down Expand Up @@ -12253,7 +12254,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}

if (tb1.ty == Tpointer && tb2.ty == Tpointer ||
tb1.ty == Tnull && tb2.ty == Tnull)
tb1.ty == Tnull && tb2.ty == Tnull)
{
result = exp.incompatibleTypes();
return;
Expand Down
3 changes: 2 additions & 1 deletion compiler/src/dmd/traits.d
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,8 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
ts.sym.dsymbolSemantic(sc);
}

return isCopyable(t) ? True() : False();
FuncDeclaration f;
return isCopyable(t, f) ? True() : False();
}

if (e.ident == Id.isNested)
Expand Down
29 changes: 23 additions & 6 deletions compiler/src/dmd/typesem.d
Original file line number Diff line number Diff line change
Expand Up @@ -437,10 +437,11 @@ private Dsymbol searchX(Dsymbol dsym, const ref Loc loc, Scope* sc, RootObject i
* Determine if type t is copyable.
* Params:
* t = type to check
* f = set to constructor that would be called, if any
* Returns:
* true if we can copy it
*/
bool isCopyable(Type t)
bool isCopyable(Type t, out FuncDeclaration f)
{
//printf("isCopyable() %s\n", t.toChars());
if (auto ts = t.isTypeStruct())
Expand All @@ -458,7 +459,7 @@ bool isCopyable(Type t)
el.type = cast() ts;
Expressions* args = new Expressions();
args.push(el);
FuncDeclaration f = resolveFuncCall(Loc.initial, null, ctor, null, cast()ts, ArgumentList(args), FuncResolveFlag.quiet);
f = resolveFuncCall(Loc.initial, null, ctor, null, cast()ts, ArgumentList(args), FuncResolveFlag.quiet);
if (!f || f.storage_class & STC.disable)
return false;
}
Expand Down Expand Up @@ -882,14 +883,29 @@ extern (D) MATCH callMatch(TypeFunction tf, Type tthis, ArgumentList argumentLis
private extern(D) bool isCopyConstructorCallable (StructDeclaration argStruct,
Expression arg, Type tprm, Scope* sc, const(char)** pMessage)
{
FuncDeclaration f;

bool b1 = isCopyable(argStruct.type, f);

auto tmp = new VarDeclaration(arg.loc, tprm, Identifier.generateId("__copytmp"), null);
tmp.storage_class = STC.rvalue | STC.temp | STC.ctfe;
tmp.dsymbolSemantic(sc);
Expression ve = new VarExp(arg.loc, tmp);
Expression e = new DotIdExp(arg.loc, ve, Id.ctor);
e = new CallExp(arg.loc, e, arg);
//printf("e = %s\n", e.toChars());
if (dmd.expressionsem.trySemantic(e, sc))

bool b2 = dmd.expressionsem.trySemantic(e, sc) !is null;

if (b1 != b2)
{
fprintf(stderr, "b1: %d b2: %d\n", b1, b2);
fprintf(stderr, "e: %s\n", e.toChars());
fprintf(stderr, "tprm: %s\n", toChars(tprm));
if (f)
fprintf(stderr, "f: %s\n", toChars(f.type));
}
if (b1)
return true;

if (!pMessage)
Expand All @@ -904,7 +920,7 @@ private extern(D) bool isCopyConstructorCallable (StructDeclaration argStruct,
* such as purity, safety or nogc.
*/
OutBuffer buf;
auto callExp = e.isCallExp();
// auto callExp = e.isCallExp();

bool nocpctor()
{
Expand All @@ -914,7 +930,7 @@ private extern(D) bool isCopyConstructorCallable (StructDeclaration argStruct,
return false;
}

auto f = callExp.f;
// auto f = callExp.f;
if (!f)
return nocpctor();

Expand Down Expand Up @@ -1043,6 +1059,7 @@ private extern(D) MATCH argumentMatchParameter (TypeFunction tf, Parameter p,
return MATCH.nomatch;
}

FuncDeclaration f;
if (arg.op == EXP.string_ && tp.ty == Tsarray)
{
if (ta.ty != Tsarray)
Expand Down Expand Up @@ -1077,7 +1094,7 @@ private extern(D) MATCH argumentMatchParameter (TypeFunction tf, Parameter p,
}
else if (global.params.rvalueRefParam != FeatureState.enabled ||
p.storageClass & STC.out_ ||
!arg.type.isCopyable()) // can't copy to temp for ref parameter
!arg.type.isCopyable(f)) // can't copy to temp for ref parameter
{
if (pMessage) *pMessage = tf.getParamError(arg, p);
return MATCH.nomatch;
Expand Down
6 changes: 1 addition & 5 deletions compiler/test/compilable/test23097.d
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@
REQUIRED_ARGS: -verrors=spec
TEST_OUTPUT:
---
(spec:2) compilable/test23097.d(14): Error: `inout` constructor `test23097.S23097.this` creates const object, not mutable
(spec:2) compilable/test23097.d(14): Error: `inout` constructor `test23097.S23097.this` creates const object, not mutable
(spec:1) compilable/test23097.d(14): Error: generated function `test23097.S23097.opAssign(S23097 p)` is not callable using argument types `(const(S23097))`
(spec:2) compilable/test23097.d(14): Error: `inout` constructor `test23097.S23097.this` creates const object, not mutable
(spec:1) compilable/test23097.d(14): `struct S23097` does not define a copy constructor for `const(S23097)` to `S23097` copies
(spec:1) compilable/test23097.d(10): Error: `inout` constructor `test23097.S23097.this` creates const object, not mutable
---
*/
void emplaceRef(UT, Args)(UT chunk, Args args)
Expand Down
7 changes: 4 additions & 3 deletions compiler/test/fail_compilation/fail22202.d
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail22202.d(22): Error: function `fun` is not callable using argument types `(SystemCopy)`
fail_compilation/fail22202.d(22): `inout ref inout(SystemCopy)(ref inout(SystemCopy) other)` copy constructor cannot be called from a `pure @safe nogc` context
fail_compilation/fail22202.d(17): `fail22202.fun(SystemCopy __param_0)` declared here
fail_compilation/fail22202.d(23): Error: `pure` function `D main` cannot call impure copy constructor `fail22202.SystemCopy.this`
fail_compilation/fail22202.d(23): Error: `@safe` function `D main` cannot call `@system` copy constructor `fail22202.SystemCopy.this`
fail_compilation/fail22202.d(15): `fail22202.SystemCopy.this` is declared here
fail_compilation/fail22202.d(23): Error: `@nogc` function `D main` cannot call non-@nogc copy constructor `fail22202.SystemCopy.this`
---
*/

Expand Down

0 comments on commit 970bc05

Please sign in to comment.