llvm: change data layout bug to an error and make it trigger more
Fixes#33446.
Don't skip the inconsistent data layout check for custom LLVMs or non-built-in targets.
With #118708, all targets will have a simple test that would trigger this error if LLVM's data layouts do change - so data layouts would be corrected during the LLVM upgrade. Therefore, with builtin targets, this error won't happen with our LLVM because each target will have been confirmed to work. With non-builtin targets, this error is probably useful to have because you can change the data layout in your target and if it is wrong then that could lead to bugs.
When using a custom LLVM, the same justification makes sense for non-builtin targets as with our LLVM, the user can update their target to match their LLVM and that's probably a good thing to do. However, with a custom LLVM, the user cannot change the builtin target data layouts if they don't match - though given that the compiler's data layout is used for layout computation and a bunch of other things - you could get some bugs because of the mismatch and probably want to know about that. I'm not sure if this is something that people do and is okay, but I doubt it?
`CFG_LLVM_ROOT` was also always set during local development with `download-ci-llvm` so this bug would never trigger locally.
In #33446, two points are raised:
- In the issue itself, changing this from a `bug!` to a proper error is what is suggested, by using `isCompatibleDataLayout` from LLVM, but that function still just does the same thing that we do and check for equality, so I've avoided the additional code necessary to do that FFI call.
- `@Mark-Simulacrum` suggests a different check is necessary to maintain backwards compatibility with old LLVM versions. I don't know how often this comes up, but we can do that with some simple string manipulation + LLVM version checks as happens already for LLVM 17 just above this diff.
Remove myself from review rotation
Still willing to do reviews (and make it through my backlog), but I don't have the bandwidth to be on the rotation right now.
Improve handling of numbers in `IntoDiagnosticArg`
While working on https://github.com/rust-lang/rust/pull/120393, I realize that my fluent selectors were not working. So here is an improvement (not a fix unfortunately).
ScopeTree: remove destruction_scopes as unused
last usages removed by https://github.com/rust-lang/rust/pull/116170
Unused, but still presented in memory at `t-gmax` (in DHAT termonology)
Properly recover from trailing attr in body
When encountering an attribute in a body, we try to recover from an attribute on an expression (as opposed to a statement). We need to properly clean up when the attribute is at the end of the body where a tail expression would be.
Fix#118164, fix#118575.
Add the unstable option to reduce the binary size of dynamic library…
# Motivation
The average length of symbol names in the rust standard library is about 100 bytes, while the average length of symbol names in the C++ standard library is about 65 bytes. In some embedded environments where dynamic library are widely used, rust dynamic library symbol name space hash become one of the key bottlenecks of application, Especially when the existing C/C++ module is reconstructed into the rust module.
The unstable option `-Z symbol_mangling_version=hashed` is added to solve the bottleneck caused by too long dynamic library symbol names.
## Test data
The following is a set of test data on the ubuntu 18.04 LTS environment. With this plug-in, the space saving rate of dynamic libraries can reach about 20%.
The test object is the standard library of rust (built based on Xargo), tokio crate, and hyper crate.
The contents of the Cargo.toml file in the construction project of the three dynamic libraries are as follows:
```txt
# Cargo.toml
[profile.release]
panic = "abort"
opt-leve="z"
codegen-units=1
strip=true
debug=true
```
The built dynamic library also removes the `.rustc` segments that are not needed at run time and then compares the size. The detailed data is as follows:
1. libstd.so
> | symbol_mangling_version | size | saving rate |
> | --- | --- | --- |
> | legacy | 804896 ||
> | hashed | 608288 | 0.244 |
> | v0 | 858144 ||
> | hashed | 608288 | 0.291 |
2. libhyper.so
> | symbol_mangling_version(libhyper.so) | symbol_mangling_version(libstd.so) | size | saving rate |
> | --- | --- | --- | --- |
> | legacy | legacy | 866312 ||
> | hashed | legacy | 645128 |0.255|
> | legacy | hashed | 854024 ||
> | hashed | hashed | 632840 |0.259|
When encountering an attribute in a body, we try to recover from an
attribute on an expression (as opposed to a statement). We need to
properly clean up when the attribute is at the end of the body where a
tail expression would be.
Fix#118164.
Classify closure arguments in refutable pattern in argument error
You can call it a function (and people may or may not agree with that), but it's better to just say those are closure arguments instead.
core: add `From<core::ascii::Char>` implementations
Introduce `From<core::ascii::Char>` implementations for all unsigned
numeric types and `char`. This matches the API of `char` type.
Issue: https://github.com/rust-lang/rust/issues/110998
Normalize field types before checking validity
I forgot to normalize field types when checking ADT-like aggregates in the MIR validator.
This normalization is needed due to a crude check for opaque types in `mir_assign_valid_types` which prevents opaque type cycles -- if we pass in an unnormalized type, we may not detect that the destination type is an opaque, and therefore will call `type_of(opaque)` later on, which causes a cycle error -> ICE.
Fixes#120253
std: make `HEAP` initializer never inline
The system allocator for Windows calls `init_or_get_process_heap` every time allocating. It generates very much useless code and makes the binary larger. The `HEAP` only needs to initialize once before the main fn.
Concerns:
* I'm not sure if `init` will be properly called in cdylib.
* Do we need to ensure the allocator works if the user enables `no_main`?
* Should we panic if `GetProcessHeap` returns null?
Rename `pointer` field on `Pin`
A few days ago, I was helping another user create a self-referential type using `PhantomPinned`. However, I noticed an odd behavior when I tried to access one of the type's fields via `Pin`'s `Deref` impl:
```rust
use std::{marker::PhantomPinned, ptr};
struct Pinned {
data: i32,
pointer: *const i32,
_pin: PhantomPinned,
}
fn main() {
let mut b = Box::pin(Pinned {
data: 42,
pointer: ptr::null(),
_pin: PhantomPinned,
});
{
let pinned = unsafe { b.as_mut().get_unchecked_mut() };
pinned.pointer = &pinned.data;
}
println!("{}", unsafe { *b.pointer });
}
```
```rust
error[E0658]: use of unstable library feature 'unsafe_pin_internals'
--> <source>:19:30
|
19 | println!("{}", unsafe { *b.pointer });
| ^^^^^^^^^
error[E0277]: `Pinned` doesn't implement `std::fmt::Display`
--> <source>:19:20
|
19 | println!("{}", unsafe { *b.pointer });
| ^^^^^^^^^^^^^^^^^^^^^ `Pinned` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `Pinned`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
```
Since the user named their field `pointer`, it conflicts with the `pointer` field on `Pin`, which is public but unstable since Rust 1.60.0 with #93176. On versions from 1.33.0 to 1.59.0, where the field on `Pin` is private, this program compiles and prints `42` as expected.
To avoid this confusing behavior, this PR renames `pointer` to `__pointer`, so that it's less likely to conflict with a `pointer` field on the underlying type, as accessed through the `Deref` impl. This is technically a breaking change for anyone who names their field `__pointer` on the inner type; if this is undesirable, it could be renamed to something more longwinded. It's also a nightly breaking change for any external users of `unsafe_pin_internals`.
impl `From<&[T; N]>` for `Cow<[T]>`
Implement `From<&[T; N]>` for `Cow<[T]>` to simplify its usage in the following example.
```rust
fn foo(data: impl Into<Cow<'static, [&'static str]>>) { /* ... */ }
fn main() {
foo(vec!["hello", "world"]);
foo(&["hello", "world"]); // Error: the trait `From<&[&str; 2]>` is not implemented for `Cow<'static, [&'static str]>`
foo(&["hello", "world"] as &[_]); // Explicit convertion into a slice is required
}
```
stabilise array methods
Closes#76118
Stabilises the remaining array methods
FCP is yet to be carried out for this
There wasn't a clear consensus on the naming, but all the other alternatives had some flaws as discussed in the tracking issue and there was a silence on this issue for a year
Subtree sync for rustc_codegen_cranelift
A couple of fixes as well as an update to Cranelift 0.104, which includes a fix for the ABI of `Option<u128>`.
r? `@ghost`
`@rustbot` label +A-codegen +A-cranelift +T-compiler
Don't fire `OPAQUE_HIDDEN_INFERRED_BOUND` on sized return of AFIT
Conceptually, we should probably not fire `OPAQUE_HIDDEN_INFERRED_BOUND` for methods like:
```
trait Foo { async fn bar() -> Self; }
```
Even though we technically cannot prove that `Self: Sized`, which is one of the item bounds of the `Output` type in the `-> impl Future<Output = Sized>` from the async desugaring.
This is somewhat justifiable along the same lines as how we allow regular methods to return `-> Self` even though `Self` isn't sized.
Fixes#113538
(side-note: some days i wonder if we should just remove the `OPAQUE_HIDDEN_INFERRED_BOUND` lint... it does make me sad that we have non-well-formed types in signatures, though.)
privacy: Refactor top-level visiting in `NamePrivacyVisitor`
Full hierarchical visiting (`nested_filter::All`) is not necessary, visiting all item-likes in isolation is enough.
Tracking current item is not necessary, passing any `HirId` with the same parent module to `adjust_ident_and_get_scope` is enough.
Follow up to https://github.com/rust-lang/rust/pull/120284.
Remove special-case handling of `vec.split_off(0)`
#76682 added special handling to `Vec::split_off` for the case where `at == 0`. Instead of copying the vector's contents into a freshly-allocated vector and returning it, the special-case code steals the old vector's allocation, and replaces it with a new (empty) buffer with the same capacity.
That eliminates the need to copy the existing elements, but comes at a surprising cost, as seen in #119913. The returned vector's capacity is no longer determined by the size of its contents (as would be expected for a freshly-allocated vector), and instead uses the full capacity of the old vector.
In cases where the capacity is large but the size is small, that results in a much larger capacity than would be expected from reading the documentation of `split_off`. This is especially bad when `split_off` is called in a loop (to recycle a buffer), and the returned vectors have a wide variety of lengths.
I believe it's better to remove the special-case code, and treat `at == 0` just like any other value:
- The current documentation states that `split_off` returns a “newly allocated vector”, which is not actually true in the current implementation when `at == 0`.
- If the value of `at` could be non-zero at runtime, then the caller has already agreed to the cost of a full memcpy of the taken elements in the general case. Avoiding that copy would be nice if it were close to free, but the different handling of capacity means that it is not.
- If the caller specifically wants to avoid copying in the case where `at == 0`, they can easily implement that behaviour themselves using `mem::replace`.
Fixes#119913.