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

Experimentally add `ffi_const` and `ffi_pure` extern fn attributes #58327

Open
wants to merge 11 commits into
base: master
from

Conversation

@gnzlbg
Copy link
Contributor

gnzlbg commented Feb 9, 2019

These attributes correspond to the const and pure C attributes.

Closes #46046 (the attributes can then be added to jemalloc-sys).

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

rust-highfive commented Feb 9, 2019

r? @michaelwoerister

(rust_highfive has picked a reviewer for you, use r? to override)

@gnzlbg gnzlbg force-pushed the gnzlbg:ffi_const_pure branch from e8ccb14 to bf149c0 Feb 9, 2019

@LifeIsStrange

This comment has been minimized.

Copy link

LifeIsStrange commented Feb 9, 2019

By curiosity, why not allow those attributes for rust code too (not only ffi)?
Also, why not expose all common llvm attributes to rust?
There is a lot of missed advanced features, and missed optimisations in rust by not being able to use compiler attributes unlike C/C++. This make rust far less competitive.

@jonas-schievink

This comment has been minimized.

Copy link
Member

jonas-schievink commented Feb 9, 2019

Also, why not expose all common llvm attributes to rust?

Because that would tie rustc to using LLVM as a backend more than necessary. The plan is to eventually allow using other backends like cranelift.

@gnzlbg

This comment has been minimized.

Copy link
Contributor Author

gnzlbg commented Feb 9, 2019

By curiosity, why not allow those attributes for rust code too (not only ffi)?

A couple of reasons. First, by restricting them to C FFI we can get away with just saying "they do whatever they do in C". This adds instant value and would result in a pretty uncontroversial RFC. Other languages can interpret C header files and use these attributes (e.g. C++, D, ...) but Rust C FFI wrappers need a way to express them.

Second, we can always allow these in Rust in the future in a backwards compatible way. We would then have to specify what these attributes "mean" for Rust code (Rust is not C), what Rust functions using these attributes are exactly allowed to do, etc. We might also need to give these some other names, since pure and const would be overloaded for Rust. The RFC process for this would be significantly more complicated.

Also, why not expose all common llvm attributes to rust?
There is a lot of missed advanced features, and missed optimisations in rust by not being able to use compiler attributes unlike C/C++. This make rust far less competitive.

We don't want to tie Rust to LLVM by exposing "LLVM-isms" (readnone, readonly, etc.). This PR makes effort in exposing C attributes for C FFI: pure and const. In LLVM they happen to generate readonly and readnone attributes, but if we had a different backed (e.g. GCC) they would generate something else.

If there are some C attributes that you want to use in C FFI, PRs welcome I guess. This PR shows pretty much how to add them. Libraries like bindgen can start using them on nightly as soon as they land. Initially I had more hopes that cross-language inlining would solve all those problems, but there is always going to be foreign code that we want to just link against that won't benefit from that.

Show resolved Hide resolved src/test/codegen/ffi-const.rs Outdated
Show resolved Hide resolved src/test/codegen/ffi-pure.rs Outdated
@nagisa

This comment has been minimized.

Copy link
Contributor

nagisa commented Feb 9, 2019

By curiosity, why not allow those attributes for rust code too (not only ffi)?

While the reasons by @jonas-schievink and @gnzlbg are convincing already, I’d like to point that this attribute is simply not necessary for Rust code, because LLVM is capable of deriving these attributes as part of optimisation process on its own.

@gnzlbg

This comment has been minimized.

Copy link
Contributor Author

gnzlbg commented Feb 10, 2019

I’d like to point that this attribute is simply not necessary for Rust code, because LLVM is capable of deriving these attributes as part of optimisation process on its own.

Right.

I imagine that, in some cases, it might be useful for Rust code to guarantee some of these properties to their callers. But that would mean that for Rust code, the attribute / language feature goal would be to express this guarantee, e.g., failing to compile if the implementation of the API changes in such a way that these properties don't hold anymore. Since we already have const fn, justifying another similar but not quite feature won't be trivial.

