From f39572d4aaf9606bc8d9bd44e90f4d681ce80be7 Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Sat, 5 Oct 2024 16:49:13 -0700 Subject: [PATCH] isCopyConstructable should call isCopyable --- compiler/src/dmd/expressionsem.d | 5 +++-- compiler/src/dmd/traits.d | 3 ++- compiler/src/dmd/typesem.d | 21 +++++++++++++++------ compiler/test/compilable/test23097.d | 6 +----- compiler/test/fail_compilation/fail22202.d | 7 ++++--- 5 files changed, 25 insertions(+), 17 deletions(-) diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index ef6c1bd07932..aba99556ad88 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -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 */ @@ -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; diff --git a/compiler/src/dmd/traits.d b/compiler/src/dmd/traits.d index e065975c67a8..8e0b147038b6 100644 --- a/compiler/src/dmd/traits.d +++ b/compiler/src/dmd/traits.d @@ -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) diff --git a/compiler/src/dmd/typesem.d b/compiler/src/dmd/typesem.d index f947dd33174e..c256c722d583 100644 --- a/compiler/src/dmd/typesem.d +++ b/compiler/src/dmd/typesem.d @@ -440,7 +440,7 @@ private Dsymbol searchX(Dsymbol dsym, const ref Loc loc, Scope* sc, RootObject i * 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()) @@ -458,7 +458,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; } @@ -881,6 +881,14 @@ 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; +static if (1) +{ + if (isCopyable(argStruct.type, f)) + return true; +} +else { auto tmp = new VarDeclaration(arg.loc, tprm, Identifier.generateId("__copytmp"), null); tmp.storage_class = STC.rvalue | STC.temp | STC.ctfe; @@ -891,7 +899,7 @@ private extern(D) bool isCopyConstructorCallable (StructDeclaration argStruct, //printf("e = %s\n", e.toChars()); if (dmd.expressionsem.trySemantic(e, sc)) return true; - +} if (!pMessage) return false; @@ -904,7 +912,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() { @@ -914,7 +922,7 @@ private extern(D) bool isCopyConstructorCallable (StructDeclaration argStruct, return false; } - auto f = callExp.f; +// auto f = callExp.f; if (!f) return nocpctor(); @@ -1043,6 +1051,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) @@ -1077,7 +1086,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; diff --git a/compiler/test/compilable/test23097.d b/compiler/test/compilable/test23097.d index 092bd774f228..3c2445ff9a20 100644 --- a/compiler/test/compilable/test23097.d +++ b/compiler/test/compilable/test23097.d @@ -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(7): Error: `inout` constructor `test23097.S23097.this` creates const object, not mutable --- */ void emplaceRef(UT, Args)(UT chunk, Args args) diff --git a/compiler/test/fail_compilation/fail22202.d b/compiler/test/fail_compilation/fail22202.d index 9fb5165a711f..7932af4b7eb5 100644 --- a/compiler/test/fail_compilation/fail22202.d +++ b/compiler/test/fail_compilation/fail22202.d @@ -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` --- */