filedesc: don't use ioctl(FIOCLEX) on Linux
All `ioctl(2)`s will fail on `O_PATH` file descriptors on Linux (because
they use `&empty_fops` as a security measure against `O_PATH` descriptors
affecting the backing file).
As a result, `File::try_clone()` and various other methods would always
fail with `-EBADF` on `O_PATH` file descriptors. The solution is to simply
use `F_SETFD` (as is used on other unices) which works on `O_PATH`
descriptors because it operates through the `fnctl(2)` layer and not
through `ioctl(2)`s.
Since this code is usually only used in strange error paths (a broken or
ancient kernel), the extra overhead of one syscall shouldn't cause any
dramas. Most other systems programming languages also use the fnctl(2)
so this brings us in line with them.
Fixes: rust-lang/rust#62314
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
core: check for pointer equality when comparing Eq slices
Because `Eq` types must be reflexively equal, an equal-length slice to the same memory location must be equal.
This is related to #33892 (and #32699) answering this comment from that PR:
> Great! One more easy question: why does this optimization not apply in the non-BytewiseEquality implementation directly above?
Because slices of non-reflexively equal types (like `f64`) are not equal even if it's the same slice. But if the types are `Eq`, we can use this same-address optimization, which this PR implements. Obviously this changes behavior if types violate the reflexivity condition of `Eq`, because their impls of `PartialEq` will no longer be called per-item, but 🤷♂ .
It's not clear how often this optimization comes up in the real world outside of the same-`&str` case covered by #33892, so **I'm requesting a perf run** (on MacOS today, so can't run `rustc_perf` myself). I'm going ahead and making the PR on the basis of being surprised things didn't already work this way.
This is my first time hacking rust itself, so as a perf sanity check I ran `./x.py bench --stage 0 src/lib{std,alloc}`, but the differences were noisy.
To make the existing specialization for `BytewiseEquality` explicit, it's now a supertrait of `Eq + Copy`. `Eq` should be sufficient, but `Copy` was included for clarity.
Rollup of 5 pull requests
Successful merges:
- #62275 (rustc_mir: treat DropAndReplace as Drop + Assign in qualify_consts.)
- #62465 (Sometimes generate storage statements for temporaries with type `!`)
- #62481 (Use `fold` in `Iterator::last` default implementation)
- #62493 (#62357: doc(ptr): add example for {read,write}_unaligned)
- #62532 (Some more cleanups to syntax::print)
Failed merges:
r? @ghost
Add a test for the issue resolved by removing `resolve_macro_path`
Add a test making sure that extern prelude entries introduced from an opaque macro are not visible anywhere, even it that macro
Fix test output after rebase
It's more convenient to have all this highly related stuff together on one screen (for future refactorings).
The `expand_invoc` function is compact enough now, after all the previous refactorings.
Remove a bunch of `Option`s that assumed that dummy fragment creation could fail.
The test output changed due to not performing the expansion in `fn expand_invoc` in case of the recursion limit hit.
The root expansion was missing one.
Expansions created for "derive containers" (see one of the next commits for the description) also didn't get expansion info.
Use variant names rather than descriptions for identifying desugarings in `#[rustc_on_unimplemented]`.
Both are highly unstable, but variant name is at least a single identifier.
Creating a fresh expansion and immediately generating a span from it is the most common scenario.
Also avoid allocating `allow_internal_unstable` lists for derive markers repeatedly.
And rename `ExpnInfo::with_unstable` to `ExpnInfo::allow_unstable`, seems to be a better fitting name.
Ok, it's hard to explain what happens, but identifier's hygienic contexts need to be "adjusted" to modules/scopes before they are resolved in them.
To be resolved in all kinds on preludes the identifier needs to be adjusted to the root expansion (aka "no expansion").
Previously this was done for the `macro m() { ::my_crate::foo }` case, but forgotten for all other cases.
Also move macro stability checking closer to other checks performed on obtained resolutions.
Tighten the stability spans as well, it is an error to *refer* to and unstable entity in any way, not only "call" it.
This way we are processing all of them in a single point, rather than separately for each syntax extension kind.
Also, the standard expected/found wording is used.
It either returns the indeterminacy error, or valid (but perhaps dummy) `SyntaxExtension`.
With this change enum `Determinacy` is no longer used in libsyntax and can be moved to resolve.
The regressions in diagnosics are fixed in the next commits.
Create real working and registered (even if dummy) `SyntaxExtension`s for them.
This improves error recovery and allows to avoid all special cases for proc macro stubs (except for the error on use, of course).
The introduced dummy `SyntaxExtension`s can be used for any other inappropriately resolved macros as well.
Avoid the tricky scheme with callbacks and keep the invocation parent data where it logically belongs - in `Definitions`.
This also allows to create `InvocationData` entries in resolve when the data is actually ready, and remove cells and "uninitialized" variants from it.
We have to deal with dummy spans anyway
Remove def-site span from expander interfaces.
It's not used by the expansion infra, only by specific expanders, which can keep it themselves if they want it.
It was used to choose whether to apply derive markers like `#[rustc_copy_clone_marker]` or not,
but it was called before all the data required for resolution is available, so it could work incorrectly in some corner cases (like user-defined derives name `Copy` or `Eq`).
Delay the decision about markers until the proper resolution results are available instead.
The expansions were created to allow unstable things inside `#[test_case/test/bench]`, but that's not a proper way to do that.
Put the required `allow_internal_unstable`s into the macros' properties instead.