For FFI, Rust can't derive these properties, so the purpose of these attributes is more clear.

@gnzlbg gnzlbg force-pushed the gnzlbg:ffi_const_pure branch from ba57d67 to 945cbe4 Feb 10, 2019

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

rust-highfive commented Feb 10, 2019

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:02cb5120:start=1549796652095474631,finish=1549796724170395726,duration=72074921095
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
Setting environment variables from .travis.yml
$ export IMAGE=x86_64-gnu-llvm-6.0
---

[00:03:32] travis_fold:start:tidy
travis_time:start:tidy
tidy check
[00:03:33] tidy error: /checkout/src/test/codegen/ffi-pure.rs: too many trailing newlines (3)
[00:03:34] some tidy checks failed
[00:03:34] 
[00:03:34] 
[00:03:34] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/tidy" "/checkout/src" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "--no-vendor" "--quiet"
[00:03:34] 
[00:03:34] 
[00:03:34] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test src/tools/tidy
[00:03:34] Build completed unsuccessfully in 0:00:46
[00:03:34] Build completed unsuccessfully in 0:00:46
[00:03:34] make: *** [tidy] Error 1
[00:03:34] Makefile:68: recipe for target 'tidy' failed
The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:2c5fb81f
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
Sun Feb 10 11:09:07 UTC 2019
---
travis_time:end:24ed987c:start=1549796948309624766,finish=1549796948314278739,duration=4653973
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:209c6b58
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb --batch -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:06859262
travis_time:start:06859262
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:00f96935
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@nagisa nagisa added the T-lang label Feb 10, 2019

@nagisa

This comment has been minimized.

Copy link
Contributor

nagisa commented Feb 10, 2019

The implementation side of things looks good to me, so r+ on that. Somebody from T-lang should sign off on this as well, I think.

@LifeIsStrange

This comment has been minimized.

Copy link

LifeIsStrange commented Feb 11, 2019

Sorry, my answer is a little late.

You all raised interesting valid points that I didn't consider first!
"First, by restricting them to C FFI we can get away with just saying "they do whatever they do in C". This adds instant value and would result in a pretty uncontroversial RFC.etc..." absolutely, adding C ffi attributes is a quick, uncontroversial improvment.

"I’d like to point that this attribute is simply not necessary for Rust code, because LLVM is capable of deriving these attributes as part of optimisation process on its own."
Well, while this diminish the needs of optimisations hints through attributes this does not obscolete them. Because compiler are not perfect, rust already has Inline and cold attributes for helping the compiler to make more informed decisions.
There are a lot more attributes for this that are today impossible to do in rust.
E.g alloc_size could be used in theory for jemalloc_sys too.

To make the question "should rust support more llvm attributes (as it already support a few) ?" more actionable, I've found sorting attributes in categories is a great help (ideally one would visualize through Venn diagram).

There is an uncontroversial, low hanging fruit category of attributes to support in rust code.
Those are the few attributes that can't have bad consequences if unsupported by the compiler backend.
That is: most of compiler optimisations hints have this property, and also debug/diagnostics attributes to an extent.
For example gcc support the hot attribute (not the same as Inline) and the malloc attribute, they are not supported to my knowledge by llvm. Yet the code is behaving exactly the same in llvm and gcc, it's just that gcc will be able to be faster and use less memory. Why not implement those seemingly uncontroversial attributes in rust (including pure and const) ?
Yes it must be assured that those attributes have compatible meaning between c/c++ and rust but most of them if not all are language agnostic!
The second category is for attributes that are supported both by gcc and llvm.
Actually their is a big intersection of attributes between the two compiler and this is a goal from clang, to quote them : "aims to support a broad range of GCC extensions." and as you can see in https://clang.llvm.org/docs/AttributeReference.html they document the very rare cases where an llvm attributes behave differently than on GCC.
So for attributes that increase Langage expressiveness and thus change how the code will behave, like return twice for example or alignment constraints or making a whole function volatile but that they are identically supported by both llvm and gcc I think that would be an improvement to support them.
For some, it's even mandatory requirements to be able to use rust.
Yes, others backends that doesn't support the de facto standard intersection of attributes between llvm and gcc would have issues. But by quantifying the pro and cons, it seems that the new langage expressiveness, guarantees and optimisations enabled outweight the user choosen eventual loss of compatibility with backends that will most likely always stay niches. Still, as only advanced users for feature/performance critical code will use this category of attributes, by far most rust codes will still be able to be compatible with those niches backends.
Finally, after all those backends must implement codegen for each rust features, I don't see why those attributes would be a different difficulty for those backend to support than the difficulty of enabling backend support for a new usual rust feature !

And there is the last category, code behavior changing llvmisms not supported by GCC, while I don't consider realistic from rust to switch from llvm to GCC (because of human ressource management efficiency (that would unnecessarily split optimisations work and increase limitations for what advantage other than ironically supporting the expressiveness of GCC only attributes?)) I agree this category is a controversial high hanging fruit.

Note : I guess that would be nice to open a meta issue for increasing rust attributes support, prioritizing inconsequential new compiler space/time optimisations hints.
I propose that the syntax would differentiate universal attributes (the inconsequentials if unsupported by the backend, from the code behavior changing attributes) through a prefix.

@gnzlbg

This comment has been minimized.

Copy link
Contributor Author

gnzlbg commented Feb 11, 2019

I guess that would be nice to open a meta issue for increasing rust attributes support,

That would be better, discussing it here is turning a bit offtopic.

@michaelwoerister

This comment has been minimized.

Copy link
Contributor

michaelwoerister commented Feb 11, 2019

I agree with @nagisa -- the implementation looks good but this should be OK'ed by the lang team first.

Show resolved Hide resolved src/librustc/hir/mod.rs Outdated
Show resolved Hide resolved src/librustc/hir/mod.rs Outdated
Show resolved Hide resolved src/librustc/hir/mod.rs Outdated
Show resolved Hide resolved src/librustc/hir/mod.rs Outdated
Update doc of `ffi_const`
Co-Authored-By: gnzlbg <gnzlbg@users.noreply.github.com>
@Centril

This comment has been minimized.

Copy link
Contributor

Centril commented Feb 11, 2019

I agree with @nagisa -- the implementation looks good but this should be OK'ed by the lang team first.

Since we already have const fn, justifying another similar but not quite feature won't be trivial.

For FFI, Rust can't derive these properties, so the purpose of these attributes is more clear.

I'm wary of the potential for unbounded increases in complexity for the purposes of FFI, especially when it comes to optimization rather than things which are impossible otherwise. I also wonder what role const fn could have here. Potentially, a subset of functions benefiting from ffi_const could also benefit from const fn. However, these musings and concerns should not stop the gathering of data. To this end I propose that #[ffi_pure/const] be added to the compiler experimentally without any commitments to stabilizing one day. I expect an RFC to be filed eventually that includes gathered data (including performance numbers) and other considerations.

@rfcbot merge

@rfcbot

This comment has been minimized.

Copy link

rfcbot commented Feb 11, 2019

Team member @Centril has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@Centril Centril changed the title Add ffi_const and ffi_pure extern fn attributes Experimentally add ffi_const and ffi_pure extern fn attributes Feb 11, 2019

@gnzlbg

This comment has been minimized.

Copy link
Contributor Author

gnzlbg commented Feb 11, 2019

I expect an RFC to be filed eventually that includes gathered data and other considerations.

I wanted to submit an RFC already, but I got distracted with other things. I might be able to get to it this week, where we can discuss the detail and other stylistic issues more in detail. I think that while discussing such an RFC, being able to play with these attributes on nightly to easily come up with examples / counterexamples would be beneficial.

@Centril

This comment has been minimized.

Copy link
Contributor

Centril commented Feb 11, 2019

I might be able to get to it this week, where we can discuss the detail and other stylistic issues more in detail.

I would hold off on such an RFC; I'd like to give these attribute some time (2+ release cycles) to bake and to get benchmarks and profiling data on the benefits so that we can make more informed decisions. You can gather the examples and counterexamples on the tracking issue for now.

@gnzlbg

This comment has been minimized.

Copy link
Contributor Author

gnzlbg commented Feb 11, 2019

I would hold off on such an RFC; I'd like to give these attribute some time (2+ release cycles) to bake and to get benchmarks and profiling data on the benefits so that we can make more informed decisions. You can gather the examples and counterexamples on the tracking issue for now.

That seems to suggest that there exist an alternative to adding these attributes.

The only alternative I can think of is, e.g., wrapping all C FFI code with a dummy wrapper, and re-compiling that wrapper using -C cross-lang-lto or something like that (cc @michaelwoerister ), but that does have a lot of issues. In any case, an RFC with a concrete solutions, this PR, or the tracking issues would be an appropriate place to discuss alternatives, if any.

@Centril

This comment has been minimized.

Copy link
Contributor

Centril commented Feb 11, 2019

That seems to suggest that there exist an alternative to adding these attributes.

The primary alternative is doing nothing, which is what will happen unless and until there are sufficient positive benchmarks to justify the additional complexity. I'm proposing that we merge this now so that benchmarks can be done more easily in the ecosystem. Moreover, there are variations on the proposed attributes that we could do, e.g. #[c_ffi::pure], #[c_ffi(...)] and so on.

the tracking issues would be an appropriate place to discuss alternatives, if any.

Right; the tracking issue is the next step after this PR which is why I suggested it as a place to idea-dump before an RFC.

@gnzlbg

This comment has been minimized.

Copy link
Contributor Author

gnzlbg commented Feb 11, 2019

The primary alternative is doing nothing, which is what will happen unless and until there are sufficient positive benchmarks to justify the additional complexity.

It is trivial to come up with benchmarks for which a lack of the pure and const attributes introduce any slowdown you'd like. This one shows an 10000000x (godbolt) slowdown.

Moreover, there are variations on the proposed attributes that we could do, e.g. #[c_ffi::pure], #[c_ffi(...)] and so on.

An RFC seems like a good place to tackle those.

@Centril

This comment has been minimized.

Copy link
Contributor

Centril commented Feb 11, 2019

It is trivial to come up with benchmarks for which a lack of the pure and const attributes introduce any slowdown you'd like. This one shows an 10000000x (godbolt) slowdown.

OK; great -- then there should be no problem to produce a comprehensive set of benchmarks. I'm particularly interested in seeing benchmarks in larger pieces of code rather than solely relying on micro-benchmarks.

An RFC seems like a good place to tackle those.

Yep.

Show resolved Hide resolved src/libsyntax/feature_gate.rs Outdated
@scottmcm

This comment has been minimized.

Copy link
Member

scottmcm commented Feb 11, 2019

If T-compiler is ok with having this in the codebase, I don't think adding it experimentally requires a lang FCP. I think that the note saying it requires an FCP (and probably RFC) to stabilize is sufficient.

@gnzlbg

This comment has been minimized.

Copy link
Contributor Author

gnzlbg commented Feb 12, 2019

So I've added the docs to the unstable book, renamed the attributes to #[c_ffi_...], and the PR now also errors if a function is both const and pure.

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

rust-highfive commented Feb 12, 2019

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:1195630e:start=1549930182074104559,finish=1549930390222622034,duration=208148517475
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
Setting environment variables from .travis.yml
$ export IMAGE=x86_64-gnu-llvm-6.0
---
tidy check
[00:04:59] * 568 error codes
[00:04:59] * highest error code: E0726
[00:04:59] * 252 features
[00:05:00] tidy error: The Unstable Book has a 'language feature' section 'c_ffi_const' which doesn't correspond to an unstable language feature
[00:05:00] tidy error: The Unstable Book has a 'language feature' section 'c_ffi_pure' which doesn't correspond to an unstable language feature
[00:05:00] some tidy checks failed
[00:05:00] 
[00:05:00] 
[00:05:00] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/tidy" "/checkout/src" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "--no-vendor" "--quiet"
[00:05:00] 
[00:05:00] 
[00:05:00] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test src/tools/tidy
[00:05:00] Build completed unsuccessfully in 0:00:45
[00:05:00] Build completed unsuccessfully in 0:00:45
[00:05:00] make: *** [tidy] Error 1
[00:05:00] Makefile:68: recipe for target 'tidy' failed
The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:196d16e4
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
Tue Feb 12 00:18:19 UTC 2019
---
travis_time:end:080d8cc2:start=1549930700232119728,finish=1549930700236315974,duration=4196246
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:31de6666
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb --batch -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:00141754
travis_time:start:00141754
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:12772e36
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

rust-highfive commented Feb 12, 2019

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:17217c8c:start=1549945738004084576,finish=1549946145855645591,duration=407851561015
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
Setting environment variables from .travis.yml
$ export IMAGE=x86_64-gnu-llvm-6.0
---
tidy check
[00:03:40] * 568 error codes
[00:03:40] * highest error code: E0726
[00:03:40] * 252 features
[00:03:40] tidy error: The Unstable Book has a 'language feature' section 'c_ffi_const' which doesn't correspond to an unstable language feature
[00:03:40] tidy error: The Unstable Book has a 'language feature' section 'c_ffi_pure' which doesn't correspond to an unstable language feature
[00:03:41] some tidy checks failed
[00:03:41] 
[00:03:41] 
[00:03:41] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/tidy" "/checkout/src" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "--no-vendor" "--quiet"
[00:03:41] 
[00:03:41] 
[00:03:41] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test src/tools/tidy
[00:03:41] Build completed unsuccessfully in 0:00:48
[00:03:41] Build completed unsuccessfully in 0:00:48
[00:03:41] Makefile:68: recipe for target 'tidy' failed
[00:03:41] make: *** [tidy] Error 1
The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:281d2980
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
Tue Feb 12 04:39:36 UTC 2019
---
travis_time:end:2a07bc66:start=1549946377288241187,finish=1549946377293431369,duration=5190182
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:1bc5c900
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb --batch -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:34c7a400
travis_time:start:34c7a400
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:22bf8647
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

performed in between these functions calls (as opposed to `#[c_ffi_pure]`
functions).

## Pitfals

This comment has been minimized.

@CryZe

CryZe Feb 12, 2019

Contributor
Suggested change Beta
## Pitfals
## Pitfalls
sub-expression elimination regardless of any operations in between the function
calls.

## Pitfals

This comment has been minimized.

@CryZe

CryZe Feb 12, 2019

Contributor
Suggested change Beta
## Pitfals
## Pitfalls
@gnzlbg

This comment has been minimized.

Copy link
Contributor Author

gnzlbg commented Feb 12, 2019

tidy error: The Unstable Book has a 'language feature' section 'c_ffi_const' which doesn't correspond to an unstable language feature

Any ideas ? I tried looking about this in the Rustc Guide without much luck. Is it documented somewhere how to add docs to the unstable book ?

@scottmcm

This comment has been minimized.

Copy link
Member

scottmcm commented Feb 12, 2019

I think the book filenames use hyphens where the feature has underscores.

