Add `Debug` impls to API types in `rustc_codegen_ssa`
Some types used in `rustc_codegen_ssa`'s interface traits are missing `Debug` impls. Though I did not smear `#[derive(Debug)]` all over the crate (some structs are quite large).
Don't re-elaborated already elaborated caller bounds in method probe
Caller bounds are already elaborated. Only elaborate object candidates' principals.
Also removes the only usage of `transitive_bounds`.
Enforce supertrait outlives obligations hold when confirming impl
**TL;DR:** We elaborate super-predicates and apply any outlives obligations when proving an impl holds to fix a mismatch between implied bounds.
Bugs in implied bounds (and implied well-formedness) occur whenever there is a mismatch between the assumptions that some code can assume to hold, and the obligations that a caller/user of that code must prove. If the former is stronger than the latter, then unsoundness occurs.
Take a look at the example unsoundness:
```rust
use std::fmt::Display;
trait Static: 'static {}
impl<T> Static for &'static T {}
fn foo<S: Display>(x: S) -> Box<dyn Display>
where
&'static S: Static,
{
Box::new(x)
}
fn main() {
let s = foo(&String::from("blah blah blah"));
println!("{}", s);
}
```
This specific example occurs because we elaborate obligations in `fn foo`:
* `&'static S: Static`
* `&'static S: 'static` <- super predicate
* `S: 'static` <- elaborating outlives bounds
However, when calling `foo`, we only need to prove the direct set of where clauses. So at the call site for some substitution `S = &'not_static str`, that means only proving `&'static &'not_static str: Static`. To prove this, we apply the impl, which itself holds trivially since it has no where clauses.
This is the mismatch -- `foo` is allowed to assume that `S: 'static` via elaborating supertraits, but callers of `foo` never need to prove that `S: 'static`.
There are several approaches to fixing this, all of which have problems due to current limitations in our type system:
1. proving the elaborated set of predicates always - This leads to issues since we don't have coinductive trait semantics, so we easily hit new cycles.
* This would fix our issue, since callers of `foo` would have to both prove `&'static &'not_static str: Static` and its elaborated bounds, which would surface the problematic `'not_static: 'static` outlives obligation.
* However, proving supertraits when proving impls leads to inductive cycles which can't be fixed until we get coinductive trait semantics.
2. Proving that an impl header is WF when applying that impl:
* This would fix our issue, since when we try to prove `&'static &'not_static str: Static`, we'd need to prove `WF(&'static &'not_static str)`, which would surface the problematic `'not_static: 'static` outlives obligation.
* However, this leads to issues since we don't have higher-ranked implied bounds. This breaks things when trying to apply impls to higher-ranked trait goals.
To get around these limitations, we apply a subset of (1.), which is to elaborate the supertrait obligations of the impl but filter only the (region/type) outlives out of that set, since those can never participate in an inductive cycle. This is likely not sufficient to fix a pathological example of this issue, but it does clearly fill in a major gap that we're currently overlooking.
This can also result in 'unintended' errors due to missing implied-bounds on binders. We did not encounter this in the crater run and don't expect people to rely on this code in practice:
```rust
trait Outlives<'b>: 'b {}
impl<'b, T> Outlives<'b> for &'b T {}
fn foo<'b>()
where
// This bound will break due to this PR as we end up proving
// `&'b &'!a (): 'b` without the implied `'!a: 'b`
// bound.
for<'a> &'b &'a (): Outlives<'b>,
{}
```
Fixes#98117
---
Crater: https://github.com/rust-lang/rust/pull/124336#issuecomment-2209165320
Triaged: https://github.com/rust-lang/rust/pull/124336#issuecomment-2236321325
All of the fallout is due to generic const exprs, and can be ignored.
Migrate `reproducible-build-2` and `stable-symbol-names` `run-make` tests to rmake
Part of #121876 and the associated [Google Summer of Code project](https://blog.rust-lang.org/2024/05/01/gsoc-2024-selected-projects.html).
Needs try-jobs.
try-job: x86_64-msvc
try-job: armhf-gnu
try-job: test-various
try-job: aarch64-apple
try-job: i686-msvc
try-job: x86_64-mingw
Rollup of 8 pull requests
Successful merges:
- #128026 (std:🧵 available_parallelism implementation for vxWorks proposal.)
- #128471 (rustdoc: Fix handling of `Self` type in search index and refactor its representation)
- #128607 (Use `object` in `run-make/symbols-visibility`)
- #128609 (Remove unnecessary constants from flt2dec dragon)
- #128611 (run-make: Remove cygpath)
- #128619 (Correct the const stabilization of `<[T]>::last_chunk`)
- #128630 (docs(resolve): more explain about `target`)
- #128660 (tests: more crashes)
r? `@ghost`
`@rustbot` modify labels: rollup
Correct the const stabilization of `<[T]>::last_chunk`
`<[T]>::first_chunk` became const stable in 1.77, but `<[T]>::last_chunk` was left out. This was fixed in 3488679768, which reached stable in 1.80, making `<[T]>::last_chunk` const stable as of that version, but it is documented as being const stable as 1.77. While this is what should have happened, the documentation should reflect what actually did happen.
Remove unnecessary constants from flt2dec dragon
The "dragon" `flt2dec` algorithm uses multi-precision multiplication by (sometimes large) powers of 10. It has precomputed some values to help with these calculations.
BUT:
* There is no need to store powers of 10 and 2 * powers of 10: it is trivial to compute the second from the first.
* We can save a chunk of memory by storing powers of 5 instead of powers of 10 for the large powers (and just shifting as appropriate).
* This also slightly speeds up the routines (by ~1-3%) since the intermediate products are smaller and the shift is cheap.
In this PR, we remove the unnecessary constants and do the necessary adjustments.
Relevant benchmarks before (on my Threadripper 3970X, x86_64-unknown-linux-gnu):
```
num::flt2dec::bench_big_shortest 137.92/iter +/- 2.24
num::flt2dec::strategy:🐉:bench_big_exact_12 2135.28/iter +/- 38.90
num::flt2dec::strategy:🐉:bench_big_exact_3 904.95/iter +/- 10.58
num::flt2dec::strategy:🐉:bench_big_exact_inf 47230.33/iter +/- 320.84
num::flt2dec::strategy:🐉:bench_big_shortest 3915.05/iter +/- 51.37
```
and after:
```
num::flt2dec::bench_big_shortest 137.40/iter +/- 2.03
num::flt2dec::strategy:🐉:bench_big_exact_12 2101.10/iter +/- 25.63
num::flt2dec::strategy:🐉:bench_big_exact_3 873.86/iter +/- 4.20
num::flt2dec::strategy:🐉:bench_big_exact_inf 47468.19/iter +/- 374.45
num::flt2dec::strategy:🐉:bench_big_shortest 3877.01/iter +/- 45.74
```
Use `object` in `run-make/symbols-visibility`
This is another case where we can simply use a rust library instead of wrangling nm.
try-job: x86_64-msvc
try-job: i686-msvc
try-job: test-various
Rollup of 6 pull requests
Successful merges:
- #127655 (turn `invalid_type_param_default` into a `FutureReleaseErrorReportInDeps`)
- #127907 (built-in derive: remove BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE hack and lint)
- #127974 (force compiling std from source if modified)
- #128309 (Implement cursors for `BTreeSet`)
- #128500 (Add test for updating enum discriminant through pointer)
- #128623 (Do not fire unhandled attribute assertion on multi-segment `AttributeType::Normal` attributes with builtin attribute as first segment)
r? `@ghost`
`@rustbot` modify labels: rollup
Do not fire unhandled attribute assertion on multi-segment `AttributeType::Normal` attributes with builtin attribute as first segment
### The Problem
In #128581 I introduced an assertion to check that all builtin attributes are actually checked via
`CheckAttrVisitor` and aren't accidentally usable on completely unrelated HIR nodes.
Unfortunately, the assertion had correctness problems as revealed in #128622.
The match on attribute path segments looked like
```rs,ignore
// Normal handler
[sym::should_panic] => /* check is implemented */
// Fallback handler
[name, ..] => match BUILTIN_ATTRIBUTE_MAP.get(name) {
// checked below
Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) => {}
Some(_) => {
if !name.as_str().starts_with("rustc_") {
span_bug!(
attr.span,
"builtin attribute {name:?} not handled by `CheckAttrVisitor`"
)
}
}
None => (),
}
```
However, it failed to account for edge cases such as an attribute whose:
1. path segments *starts* with a segment matching the name of a builtin attribute such as `should_panic`, and
2. the first segment's symbol does not start with `rustc_`, and
3. the matched builtin attribute is also of `AttributeType::Normal` attribute type upon registration with the builtin attribute map.
These conditions when all satisfied cause the span bug to be issued for e.g.
`#[should_panic::skip]` because the `[sym::should_panic]` arm is not matched (since it's
`[sym::should_panic, sym::skip]`).
### Proposed Solution
This PR tries to remedy that by adjusting all normal/specific handlers to not match exactly on a single segment, but instead match a prefix segment.
i.e.
```rs,ignore
// Normal handler, notice the `, ..` rest pattern
[sym::should_panic, ..] => /* check is implemented */
// Fallback handler
[name, ..] => match BUILTIN_ATTRIBUTE_MAP.get(name) {
// checked below
Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) => {}
Some(_) => {
if !name.as_str().starts_with("rustc_") {
span_bug!(
attr.span,
"builtin attribute {name:?} not handled by `CheckAttrVisitor`"
)
}
}
None => (),
}
```
### Review Remarks
This PR contains 2 commits:
1. The first commit adds a regression test. This will ICE without the `CheckAttrVisitor` changes.
2. The second commit adjusts `CheckAttrVisitor` assertion logic. Once this commit is applied, the test should no longer ICE and produce the expected bless stderr.
Fixes#128622.
r? ``@nnethercote`` (since you reviewed #128581)
Implement cursors for `BTreeSet`
Tracking issue: https://github.com/rust-lang/rust/issues/107540
This is a straightforward wrapping of the map API, except that map's `CursorMut` does not make sense, because there is no value to mutate. Hence, map's `CursorMutKey` is wrapped here as just `CursorMut`, since it's unambiguous for sets and we don't normally speak of "keys". On the other hand, I can see some potential for confusion with `CursorMut` meaning different things in each module. I'm happy to take suggestions to improve that.
r? ````@Amanieu````
turn `invalid_type_param_default` into a `FutureReleaseErrorReportInDeps`
`````@rust-lang/types````` I assume the plan is still to disallow this? It has been a future-compat lint for a long time, seems ripe to go for hard error.
However, turns out that outright removing it right now would lead to [tons of crater regressions](https://github.com/rust-lang/rust/pull/127655#issuecomment-2228285460), so for now this PR just makes this future-compat lint show up in cargo's reports, so people are warned when they use a dependency that is affected by this.
Fixes https://github.com/rust-lang/rust/issues/27336 by removing the feature gate (so there's no way to silence the lint even on nightly)
CC https://github.com/rust-lang/rust/issues/36887
`<[T]>::first_chunk` became const stable in 1.77, but `<[T]>::last_chunk` was
left out. This was fixed in 3488679768, which reached stable in 1.80,
making `<[T]>::last_chunk` const stable as of that version, but it is
documented as being const stable as 1.77. While this is what should have
happened, the documentation should reflect what actually did happen.
It was barely used, and the places that used it are actually clearer
without it since they were often undoing some of its work. This also
avoids an unnecessary clone of the receiver type and removes a layer of
logical indirection in the code.
This is much more readable and idiomatic, and also may help performance
since `match`es usually use switches while `if`s may not.
I also fixed an incorrect comment.
We already have special-cased code to handle inlining `Self` as the type
or trait it refers to, and this was just causing glitches like the
search `A -> B` yielding blanket `Into` impls.
Rustdoc often has to special-case `Self` because it is, well, a special
type of generic parameter (although it also behaves as an alias in
concrete impls). Instead of spreading this special-casing throughout the
code base, create a new variant of the `clean::Type` enum that is for
`Self` types.
This is a refactoring that has almost no impact on rustdoc's behavior,
except that `&Self`, `(Self,)`, `&[Self]`, and other similar occurrences
of `Self` no longer link to the wrapping type (reference primitive,
tuple primitive, etc.) as regular generics do. I felt this made more
sense since users would expect `Self` to link to the containing trait or
aliased type (though those are usually expanded), not the primitive that
is wrapping it. For an example of the change, see the docs for
`std::alloc::Allocator::by_ref`.