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

Allow -preview=in only with extern(D|C++) #12242

Merged
merged 1 commit into from
Jun 20, 2022

Conversation

Geod24
Copy link
Member

@Geod24 Geod24 commented Mar 1, 2021

The intent of `-preview=in` is to make `in` the go-to storage class for input parameters.
In doing so, it makes the ABI less obvious (although still deterministic),
by sometimes degrading the parameter from reference to a value if it is better ABI-wise.
This behavior is obviously at odds with non-`extern(D)` functions,
which expect to match a specific ABI, hence `in` parameters can no longer apply
to non-`extern(D)` or `extern(C++)` functions when `-preview=in` is used.

However, as C++, also have a "go to" storage class for input parameters (`const T&`),
`in` can also be applied on `extern(C++)` function in order to bind to `const T&` parameters.
When doing so, `in` will always mean `ref`. This also allows to expose a closer API
for a function than via `const ref`, as `in` will allow to bind rvalues to `const T&`, as in C++.

@kinke @ibuclaw : Any opinion on this ? If this is too much, I can see two other course of action:

  • Disabling in for anything non-extern(D);
  • Making in always make scope const with extern(C), never ref, disable for others;

@dlang-bot
Copy link
Contributor

dlang-bot commented Mar 1, 2021

Thanks for your pull request, @Geod24!

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

@Geod24 Geod24 requested review from ibuclaw and kinke March 1, 2021 04:50
@Geod24 Geod24 changed the title -preview=in can now be used with extern(C++), disabled for other non-D linkage Allow -preview=in only with extern(D|C++) Mar 1, 2021
Geod24 added a commit to Geod24/druntime that referenced this pull request Mar 1, 2021
Geod24 added a commit to Geod24/druntime that referenced this pull request Mar 1, 2021
dlang-bot pushed a commit to dlang/druntime that referenced this pull request Mar 1, 2021
Geod24 added a commit to Geod24/druntime that referenced this pull request Mar 1, 2021
The argument is sent to another process, and can contain a pointer.
Additionally, there is currently a PR in DMD to forbid using
'in' with extern(C) functions when '-preview=in' is provided
(dlang/dmd#12242).
@Geod24
Copy link
Member Author

Geod24 commented Mar 1, 2021

Maybe the const solution for extern(C) is the best way forward. After all, we allow to pass D arrays to extern(C) functions (https://github.com/dlang/druntime/blob/0125219f894a43d2ab0a7571b690c96e400051ca/src/rt/aApply.d#L21).

dlang-bot pushed a commit to dlang/druntime that referenced this pull request Mar 1, 2021
The argument is sent to another process, and can contain a pointer.
Additionally, there is currently a PR in DMD to forbid using
'in' with extern(C) functions when '-preview=in' is provided
(dlang/dmd#12242).
@PetarKirov
Copy link
Member

Keep in mind that scope is meaningless for non-extern (D) functions that are not implemented in D, as C and C++ compilers won't enforce that the parameter are not escaped, so while in means const scope maybe-ref in D, it should be translated as exactly const ref for C and C++.

@kinke
Copy link
Contributor

kinke commented Mar 1, 2021

Disabling in for anything non-extern(D)

I think I'd prefer that for simplicity, otherwise the in semantics get too complicated.

Edit: This also allows to expose a closer API for a function than via 'const ref', as 'in' will allow to bind rvalues to 'const T&', as in C++. Hmm okay that'd be nice indeed...

@Geod24
Copy link
Member Author

Geod24 commented Mar 2, 2021

Keep in mind that scope is meaningless for non-extern (D) functions that are not implemented in D

Not exactly meaningless, since the compiler will check scope if called from a @safe context. And yes, we have some in druntime.

I think I'd prefer that for simplicity, otherwise the in semantics get too complicated.
[...]
Hmm okay that'd be nice indeed...

That was exactly my thought process. Maybe @ibuclaw can weight in ?

@PetarKirov
Copy link
Member

PetarKirov commented Mar 2, 2021

compiler will check scope if called from a @safe context

That's actual the main problem. scope parameters allow allow more code in @safe functions, not less. For example, functions can to receive pointers/references to local variables in @safe code via scope parameters. This is under the assumption that the callee is implemented in D and the compiler has verified that it doesn't escape the address of its scope parameters. If the function is implemented in another language, this assumption doesn't hold any more.

This also allows to expose a closer API for a function than via 'const ref', as 'in' will allow to bind rvalues to 'const T&', as in C++.

P.S. I also think this would be nice.

@Geod24
Copy link
Member Author

Geod24 commented Mar 2, 2021

If the function is implemented in another language, this assumption doesn't hold any more.

The same can be said of other attributes. IMO C++ const's situation is even worse, are we could be forced to apply const to a parameter even though it is mutated.

n8sh pushed a commit to n8sh/druntime that referenced this pull request Mar 3, 2021
n8sh pushed a commit to n8sh/druntime that referenced this pull request Mar 3, 2021
The argument is sent to another process, and can contain a pointer.
Additionally, there is currently a PR in DMD to forbid using
'in' with extern(C) functions when '-preview=in' is provided
(dlang/dmd#12242).
rymrg pushed a commit to rymrg/druntime that referenced this pull request Mar 15, 2021
rymrg pushed a commit to rymrg/druntime that referenced this pull request Mar 15, 2021
The argument is sent to another process, and can contain a pointer.
Additionally, there is currently a PR in DMD to forbid using
'in' with extern(C) functions when '-preview=in' is provided
(dlang/dmd#12242).
@atilaneves
Copy link
Contributor

I think it makes sense to be able to declare parameters to be scope even in extern(C) code, especially considering that just because functions have that linkage doesn't imply they're actually written in C.

And even if they are, I for one would like to tell the compiler that they're not escaped.

Chigusa0w0 pushed a commit to Chigusa0w0/druntime that referenced this pull request May 2, 2021
Chigusa0w0 pushed a commit to Chigusa0w0/druntime that referenced this pull request May 2, 2021
The argument is sent to another process, and can contain a pointer.
Additionally, there is currently a PR in DMD to forbid using
'in' with extern(C) functions when '-preview=in' is provided
(dlang/dmd#12242).
@Geod24 Geod24 force-pushed the preview-in-extern-cpp branch 5 times, most recently from 3253bd3 to cfab94c Compare June 16, 2022 22:58
@Geod24
Copy link
Member Author

Geod24 commented Jun 16, 2022

I think this is finally passing the CI (!)

@thewilsonator
Copy link
Contributor

Final ping: @kinke @ibuclaw

@thewilsonator thewilsonator added the Merge:72h no objection -> merge The PR will be merged if there are no objections raised. label Jun 17, 2022
@@ -0,0 +1,11 @@
`-preview=in` can now be used with `extern(C++)`, disabled for other non-D linkage

The intent of `-preview=in` is to make `in` the go-to storage class for input parameters in D.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this official vision?

Copy link
Member Author

Choose a reason for hiding this comment

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

Has Walter said those words exactly? Not that I recall. But he did put in, inout (now ref) and out in the language, so yeah I think that's as close as we'd get.

changelog/previewInLink.dd Outdated Show resolved Hide resolved
changelog/previewInLink.dd Outdated Show resolved Hide resolved
The intent of `-preview=in` is to make `in` the go-to storage class for input parameters in D.
However it is D centric, as it is an enhanced version of `scope const ref`.
As non-`extern(D)` functions usually are expected to match a specific ABI,
using `in` is hardly a good idea.

However, as C++, also have a "go to" storage class for input parameters (`const T&`),
`in` can also be applied on `extern(C++)` function in order to bind to `const T&` parameters.
This also allows to expose a closer API for a function than via `const ref`,
as `in` will allow to bind rvalues to `const T&`, as in C++.
@Geod24
Copy link
Member Author

Geod24 commented Jun 17, 2022

@dkorpel : Fixed

@ibuclaw
Copy link
Member

ibuclaw commented Jun 18, 2022

I have nothing against this, would the likes of @atilaneves or @WalterBright wish to have another look?

case LINK.cpp:
fparam.storageClass |= STC.ref_;
break;
case LINK.default_, LINK.d:
Copy link
Member

Choose a reason for hiding this comment

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

What exactly does in mean for D linkage? Is it different than for C++?

Copy link
Member Author

Choose a reason for hiding this comment

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

This PR predates our decision to make in always mean ref. I'll correct it in the next PR.

@WalterBright
Copy link
Member

Does the meaning of in differ for D and C++ linkage?

@atilaneves
Copy link
Contributor

Does the meaning of in differ for D and C++ linkage?

I hope not.

@Geod24
Copy link
Member Author

Geod24 commented Jun 20, 2022

Not after I disable the optimization, which is the next PR.

@thewilsonator thewilsonator added Merge:auto-merge and removed Merge:72h no objection -> merge The PR will be merged if there are no objections raised. labels Jun 20, 2022
@dlang-bot dlang-bot merged commit b3cc517 into dlang:master Jun 20, 2022
@Geod24 Geod24 deleted the preview-in-extern-cpp branch June 20, 2022 12:58
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.

10 participants