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 Issue 18157 - std.file.rmdirRecurse should be usable in @safe #7675

Merged
merged 1 commit into from Oct 29, 2020

Conversation

ljmf00
Copy link
Member

@ljmf00 ljmf00 commented Oct 22, 2020

rmdirRecurse should be @safe as the cast(string) is safe in this context and
dirEntries, even though @System, it uses a RefCounted iterator which inside
will always make the reference deleted as the reference will never be passed
outside the function scope.

Signed-off-by: Luís Ferreira contact@lsferreira.net

@dlang-bot
Copy link
Contributor

Thanks for your pull request and interest in making D better, @ljmf00! 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.

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 + phobos#7675"

@ljmf00
Copy link
Member Author

ljmf00 commented Oct 22, 2020

Please tell if I'm thinking in a wrong way and there's logic that need to be added in order to make this properly @safe , but AFAIK this shouldn't be a problem.

Copy link
Contributor

@thewilsonator thewilsonator left a comment

Choose a reason for hiding this comment

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

The general idea is to have @trusted as narrow in scope as possible

std/file.d Show resolved Hide resolved
std/file.d Outdated
@@ -4444,6 +4445,7 @@ void rmdirRecurse(scope const(char)[] pathname)
}

/// ditto
@trusted
Copy link
Contributor

Choose a reason for hiding this comment

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

What needs to be @trusted in this function?

Copy link
Member Author

Choose a reason for hiding this comment

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

dirEntries is @System, so that's why it needs @trusted attribute. In this context, I consider this being safe because dirEntries returns a RefCounted wrapped variable, that, inside this will always be eliminated, so it doesn't make much sense to be unsafe here, IMHO.

The unsafe part is here:

foreach (DirEntry e; dirEntries(de.name, SpanMode.depth, false))
{
    attrIsDir(e.linkAttributes) ? rmdir(e.name) : remove(e.name);
}

Copy link
Contributor

Choose a reason for hiding this comment

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

is it the call to dirEntries, or the iteration or both? What about rmdir/remove?

Copy link
Member

Choose a reason for hiding this comment

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

Can't we use a local @trusted lambda + a comment to make sure nothing unsafe gets added in the future?

Copy link
Member Author

Choose a reason for hiding this comment

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

is it the call to dirEntries, or the iteration or both? What about rmdir/remove?

both rmdir and remove uses a @trusted trustedRmdir and removeImpl respectively, so, when called it's both @safe calls.

Can't we use a local @trusted lambda + a comment to make sure nothing unsafe gets added in the future?

Sure, I'll do it.

Also, if you follow this example here,

foreach (DirEntry de; dirEntries(tzDatabaseDir, SpanMode.depth))
, they are also using dirEntries in a @trusted function, so maybe it should be a good idea to wrap it too. I'll do it in another PR.

@thewilsonator
Copy link
Contributor

Does this have an issue number?

Copy link
Member

@wilzbach wilzbach left a comment

Choose a reason for hiding this comment

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

.

@ljmf00
Copy link
Member Author

ljmf00 commented Oct 26, 2020

Does this have an issue number?

Yes, https://issues.dlang.org/show_bug.cgi?id=18157 . I'll change the PR title.

Also, I don't think the dependency there to https://issues.dlang.org/show_bug.cgi?id=18155 is necessary, because, since dirEntries are using a RefConted object to increase performance and to not rely on GC.

@ljmf00 ljmf00 changed the title file: make rmdirRecurse @safe Fix Issue 18157: file: make rmdirRecurse @safe Oct 26, 2020
@ljmf00 ljmf00 changed the title Fix Issue 18157: file: make rmdirRecurse @safe Fix Issue 18155 - std.file.dirEntries should be usable in @safe Oct 26, 2020
@ljmf00 ljmf00 changed the title Fix Issue 18155 - std.file.dirEntries should be usable in @safe Fix Issue 18157 - std.file.rmdirRecurse should be usable in @safe Oct 26, 2020
@ljmf00
Copy link
Member Author

ljmf00 commented Oct 26, 2020

My fault, I referenced the wrong issue. Already updated the title again.

Copy link
Contributor

@edi33416 edi33416 left a comment

Choose a reason for hiding this comment

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

Can it also be marked as pure?

std/file.d Outdated Show resolved Hide resolved
@ljmf00
Copy link
Member Author

ljmf00 commented Oct 26, 2020

Can it also be marked as pure?

No. This function can't be pure in any way because it calls impure functions and this perform I/O.

`rmdirRecurse` should be @safe as the cast(string) is safe in this context and
dirEntries, even though @System, it uses a RefCounted iterator which inside
will always make the reference deleted as the reference will never be passed
outside the function scope.

Signed-off-by: Luís Ferreira <contact@lsferreira.net>
Copy link
Contributor

@edi33416 edi33416 left a comment

Choose a reason for hiding this comment

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

lgtm

}
// dirEntries is @system because it uses a DirIterator with a
// RefCounted variable, but here, no references to the payload is
// escaped to the outside, so this should be @trusted
Copy link
Contributor

Choose a reason for hiding this comment

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

Can't this be verified by the compiler by making the ref DirEntry de scope?

Copy link
Member Author

Choose a reason for hiding this comment

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

No because .dirEntries is @System and scope will do nothing about safety here. RefCounted is @System because the implementation uses malloc/free.

Copy link
Member Author

Choose a reason for hiding this comment

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

See this interesting discussion about @safe ref counting on dlang forum: https://forum.dlang.org/thread/r8ilpu$2mk7$1@digitalmars.com

@dlang-bot dlang-bot merged commit 5ce45f9 into dlang:master Oct 29, 2020
@ljmf00
Copy link
Member Author

ljmf00 commented Nov 2, 2020

@wilzbach the bot didn't detected the issue Fix even though merged with Fix Issue xxx https://issues.dlang.org/show_bug.cgi?id=18157. Can this be closed?

@wilzbach
Copy link
Member

wilzbach commented Nov 2, 2020

The bot only parses the commit messages as they are used to assemble the changelog. That's why it's important to check whether the issue displays in its commit message. We can't do much more than closing the issue manually and likely it will end up in the changelog because of the merge commit title.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants