Skip to content
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

Fix #20595 - automatically unittest destroy(T.init) #20598

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

thewilsonator
Copy link
Contributor

No description provided.

@thewilsonator thewilsonator added Review:Needs Changelog A changelog entry needs to be added to /changelog Review:WIP Work In Progress - not ready for review or pulling labels Dec 23, 2024
@dlang-bot
Copy link
Contributor

Thanks for your pull request and interest in making D better, @thewilsonator! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the coverage diff by visiting the details link of the codecov check)
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

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 "master + dmd#20598"

@thewilsonator thewilsonator force-pushed the thewilsonator-patch-35 branch 3 times, most recently from a5431c3 to 0d1bb53 Compare December 24, 2024 00:26
static if (is (T == struct) && is(typeof(T.init) == T))
{
/// Verify that `destroy` works with `T.init`.
/// TODO: explain why
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @pbackus could you please provide a detailed explanation here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Short answer: I was wrong. Close this.

Long answer: the requirement I was thinking of is that destroying T.init must not cause undefined behavior, because T.init is always available in @safe code. But that does not mean it has to succeed—it could still throw an exception, enter an infinite loop, terminate the process, etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Long answer: the requirement I was thinking of is that destroying T.init must not cause undefined behavior, because T.init is always available in @safe code. But that does not mean it has to succeed—it could still throw an exception, enter an infinite loop, terminate the process, etc.

I don't think you can even rely on T.init always being available in @safe code due to it still being possible to define an init() method, which may be @system.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if a type defines an init() method, you can still obtain its .init value by using something like (T[1]).init.

There is currently no reliable way to prevent @safe code from accessing a type's .init value.

Copy link
Contributor

@Herringway Herringway Dec 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is currently no reliable way to prevent @safe code from accessing a type's .init value.

A @system init field is also legal - struct Foo { @system noreturn init; }, for example. The (T[1]).init trick doesn't work around that one. It's only a deprecation right now, so TECHNICALLY it's allowed... for now.

Whoops, testing error

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works for me, even with -preview=systemVariables enabled:

struct S
{
    int n = 123;
    @disable this();
    @system noreturn init;
}

void main() @safe
{
    auto a = (S[1]).init;
    assert(a[0].n == 123); // passes
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm:

struct S
{
    int n = 123;
    //@disable this();
    @system static immutable S init;
}

void main() @safe
{
    auto a = S.init;
    assert(a.n == 123); // passes
}

successfully compiles with -preview=systemVariables which seems like a bug to me

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's definitely a bug, but it's also irrelevant to this PR which—again—should be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Review:Needs Changelog A changelog entry needs to be added to /changelog Review:WIP Work In Progress - not ready for review or pulling
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants