Skip to content

fix #21478: Ref parameter overload not called when struct implements copy constructor #21493

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 5, 2025

Conversation

ibuclaw
Copy link
Member

@ibuclaw ibuclaw commented Jun 29, 2025

If a struct implemented a copy constructor, then an rvalue opAssign would be given a better match score than the lvalue opAssign regardless of the ref-ness of the argument.

struct S
{
    this(ref return scope S);
    ref S opAssign(const ref S);
    ref S opAssign(const S);
}

s1 = s2;  // lowered as:  S.opAssign(&s1, *S.this(s2));

This change optimizes the assignment as:

s1 = s2;  // lowered as: S.opAssign(&s1, &s2);

Essentially, this is same as C++ semantics on object that implements rule of five.

@dlang-bot
Copy link
Contributor

Thanks for your pull request, @ibuclaw!

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

⚠️⚠️⚠️ Warnings ⚠️⚠️⚠️

  • In preparation for migrating from Bugzilla to GitHub Issues, the issue reference syntax has changed. Please add the word "Bugzilla" to issue references. For example, Fix Bugzilla Issue 12345 or Fix Bugzilla 12345.(Reminder: the edit needs to be done in the Git commit message, not the GitHub pull request.)

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "stable + dmd#21493"

@ibuclaw ibuclaw force-pushed the issue21478 branch 6 times, most recently from f5866ad to 537ce5b Compare July 1, 2025 20:26
@ibuclaw ibuclaw changed the title fix #21478: Copy assignment not called when struct implements rule of five fix #21478: Ref parameter overload not called when struct implements copy constructor Jul 1, 2025
@ibuclaw
Copy link
Member Author

ibuclaw commented Jul 1, 2025

Looks like this has found a wrong @nogc diagnostic coming from a speculative context.

source/mir/algebraic.d(2659,19): Error: `@nogc` function `mir.algebraic.__unittest_L2622_C24` cannot call non-@nogc constructor `mir.algebraic.Algebraic!(C4, S4).Algebraic.__ctor!(immutable(Algebraic!(C4, S4)), S4).this`
    immutable b = immutable V(s);
                  ^
source/mir/algebraic.d(2046,50):        and allocating with `new` makes it fail to infer `@nogc`
            enum CanCompile = __traits(compiles, new Q(forward!args));

Changing new to scope new suppresses this, but that shouldn't be necessary.

--- a/source/mir/algebraic.d
+++ b/source/mir/algebraic.d
@@ -2043,7 +2043,7 @@ struct Algebraic(T__...)
         template CanCompile(T)
         {
             alias Q = CopyTypeQualifiers!(This, T);
-            enum CanCompile = __traits(compiles, new Q(forward!args));
+            enum CanCompile = __traits(compiles, { scope q = new Q(forward!args); });
         }
 
         alias TargetType = Filter!(CanCompile, _ReflectionTypes);

@ibuclaw
Copy link
Member Author

ibuclaw commented Jul 4, 2025

Blocked by #21504

@thewilsonator
Copy link
Contributor

dependant PR merged. Please rebase to restart the CI.

…ents cpctor

If a struct implemented a copy constructor, then an rvalue opAssign
would be given a better match score than the lvalue opAssign regardless
of the ref-ness of the argument.
```
struct S
{
    this(ref return scope S);
    ref S opAssign(const ref S);
    ref S opAssign(const S);
}

s1 = s2;  // lowered as:  S.opAssign(&s1, *S.this(s2));
```

This change optimizes the assignment as:
```
s1 = s2;  // lowered as: S.opAssign(&s1, &s2);
```

Closes: dlang#21478
@thewilsonator thewilsonator merged commit 8ab5cad into dlang:stable Jul 5, 2025
69 of 74 checks passed
@ibuclaw ibuclaw deleted the issue21478 branch July 5, 2025 12:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Ref parameter overload not called when struct implements copy constructor
3 participants