test: Move run-make tests into compiletest
Forcing them to be embedded in makefiles precludes being able to run them in
rustbuild, and adding them to compiletest gives us a great way to leverage
future enhancements to our "all encompassing test suite runner" as well as just
moving more things into Rust.
All tests are still Makefile-based in the sense that they rely on `make` being
available to run them, but there's no longer any Makefile-trickery to run them
and rustbuild can now run them out of the box as well.
Forcing them to be embedded in makefiles precludes being able to run them in
rustbuild, and adding them to compiletest gives us a great way to leverage
future enhancements to our "all encompassing test suite runner" as well as just
moving more things into Rust.
All tests are still Makefile-based in the sense that they rely on `make` being
available to run them, but there's no longer any Makefile-trickery to run them
and rustbuild can now run them out of the box as well.
Some preliminary work towards making trans "collector driven".
The `trans::collector` already collects all translation items and `trans::partitioning` distributes these translation items into codegen units. The changes in this PR provide the following extensions to this functionality:
1. Drop-glue is handled more accurately now, knowing about the difference between `DropGlueKind::Ty` and `DropGlueKind::TyContents`.
2. The partitioning module now supports the `FixedUnitCount` strategy which more or less corresponds to the partitioning one gets via supplying `-Ccodegen-units` today.
3. The partitioning scheme also takes care of assigned LLVM declarations to codegen units, not just definitions (declarations for external items not yet implemented).
It's debatable whether declarations should be handled by the partitioning scheme or whether they should just be emitted on demand.
rustc_driver: Allow running the compiler with a FileLoader
cc @nrc. I chose to implement this in such a way that it doesn't break anything. Please let me know if you want me to change anything.
std: Add compatibility with android-9
The Gecko folks currently use Android API level 9 for their builds, so they're
requesting that we move back our minimum supported API level from 18 to 9. Turns
out, ABI-wise at least, there's not that many changes we need to take care of.
The `ftruncate64` API appeared in android-12 and the `log2` and `log2f` APIs
appeared in android-18. We can have a simple shim for `ftruncate64` which falls
back on `ftruncate` and the `log2` function can be approximated with just
`ln(f) / ln(2)`.
This should at least get the standard library building on API level 9, although
the tests aren't quite happening there just yet. As we seem to be growing a
number of Android compatibility shims, they're now centralized in a common
`sys::android` module.
Fix use of the `move` command in the Windows shell
`move` works both in `cmd` and in Powershell. `mv` works only in Powershell and the book says nothing about which shell is recommended so this could confuse beginners.
Closes#33219.
Make HashSet::Insert documentation more consistent
I have made the HashSet::Insert documentation more consistent in the use of the term 'value' vs 'key'. Also clarified that if _this_ value is present true is returned, instead of the ambiguous 'a value present'.
r? @steveklabnik
Tweaks to sections related to Ownership
Reading through these sections, I thought the intro text could be improved slightly. So
here is a PR that addresses what was bugging me about it. :-)
Main issue was the wording of the opening sentence ("guide" is not clearly defined and the
wording was a bit too terse in my opinion). I also took issue with the term "one of the most
unique". Uniqueness is a `bool`, not an `f64`. :-)
r? @steveklabnik
Various improvements to MIR and LLVM IR Construction
Primarily affects the MIR construction, which indirectly improves LLVM
IR generation, but some LLVM IR changes have been made too.
* Handle "statement expressions" more intelligently. These are
expressions that always evaluate to `()`. Previously a temporary would
be generated as a destination to translate into, which is unnecessary.
This affects assignment, augmented assignment, `return`, `break` and
`continue`.
* Avoid inserting drops for non-drop types in more places. Scheduled
drops were already skipped for types that we knew wouldn't need
dropping at construction time. However manually-inserted drops like
those for `x` in `x = y;` were still generated. `build_drop` now takes
a type parameter like its `schedule_drop` counterpart and checks to
see if the type needs dropping.
* Avoid generating an extra temporary for an assignment where the types
involved don't need dropping. Previously an expression like
`a = b + 1;` would result in a temporary for `b + 1`. This is so the
RHS can be evaluated, then the LHS evaluated and dropped and have
everything work correctly. However, this isn't necessary if the `LHS`
doesn't need a drop, as we can just overwrite the existing value.
* Improves lvalue analysis to allow treating an `Rvalue::Use` as an
operand in certain conditions. The reason for it never being an
operand is so it can be zeroed/drop-filled, but this is only true for
types that need dropping.
The first two changes result in significantly fewer MIR blocks being
generated, as previously almost every statement would end up generating
a new block due to the drop of the `()` temporary being generated.
rustdoc: Cleanup ABI rendering
Use a common method for rendering `extern "<abi>"`.
This now consistently shows `extern fn` rather than `extern "C" fn`.
Feature gate clean
This PR does a bit of cleaning in the feature-gate-handling code of libsyntax. It also fixes two bugs (#32782 and #32648). Changes include:
* Change the way the existing features are declared in `feature_gate.rs`. The array of features and the `Features` struct are now defined together by a single macro. `featureck.py` has been updated accordingly. Note: there are now three different arrays for active, removed and accepted features instead of a single one with a `Status` item to tell wether a feature is active, removed, or accepted. This is mainly due to the way I implemented my macro in the first time and I can switch back to a single array if needed. But an advantage of the way it is now is that when an active feature is used, the parser only searches through the list of active features. It goes through the other arrays only if the feature is not found. I like to think that error checking (in this case, checking that an used feature is active) does not slow down compilation of valid code. :) But this is not very important...
* Feature-gate checking pass now use the `Features` structure instead of looking through a string vector. This should speed them up a bit. The construction of the `Features` struct should be faster too since it is build directly when parsing features instead of calling `has_feature` dozens of times.
* The MacroVisitor pass has been removed, it was mostly useless since the `#[cfg]-stripping` phase happens before (fixes#32648). The features that must actually be checked before expansion are now checked at the time they are used. This also allows us to check attributes that are generated by macro expansion and not visible to MacroVisitor, but are also removed by macro expansion and thus not visible to PostExpansionVisitor either. This fixes#32782. Note that in order for `#[derive_*]` to be feature-gated but still accepted when generated by `#[derive(Trait)]`, I had to do a little bit of trickery with spans that I'm not totally confident into. Please review that part carefully. (It's in `libsyntax_ext/deriving/mod.rs`.)::
Note: this is a [breaking change], since programs with feature-gated attributes on macro-generated macro invocations were not rejected before. For example:
```rust
macro_rules! bar (
() => ()
);
macro_rules! foo (
() => (
#[allow_internal_unstable] //~ ERROR allow_internal_unstable side-steps
bar!();
);
);
```
foo!();
LLVM's assertion doesn't provide much insight as to what the problem
was. We were already checking `call` instructions ourselves, so this
brings the checks from there to `invoke`.
Both the `invoke` and `call` checking is controlled by
`debug_assertions`.
I'm not sure what the signficance of `drop-glue i8` is, nor why one of
the tests had it appear while the others had it disappear. Either way it
doesn't seem like the presence or absense of it is the focus of the
tests.
Primarily affects the MIR construction, which indirectly improves LLVM
IR generation, but some LLVM IR changes have been made too.
* Handle "statement expressions" more intelligently. These are
expressions that always evaluate to `()`. Previously a temporary would
be generated as a destination to translate into, which is unnecessary.
This affects assignment, augmented assignment, `return`, `break` and
`continue`.
* Avoid inserting drops for non-drop types in more places. Scheduled
drops were already skipped for types that we knew wouldn't need
dropping at construction time. However manually-inserted drops like
those for `x` in `x = y;` were still generated. `build_drop` now takes
a type parameter like its `schedule_drop` counterpart and checks to
see if the type needs dropping.
* Avoid generating an extra temporary for an assignment where the types
involved don't need dropping. Previously an expression like
`a = b + 1;` would result in a temporary for `b + 1`. This is so the
RHS can be evaluated, then the LHS evaluated and dropped and have
everything work correctly. However, this isn't necessary if the `LHS`
doesn't need a drop, as we can just overwrite the existing value.
* Improves lvalue analysis to allow treating an `Rvalue::Use` as an
operand in certain conditions. The reason for it never being an
operand is so it can be zeroed/drop-filled, but this is only true for
types that need dropping.
The first two changes result in significantly fewer MIR blocks being
generated, as previously almost every statement would end up generating
a new block due to the drop of the `()` temporary being generated.
Make some fatal lexer errors recoverable
I've kept the changes to a minimum since I'm not really sure if this approach is a acceptable.
fixes#12834
cc @nrc
The Gecko folks currently use Android API level 9 for their builds, so they're
requesting that we move back our minimum supported API level from 18 to 9. Turns
out, ABI-wise at least, there's not that many changes we need to take care of.
The `ftruncate64` API appeared in android-12 and the `log2` and `log2f` APIs
appeared in android-18. We can have a simple shim for `ftruncate64` which falls
back on `ftruncate` and the `log2` function can be approximated with just
`ln(f) / ln(2)`.
This should at least get the standard library building on API level 9, although
the tests aren't quite happening there just yet. As we seem to be growing a
number of Android compatibility shims, they're now centralized in a common
`sys::android` module.
report `const_err` on all expressions that can fail
also a drive-by fix for reporting an "overflow in shift *left*" when shifting an `i64` *right*
This increases the warning noise for shifting by more than the bitwidth and for `-T::MIN`. I can silence the bitwidth warnings explicitly and fix the const evaluator to make sure `--$expr` is treated exactly like `$expr` (which is kinda wrong, but mathematically right).
r? @eddyb
`move` work both in `cmd` and in Powershell. `mv` works only in Powershell and the book says nothing about which shell is recommended so this could confuse beginners.
Closes#33219.
special-case #[derive(Copy, Clone)] with a shallow clone
If a type is Copy then its Clone implementation can be a no-op. Currently `#[derive(Clone)]` generates a deep clone anyway. This can lead to lots of code bloat.
This PR detects the case where Copy and Clone are both being derived (the general case of "is this type Copy" can't be determined by a syntax extension) and generates the shallow Clone impl. Right now this can only be done if there are no type parameters (see https://github.com/rust-lang/rust/issues/31085#issuecomment-178988663), but this restriction can be removed after specialization.
Fixes#31085.
rustdoc: Handle concurrent mkdir requests
It's likely that `rustdoc` as a tool is run concurrently in the same output
(e.g. documenting multiple crates as Cargo does), in which case it needs to
handle concurrent calls to `fs::create_dir`.
Changes #[derive(Copy, Clone)] to use a faster impl of Clone when
both derives are present, and there are no generics in the type.
The faster impl is simply returning *self (which works because the
type is also Copy). See the comments in libsyntax_ext/deriving/clone.rs
for more details.
There are a few types which are Copy but not Clone, in violation
of the definition of Copy. These include large arrays and tuples. The
very existence of these types is arguably a bug, but in order for this
optimization not to change the applicability of #[derive(Copy, Clone)],
the faster Clone impl also injects calls to a new function,
core::clone::assert_receiver_is_clone, to verify that all members are
actually Clone.
This is not a breaking change, because pursuant to RFC 1521, any type
that implements Copy should not do any observable work in its Clone
impl.