(In case that's not it, here are PRs in which I updated the unstable book: #53693 #52602)

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

rust-highfive commented Feb 12, 2019

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:04b1a4f1:start=1549965418228328595,finish=1549965538396790302,duration=120168461707
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
Setting environment variables from .travis.yml
$ export IMAGE=x86_64-gnu-llvm-6.0
---
[01:02:09] .................................................................................................... 100/5386
[01:02:13] .................................................................................................... 200/5386
[01:02:16] .................................................................................................... 300/5386
[01:02:19] .................................................................................................... 400/5386
[01:02:23] ...............................................................F.................................... 500/5386
[01:02:31] .................................................................................................... 700/5386
[01:02:36] .................................................................................................... 800/5386
[01:02:42] ....................................................................................i............... 900/5386
[01:02:46] i................................................................................................... 1000/5386
---
[01:05:34] .................................................................................................... 5300/5386
[01:05:37] .........................i............................................................
[01:05:37] failures:
[01:05:37] 
[01:05:37] ---- [ui] ui/c_ffi_const2.rs stdout ----
[01:05:37] 
[01:05:37] error: Error: expected failure status (Some(1)) but received status Some(101).
[01:05:37] status: exit code: 101
[01:05:37] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/c_ffi_const2.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/c_ffi_const2/a" "-Crpath" "-O" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/c_ffi_const2/auxiliary" "-A" "unused"
[01:05:37] ------------------------------------------
[01:05:37] 
[01:05:37] ------------------------------------------
[01:05:37] stderr:
[01:05:37] stderr:
[01:05:37] ------------------------------------------
[01:05:37] {"message":"`#[c_ffi_const]` function cannot be`#[c_ffi_pure]`","code":{"code":"E0726","explanation":null},"level":"error","spans":[{"file_name":"/checkout/src/test/ui/c_ffi_const2.rs","byte_start":77,"byte_end":90,"line_start":5,"line_end":5,"column_start":5,"column_end":18,"is_primary":true,"text":[{"text":"    #[c_ffi_pure] //~ ERROR `#[c_ffi_const]` function cannot be`#[c_ffi_pure]` [E0726]","highlight_start":5,"highlight_end":18}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"error[E0726]: `#[c_ffi_const]` function cannot be`#[c_ffi_pure]`\n  --> /checkout/src/test/ui/c_ffi_const2.rs:5:5\n   |\nLL |     #[c_ffi_pure] //~ ERROR `#[c_ffi_const]` function cannot be`#[c_ffi_pure]` [E0726]\n   |     ^^^^^^^^^^^^^\n\n"}
[01:05:37] Attributes 'readnone and readonly' are incompatible!
[01:05:37] void ()* @baz
[01:05:37] LLVM ERROR: Broken module found, compilation aborted!
[01:05:37] ------------------------------------------
[01:05:37] 
[01:05:37] 
[01:05:37] thread '[ui] ui/c_ffi_const2.rs' panicked at 'explicit panic', src/tools/compiletest/src/runtest.rs:3295:9
[01:05:37] 
[01:05:37] 
[01:05:37] failures:
[01:05:37] failures:
[01:05:37]     [ui] ui/c_ffi_const2.rs
[01:05:37] test result: FAILED. 5362 passed; 1 failed; 23 ignored; 0 measured; 0 filtered out
[01:05:37] 
[01:05:37] thread 'main' panicked at 'Some tests failed', src/tools/compiletest/src/main.rs:496:22
[01:05:37] 
[01:05:37] 
[01:05:37] 
[01:05:37] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/ui" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "ui" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-6.0/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--target-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "6.0.0\n" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--llvm-components" "" "--llvm-cxxflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"
[01:05:37] 
[01:05:37] 
[01:05:37] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:05:37] Build completed unsuccessfully in 0:04:32
[01:05:37] Build completed unsuccessfully in 0:04:32
[01:05:37] make: *** [check] Error 1
[01:05:37] Makefile:48: recipe for target 'check' failed
The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:1de05e22
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
Tue Feb 12 11:04:45 UTC 2019

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@joshtriplett

This comment has been minimized.

Copy link
Member

joshtriplett commented Feb 12, 2019

I don't want to bikeshed this, but I think c_ffi_ is the wrong prefix. ffi_ seems appropriate as this applies to FFI functions, but this isn't related to C except insofar as extern functions use the C ABI. ffi_pure is not a C-specific concept.

@gnzlbg

This comment has been minimized.

Copy link
Contributor Author

gnzlbg commented Feb 12, 2019

{"message":"`#[c_ffi_const]` function cannot be`#[c_ffi_pure]`","code":{"code":"E0726","explanation":null},"level":"error","spans":[{"file_name":"/checkout/src/test/ui/c_ffi_const2.rs","byte_start":77,"byte_end":90,"line_start":5,"line_end":5,"column_start":5,"column_end":18,"is_primary":true,"text":[{"text":"    #[c_ffi_pure] //~ ERROR `#[c_ffi_const]` function cannot be`#[c_ffi_pure]` [E0726]","highlight_start":5,"highlight_end":18}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"error[E0726]: `#[c_ffi_const]` function cannot be`#[c_ffi_pure]`\n  --> /checkout/src/test/ui/c_ffi_const2.rs:5:5\n   |\nLL |     #[c_ffi_pure] //~ ERROR `#[c_ffi_const]` function cannot be`#[c_ffi_pure]` [E0726]\n   |     ^^^^^^^^^^^^^\n\n"}
[01:05:37] Attributes 'readnone and readonly' are incompatible!
[01:05:37] void ()* @baz
[01:05:37] LLVM ERROR: Broken module found, compilation aborted!

So it appears that LLVM does not like pure const functions at all. I'm using span_err to report this error here: https://github.com/rust-lang/rust/pull/58327/files#diff-4ed25c00aceb84666fca639cf8101c7cR2277

But it appears that after the error is .emit()ed compilation continues. Is there a way to make this error completely stop compilation ?

@gnzlbg

This comment has been minimized.

Copy link
Contributor Author

gnzlbg commented Feb 12, 2019

@joshtriplett I've created a meta issue with some open questions in the RFC repo about FFI attribute syntax: rust-lang/rfcs#2637

It might be better to move discussions about these points there. An RFC about a particular attribute could focus on the motivation for the attribute, semantics, etc. and leave the syntax as an unresolved question .

Mixing the discussion of those topics with a general discussion about what the best syntax is to expose these things could result in a big mess.

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

rust-highfive commented Feb 12, 2019

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:169cdf52:start=1549992459404591545,finish=1549992556750057118,duration=97345465573
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
Setting environment variables from .travis.yml
$ export IMAGE=x86_64-gnu-llvm-6.0
---
[01:05:10] .................................................................................................... 100/5386
[01:05:13] .................................................................................................... 200/5386
[01:05:16] .................................................................................................... 300/5386
[01:05:18] .................................................................................................... 400/5386
[01:05:22] ...............................................................F.................................... 500/5386
[01:05:29] .................................................................................................... 700/5386
[01:05:34] .................................................................................................... 800/5386
[01:05:38] ....................................................................................i............... 900/5386
[01:05:42] i................................................................................................... 1000/5386
---
[01:08:13] .................................................................................................... 5300/5386
[01:08:16] .........................i............................................................
[01:08:16] failures:
[01:08:16] 
[01:08:16] ---- [ui] ui/c_ffi_const2.rs stdout ----
[01:08:16] 
[01:08:16] error: Error: expected failure status (Some(1)) but received status Some(101).
[01:08:16] status: exit code: 101
[01:08:16] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/c_ffi_const2.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/c_ffi_const2/a" "-Crpath" "-O" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/c_ffi_const2/auxiliary" "-A" "unused"
[01:08:16] ------------------------------------------
[01:08:16] 
[01:08:16] ------------------------------------------
[01:08:16] stderr:
[01:08:16] stderr:
[01:08:16] ------------------------------------------
[01:08:16] {"message":"`#[c_ffi_const]` function cannot be`#[c_ffi_pure]`","code":{"code":"E0726","explanation":null},"level":"error","spans":[{"file_name":"/checkout/src/test/ui/c_ffi_const2.rs","byte_start":77,"byte_end":90,"line_start":5,"line_end":5,"column_start":5,"column_end":18,"is_primary":true,"text":[{"text":"    #[c_ffi_pure] //~ ERROR `#[c_ffi_const]` function cannot be`#[c_ffi_pure]` [E0726]","highlight_start":5,"highlight_end":18}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"error[E0726]: `#[c_ffi_const]` function cannot be`#[c_ffi_pure]`\n  --> /checkout/src/test/ui/c_ffi_const2.rs:5:5\n   |\nLL |     #[c_ffi_pure] //~ ERROR `#[c_ffi_const]` function cannot be`#[c_ffi_pure]` [E0726]\n   |     ^^^^^^^^^^^^^\n\n"}
[01:08:16] Attributes 'readnone and readonly' are incompatible!
[01:08:16] void ()* @baz
[01:08:16] LLVM ERROR: Broken module found, compilation aborted!
[01:08:16] ------------------------------------------
[01:08:16] 
[01:08:16] 
[01:08:16] thread '[ui] ui/c_ffi_const2.rs' panicked at 'explicit panic', src/tools/compiletest/src/runtest.rs:3295:9
[01:08:16] 
[01:08:16] 
[01:08:16] failures:
[01:08:16] failures:
[01:08:16]     [ui] ui/c_ffi_const2.rs
[01:08:16] test result: FAILED. 5362 passed; 1 failed; 23 ignored; 0 measured; 0 filtered out
[01:08:16] 
[01:08:16] thread 'main' panicked at 'Some tests failed', src/tools/compiletest/src/main.rs:496:22
[01:08:16] 
[01:08:16] 
[01:08:16] 
[01:08:16] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/ui" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "ui" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-6.0/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--target-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "6.0.0\n" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--llvm-components" "" "--llvm-cxxflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"
[01:08:16] 
[01:08:16] 
[01:08:16] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:08:16] Build completed unsuccessfully in 0:04:07
[01:08:16] Build completed unsuccessfully in 0:04:07
[01:08:16] Makefile:48: recipe for target 'check' failed
[01:08:16] make: *** [check] Error 1
The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:06b9e140
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
Tue Feb 12 18:37:42 UTC 2019
---
travis_time:end:11103419:start=1549996663290885386,finish=1549996663297738730,duration=6853344
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:1941d5bb
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:2323591e
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@michaelwoerister

This comment has been minimized.

Copy link
Contributor

michaelwoerister commented Feb 21, 2019

I'm not quite clear on what the status of this is. Did @rust-lang/lang sign off on it? I think some boxes still need checking.

@gnzlbg

This comment has been minimized.

Copy link
Contributor Author

gnzlbg commented Feb 21, 2019

Did @rust-lang/lang sign off on it? I think some boxes still need checking.

I don't think so, no.

cc @eddyb taking a look at these, I briefly thought about whether we could use them to implement the bench_input / bench_output APIs that you proposed in the black-box RFC, e.g.,

#[c_ffi_const]
fn bench_input<T>(x: T) -> T {
    asm!("" : "=*m"(&x) : "*m"(&x) : : :);
    x
}

but I would be surprised if telling LLVM that a function that it can prove as "not const" is const would be undefined behavior. So I'd rather keep this as C FFI attributes for now, and if we ever need to do that, add a #[rustc_llvm_attr(const)] or similar to specifically do that, clearly stating that such thing is perma-unstable and aiming for LLVM semantics explicitly, instead of reusing a C FFI attribute.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment