`LevelSpec` has two related fields, `level` and `lint_id`. This commit
makes the fields private (and introduces getters) to ensure they are set
together using only valid combinations.
The commit also introduces `is_allow` and `is_expect` methods because
those are useful.
It is misnamed, given that it has three fields: `level`, `lint_id`, and
`src`. (Presumably the `lint_id` was added later.)
This commit renames it as `LevelSpec`. (I also considered `LevelInfo`
but that's very generic. `Spec` has pre-existing uses in
`LintLevelsProvider::current_specs` and `LintSet::specs` and
`ShallowLintLevelMap::specs`.)
Related things renamed as well:
- `level` -> `level_spec` (where appropriate)
- `lint_levels` -> `lint_level_specs`
- `get_lint_level` -> `get_lint_level_spec`
- `level_and_source` -> `level_spec`
- `CodegenLintLevels` -> `CodegenLintLevelSpecs`
- `raw_lint_id_level` -> `raw_lint_level_spec`
- `lint_level_at_node` -> `lint_level_spec_at_node`
- `reveal_actual_level` -> `reveal_actual_level_spec`
- `probe_for_lint_level` -> `probe_for_lint_level_spec`
This clears up a lot of `Level` vs. `LevelSpec` ambiguity. E.g. no more
`level.level` expressions.
Unnormalized migration: assert_fully_normalized, struct_tail, and `field.ty`
tracking issue: https://github.com/rust-lang/rust/issues/155345 (first checkbox, and partial second checkbox, of that issue)
I'm going a bit slower than expected (less free time than I'd hope, lots of GCA work that I'm doing instead), and figured I'd just submit what I have now rather than building up a big batch of changes. Slow and steady!
r? @lcnr
change the type of the argument of `drop_in_place` lang item to `&mut _`
We used to special case `core::ptr::drop_in_place` when computing LLVM argument attributes with this hack:
https://github.com/rust-lang/rust/blob/db5e2dc248fe5bb26f70d7baec46a3bca9fa3e1d/compiler/rustc_ty_utils/src/abi.rs#L383-L392
This is because even though `drop_in_place` takes a `*mut T` it is semantically a `&mut T` (remember how `&mut Self` is passed to `Drop::drop`). This is apparently relevant for perf.
This PR replaces this hack with a simpler solution -- it makes `drop_in_place` a thin wrapper around newly added `core::ptr::drop_glue`, which is the actual lang item and takes a `&mut T`:
https://github.com/rust-lang/rust/blob/d2563d5003bbecff1efc40c1f5673ceec603825b/library/core/src/ptr/mod.rs#L810-L833
------
The rest of the PR is blessing tests and cleaning up things which are not necessary after this change.
One thing that is a bit awkward is that now that `drop_glue` is the actual lang item, a lot of the comments referring to `drop_in_place` are outdated. Should I try fixing that?
I've also changed `async_drop_in_place` to take a `&mut T`, and it simplified the code handling it a bit. (since it's unstable we don't need to introduce a wrapper)
-------
cc @RalfJung
Closes https://github.com/rust-lang/rust/issues/154274
Improve caching by introducing `TypingMode::ErasedNotCoherence`
r? @lcnr
This introduces `TypingMode::ErasedNotCoherence`. Most typing modes contain a list of opaque types, which are quite often unused during canonicalization. With this change, any time we try canonicalization, we replace whichever typing mode we're currently in with `ErasedNotcoherence`, attempt to canonicalize, and if that fails *retry* in the original typing mode. If erased mode succeeds, this is beneficial because that way the opaque types don't end up in the cache key, allowing more cache reuse.
This seems to have a small (0.5%) slowdown on most programs, but a dramatic (>60%) speedup in specific cases like the rustc-perf `wg-grammar` benchmark. Some more improvements are expected with "eager normalization", which is work that's under way right now.
Every lifting root calls `unwrap`/`expect` on the result, except for
`ImmTy::fmt` but there's no good reason for that exception. Making
lifting infallible is sensible because it should only fail if the wrong
interner is somehow used, which indicates a major bug in rustc rather
than an error condition.
Refactor FnDecl and FnSig non-type fields into a new wrapper type
#### Why this Refactor?
This PR is part of an initial cleanup for the [arg splat experiment](https://github.com/rust-lang/rust/issues/153629), but it's a useful refactor by itself.
It refactors the non-type fields of `FnDecl`, `FnSig`, and `FnHeader` into a new packed wrapper types, based on this comment in the `splat` experiment PR:
https://github.com/rust-lang/rust/pull/153697#discussion_r3004637413
It also refactors some common `FnSig` creation settings into their own methods. I did this instead of creating a struct with defaults.
#### Relationship to `splat` Experiment
I don't think we can use functional struct updates (`..default()`) to create `FnDecl` and `FnSig`, because we need the bit-packing for the `splat` experiment.
Bit-packing will avoid breaking "type is small" assertions for commonly used types when `splat` is added.
This PR packs these types:
- ExternAbi: enum + `unwind` variants (38) -> 6 bits
- ImplicitSelfKind: enum variants (5) -> 3 bits
- lifetime_elision_allowed, safety, c_variadic: bool -> 1 bit
#### Minor Changes
Fixes some typos, and applies rustfmt to clippy files that got skipped somehow.
Most diagnostic types are only used within their own crate, and so have
a `pub(crate)` visibility. We have some diagnostic types that are
unnecessarily `pub`. This is bad because (a) information hiding, and (b)
if a `pub(crate)` type becomes unused the compiler will warn but it
won't warn for a `pub` type.
This commit eliminates unnecessary `pub` visibilities for some
diagnostic types, and also some related things due to knock-on effects.
(I found these types with some ad hoc use of `grep`.)
Start using pattern types in libcore
cc rust-lang/rust#135996
Replaces the innards of `NonNull` with `*const T is !null`.
This does affect LLVM's optimizations, as now reading the field preserves the metadata that the field is not null, and transmuting to another type (e.g. just a raw pointer), will also preserve that information for optimizations. This can cause LLVM opts to do more work, but it's not guaranteed to produce better machine code.
Once we also remove all uses of rustc_layout_scalar_range_start from rustc itself, we can remove the support for that attribute entirely and handle all such needs via pattern types
`ty::Alias` refactor
This PR changes the following alias-related types from this:
```rust
pub enum AliasTyKind {
Projection,
Inherent,
Opaque,
Free,
}
pub struct AliasTy<I: Interner> {
pub args: I::GenericArgs,
pub def_id: I::DefId,
}
pub enum TyKind<I: Interner> {
...
Alias(AliasTyKind, AliasTy<I>),
}
```
Into this:
```rust
pub enum AliasTyKind<I: Interner> {
Projection { def_id: I::DefId },
Inherent { def_id: I::DefId },
Opaque { def_id: I::DefId },
Free { def_id: I::DefId },
}
pub struct AliasTy<I: Interner> {
pub args: I::GenericArgs,
pub kind: AliasTyKind<I>,
}
pub enum TyKind<I: Interner> {
...
Alias(AliasTy<I>),
}
```
... and then does a thousand other changes to accommodate for this change everywhere.
This brings us closer to being able to have `AliasTyKind`s which don't require a `DefId` (and thus can be more easily created, etc). Although notably we depend on both `AliasTyKind -> DefId` and `DefId -> AliasTyKind` conversions in a bunch of places still.
r? lcnr
----
A lot of these changes were done either by search & replace (via `ast-grep`) or on auto pilot, so I'm not quite sure I didn't mess up somewhere, but at least tests pass...
simd_fmin/fmax: make semantics and name consistent with scalar intrinsics
This is the SIMD version of https://github.com/rust-lang/rust/pull/153343: change the documented semantics of the SIMD float min/max intrinsics to that of the scalar intrinsics, and also make the name consistent. The overall semantic change this amounts to is that we restrict the non-determinism: the old semantics effectively mean "when one input is an SNaN, the result non-deterministically is a NaN or the other input"; the new semantics say that in this case the other input must be returned. For all other cases, old and new semantics are equivalent. This means all users of these intrinsics that were correct with the old semantics are still correct: the overall set of possible behaviors has become smaller, no new possible behaviors are being added.
In terms of providers of this API:
- Miri, GCC, and cranelift already implement the new semantics, so no changes are needed.
- LLVM is adjusted to use `minimumnum nsz` instead of `minnum`, thus giving us the new semantics.
In terms of consumers of this API:
- Portable SIMD almost certainly wants to match the scalar behavior, so this is strictly a bugfix here.
- Stdarch mostly stopped using the intrinsic, except on nvptx, where arguably the new semantics are closer to what we actually want than the old semantics (https://github.com/rust-lang/stdarch/issues/2056).
Q: Should there be an `f` in the intrinsic name to indicate that it is for floats? E.g., `simd_fminimum_number_nsz`?
Also see https://github.com/rust-lang/rust/issues/153395.
Merge `fabsf16/32/64/128` into `fabs::<F>`
Following [a small conversation on Zulip](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Float.20intrinsics/with/521501401) (and because I'd be interested in starting to contribute on Rust), I thought I'd give a try at merging the float intrinsics :)
This PR just merges `fabsf16`, `fabsf32`, `fabsf64`, `fabsf128`, as it felt like an easy first target.
Notes:
- I'm opening the PR for one intrinsic as it's probably easier if the shift is done one intrinsic at a time, but let me know if you'd rather I do several at a time to reduce the number of PRs.
- Currently this PR increases LOCs, despite being an attempt at simplifying the intrinsics/compilers. I believe this increase is a one time thing as I had to define new functions and move some things around, and hopefully future PRs/commits will reduce overall LoCs
- `fabsf32` and `fabsf64` are `#[rustc_intrinsic_const_stable_indirect]`, while `fabsf16` and `fabsf128` aren't; because `f32`/`f64` expect the function to be const, the generic version must be made indirectly stable too. We'd need to check with T-lang this change is ok; the only other intrinsics where there is such a mismatch is `minnum`, `maxnum` and `copysign`.
- I haven't touched libm because I'm not familiar with how it works; any guidance would be welcome!