valtree performance tuning
Summary: This PR makes type checking of code with many type-level constants faster.
After https://github.com/rust-lang/rust/pull/136180 was merged, we observed a small perf regression (https://github.com/rust-lang/rust/pull/136318#issuecomment-2635562821). This happened because that PR introduced additional copies in the fast reject code path for consts, which is very hot for certain crates: 6c1d960d88/compiler/rustc_type_ir/src/fast_reject.rs (L486-L487)
This PR improves the performance again by properly interning the valtrees so that copying and comparing them becomes faster. This will become especially useful with `feature(adt_const_params)`, so the fast reject code doesn't have to do a deep compare of the valtrees.
Note that we can't just compare the interned consts themselves in the fast reject, because sometimes `'static` lifetimes in the type are be replaced with inference variables (due to canonicalization) on one side but not the other.
A less invasive alternative that I considered is simply avoiding copies introduced by https://github.com/rust-lang/rust/pull/136180 and comparing the valtrees it in-place (see commit: 9e91e50ac5 / perf results: https://github.com/rust-lang/rust/pull/136593#issuecomment-2642303245), however that was still measurably slower than interning.
There are some minor regressions in secondary benchmarks: These happen due to changes in memory allocations and seem acceptable to me. The crates that make heavy use of valtrees show no significant changes in memory usage.
Rollup of 8 pull requests
Successful merges:
- #134999 (Add cygwin target.)
- #136559 (Resolve named regions when reporting type test failures in NLL)
- #136660 (Use a trait to enforce field validity for union fields + `unsafe` fields + `unsafe<>` binder types)
- #136858 (Parallel-compiler-related cleanup)
- #136881 (cg_llvm: Reduce visibility of all functions in the llvm module)
- #136888 (Always perform discr read for never pattern in EUV)
- #136948 (Split out the `extern_system_varargs` feature)
- #136949 (Fix import in bench for wasm)
r? `@ghost`
`@rustbot` modify labels: rollup
Split out the `extern_system_varargs` feature
After the stabilization PR was opened, `extern "system"` functions were added to `extended_varargs_abi_support`. This has a number of questions regarding it that were not discussed and were somewhat surprising. It deserves to be considered as its own feature, separate from `extended_varargs_abi_support`.
Tracking issue:
- https://github.com/rust-lang/rust/issues/136946
Always perform discr read for never pattern in EUV
Always perform a read of `!` discriminants to ensure that it's captured by closures in expr use visitor
Fixes#136852
r? Nadrieril or reassign
cg_llvm: Reduce visibility of all functions in the llvm module
Next part of #135502
This reduces the visibility of all functions in the `llvm` module to `pub(crate)` and marks the `enzyme_ffi` modules with `#![expect(dead_code)]` (as previously discussed: <https://github.com/rust-lang/rust/pull/135502#discussion_r1915608085>).
r? ``@Zalathar``
Parallel-compiler-related cleanup
Parallel-compiler-related cleanup
I carefully split changes into commits. Commit messages are self-explanatory. Squashing is not recommended.
cc "Parallel Rustc Front-end" https://github.com/rust-lang/rust/issues/113349
r? SparrowLii
``@rustbot`` label: +WG-compiler-parallel
Use a trait to enforce field validity for union fields + `unsafe` fields + `unsafe<>` binder types
This PR introduces a new, internal-only trait called `BikeshedGuaranteedNoDrop`[^1] to faithfully model the field check that used to be implemented manually by `allowed_union_or_unsafe_field`.
942db6782f/compiler/rustc_hir_analysis/src/check/check.rs (L84-L115)
Copying over the doc comment from the trait:
```rust
/// Marker trait for the types that are allowed in union fields, unsafe fields,
/// and unsafe binder types.
///
/// Implemented for:
/// * `&T`, `&mut T` for all `T`,
/// * `ManuallyDrop<T>` for all `T`,
/// * tuples and arrays whose elements implement `BikeshedGuaranteedNoDrop`,
/// * or otherwise, all types that are `Copy`.
///
/// Notably, this doesn't include all trivially-destructible types for semver
/// reasons.
///
/// Bikeshed name for now.
```
As far as I am aware, there's no new behavior being guaranteed by this trait, since it operates the same as the manually implemented check. We could easily rip out this trait and go back to using the manually implemented check for union fields, however using a trait means that this code can be shared by WF for `unsafe<>` binders too. See the last commit.
The only diagnostic changes are that this now fires false-negatives for fields that are ill-formed. I don't consider that to be much of a problem though.
r? oli-obk
[^1]: Please let's not bikeshed this name lol. There's no good name for `ValidForUnsafeFieldsUnsafeBindersAndUnionFields`.
Resolve named regions when reporting type test failures in NLL
Just a improvement tweak to an error message that I broke out of a bigger PR that I had to close lol
Previously it only did integer-ABI things, but this way it does data pointers too. That gives more information in general to the backend, and allows slightly simplifying one of the helpers in slice iterators.
After the stabilization PR was opened, `extern "system"` functions were
added to `extended_varargs_abi_support`. This has a number of questions
regarding it that were not discussed and were somewhat surprising.
It deserves to be considered as its own feature, separate from
`extended_varargs_abi_support`.
When preparing a function's coverage counters and metadata during codegen, any
part of the original coverage graph that was removed by MIR optimizations can
be treated as having an execution count of zero.
Somewhat counter-intuitively, if we give those unreachable nodes a _higher_
priority for receiving physical counters (instead of counter expressions), that
ends up reducing the total number of physical counters needed.
This works because if a node is unreachable, we don't actually create a
physical counter for it. Instead that node gets a fixed zero counter, and any
other node that would have relied on that physical counter in its counter
expression can just ignore that term completely.
Fix cycle when debug-printing opaque types from RPITIT
Extend #66594 to opaque types from RPITIT.
Before this PR, enabling debug logging like `RUSTC_LOG="[check_type_bounds]"` for code containing RPITIT produces a query cycle of `explicit_item_bounds`, as pretty printing for opaque type calls [it](d9a4a47b8b/compiler/rustc_middle/src/ty/print/pretty.rs (L1001)).
Mark condition/carry bit as clobbered in C-SKY inline assembly
C-SKY's compare and some arithmetic/logical instructions modify condition/carry bit (C) in PSR, but there is currently no way to mark it as clobbered in `asm!`.
This PR marks it as clobbered except when [`options(preserves_flags)`](https://doc.rust-lang.org/reference/inline-assembly.html#r-asm.options.supported-options.preserves_flags) is used.
Refs:
- Section 1.3 "Programming model" and Section 1.3.5 "Condition/carry bit" in CSKY Architecture user_guide:
9f7121f7d4/CSKY%20Architecture%20user_guide.pdf
> Under user mode, condition/carry bit (C) is located in the lowest bit of PSR, and it can be
accessed and changed by common user instructions. It is the only data bit that can be visited
under user mode in PSR.
> Condition or carry bit represents the result after one operation. Condition/carry bit can be
clearly set according to the results of compare instructions or unclearly set as some
high-precision arithmetic or logical instructions. In addition, special instructions such as
DEC[GT,LT,NE] and XTRB[0-3] will influence the value of condition/carry bit.
- Register definition in LLVM:
https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/CSKY/CSKYRegisterInfo.td#L88
cc ```@Dirreke``` ([target maintainer](aa6f5ab18e/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md (target-maintainers)))
r? ```@Amanieu```
```@rustbot``` label +O-csky +A-inline-assembly
Reject `?Trait` bounds in various places where we unconditionally warned since 1.0
fixes#135730fixes#135809
Also a breaking change, so let's see what crater says.
This has been an unconditional warning since *before* 1.0
Cast allocas to default address space
Pointers for variables all need to be in the same address space for correct compilation. Therefore ensure that even if an `alloca` is created in a different address space, it is casted to the default address space before its value is used.
This is necessary for the amdgpu target and others where the default address space for `alloca`s is not 0.
For example the following code compiles incorrectly when not casting the address space to the default one:
```rust
fn f(p: *const i8 /* addrspace(0) */) -> *const i8 /* addrspace(0) */ {
let local = 0i8; /* addrspace(5) */
let res = if cond { p } else { &raw const local };
res
}
```
results in
```llvm
%local = alloca addrspace(5) i8
%res = alloca addrspace(5) ptr
if:
; Store 64-bit flat pointer
store ptr %p, ptr addrspace(5) %res
else:
; Store 32-bit scratch pointer
store ptr addrspace(5) %local, ptr addrspace(5) %res
ret:
; Load and return 64-bit flat pointer
%res.load = load ptr, ptr addrspace(5) %res
ret ptr %res.load
```
For amdgpu, `addrspace(0)` are 64-bit pointers, `addrspace(5)` are 32-bit pointers.
The above code may store a 32-bit pointer and read it back as a 64-bit pointer, which is obviously wrong and cannot work. Instead, we need to `addrspacecast %local to ptr addrspace(0)`, then we store and load the correct type.
Tracking issue: #135024
Stabilize target_feature_11
# Stabilization report
This is an updated version of https://github.com/rust-lang/rust/pull/116114, which is itself a redo of https://github.com/rust-lang/rust/pull/99767. Most of this commit and report were copied from those PRs. Thanks ```@LeSeulArtichaut``` and ```@calebzulawski!```
## Summary
Allows for safe functions to be marked with `#[target_feature]` attributes.
Functions marked with `#[target_feature]` are generally considered as unsafe functions: they are unsafe to call, cannot *generally* be assigned to safe function pointers, and don't implement the `Fn*` traits.
However, calling them from other `#[target_feature]` functions with a superset of features is safe.
```rust
// Demonstration function
#[target_feature(enable = "avx2")]
fn avx2() {}
fn foo() {
// Calling `avx2` here is unsafe, as we must ensure
// that AVX is available first.
unsafe {
avx2();
}
}
#[target_feature(enable = "avx2")]
fn bar() {
// Calling `avx2` here is safe.
avx2();
}
```
Moreover, once https://github.com/rust-lang/rust/pull/135504 is merged, they can be converted to safe function pointers in a context in which calling them is safe:
```rust
// Demonstration function
#[target_feature(enable = "avx2")]
fn avx2() {}
fn foo() -> fn() {
// Converting `avx2` to fn() is a compilation error here.
avx2
}
#[target_feature(enable = "avx2")]
fn bar() -> fn() {
// `avx2` coerces to fn() here
avx2
}
```
See the section "Closures" below for justification of this behaviour.
## Test cases
Tests for this feature can be found in [`tests/ui/target_feature/`](f6cb952dc1/tests/ui/target-feature).
## Edge cases
### Closures
* [target-feature 1.1: should closures inherit target-feature annotations? #73631](https://github.com/rust-lang/rust/issues/73631)
Closures defined inside functions marked with #[target_feature] inherit the target features of their parent function. They can still be assigned to safe function pointers and implement the appropriate `Fn*` traits.
```rust
#[target_feature(enable = "avx2")]
fn qux() {
let my_closure = || avx2(); // this call to `avx2` is safe
let f: fn() = my_closure;
}
```
This means that in order to call a function with #[target_feature], you must guarantee that the target-feature is available while the function, any closures defined inside it, as well as any safe function pointers obtained from target-feature functions inside it, execute.
This is usually ensured because target features are assumed to never disappear, and:
- on any unsafe call to a `#[target_feature]` function, presence of the target feature is guaranteed by the programmer through the safety requirements of the unsafe call.
- on any safe call, this is guaranteed recursively by the caller.
If you work in an environment where target features can be disabled, it is your responsibility to ensure that no code inside a target feature function (including inside a closure) runs after this (until the feature is enabled again).
**Note:** this has an effect on existing code, as nowadays closures do not inherit features from the enclosing function, and thus this strengthens a safety requirement. It was originally proposed in #73631 to solve this by adding a new type of UB: “taking a target feature away from your process after having run code that uses that target feature is UB” .
This was motivated by userspace code already assuming in a few places that CPU features never disappear from a program during execution (see i.e. 2e29bdf908/crates/std_detect/src/detect/arch/x86.rs); however, concerns were raised in the context of the Linux kernel; thus, we propose to relax that requirement to "causing the set of usable features to be reduced is unsafe; when doing so, the programmer is required to ensure that no closures or safe fn pointers that use removed features are still in scope".
* [Fix #[inline(always)] on closures with target feature 1.1 #111836](https://github.com/rust-lang/rust/pull/111836)
Closures accept `#[inline(always)]`, even within functions marked with `#[target_feature]`. Since these attributes conflict, `#[inline(always)]` wins out to maintain compatibility.
### ABI concerns
* [The extern "C" ABI of SIMD vector types depends on target features #116558](https://github.com/rust-lang/rust/issues/116558)
The ABI of some types can change when compiling a function with different target features. This could have introduced unsoundness with target_feature_11, but recent fixes (#133102, #132173) either make those situations invalid or make the ABI no longer dependent on features. Thus, those issues should no longer occur.
### Special functions
The `#[target_feature]` attribute is forbidden from a variety of special functions, such as main, current and future lang items (e.g. `#[start]`, `#[panic_handler]`), safe default trait implementations and safe trait methods.
This was not disallowed at the time of the first stabilization PR for target_features_11, and resulted in the following issues/PRs:
* [`#[target_feature]` is allowed on `main` #108645](https://github.com/rust-lang/rust/issues/108645)
* [`#[target_feature]` is allowed on default implementations #108646](https://github.com/rust-lang/rust/issues/108646)
* [#[target_feature] is allowed on #[panic_handler] with target_feature 1.1 #109411](https://github.com/rust-lang/rust/issues/109411)
* [Prevent using `#[target_feature]` on lang item functions #115910](https://github.com/rust-lang/rust/pull/115910)
## Documentation
* Reference: [Document the `target_feature_11` feature reference#1181](https://github.com/rust-lang/reference/pull/1181)
---
cc tracking issue https://github.com/rust-lang/rust/issues/69098
cc ```@workingjubilee```
cc ```@RalfJung```
r? ```@rust-lang/lang```
Rename rustc_middle::Ty::is_unsafe_ptr to is_raw_ptr
The wording unsafe pointer is less common and not mentioned in a lot of places, instead this is usually called a "raw pointer". For the sake of uniformity, we rename this method.
This came up during the review of
https://github.com/rust-lang/rust/pull/134424.
r? `@Noratrieb`
compiler: give `ExternAbi` truly stable `Hash` and `Ord`
Currently, `ExternAbi` has a bunch of code to handle the reality that, as an enum, adding more variants to it will risk it hashing differently. It forces all of those variants to be added in a fixed order, except this means that the order of the variants doesn't correspond to any logical order except "historical accident". This is all to avoid having to rebless two tests. Perhaps there were more, once upon a time? But then we invented normalization in our test suite to handle exactly this sort of issue in a more general way.
There are two options here:
- Get rid of all the logical overhead and shrug, embracing blessing a couple of tests sometimes
- Change `ExternAbi` to have an ordering and hash that doesn't depend on the number of variants
As `ExternAbi` is essentially a strongly-typed string, and thus no two strings can be identical, this implements the second of the two by hand-implementing `Ord` and `Hash` to make the hashing and comparison based on the string! This will diff the current hashes, but they will diff no more after this.
Previously, we unconditionally set the bitwidth to 128-bits, the largest
an discrimnator would possibly be. Then, LLVM would cut down the constant by
chopping off leading zeroes before emitting the DWARF. LLVM only
supported 64-bit descriminators, so this would also have occasionally
resulted in truncated data (or an assert) if more than 64-bits were
used.
LLVM added support for 128-bit enumerators in llvm/llvm-project#125578
That patchset also trusts the constant to describe how wide the variant tag is.
As a result, we went from emitting tags that looked like:
DW_AT_discr_value (0xfe)
(`form1`)
to emitting tags that looked like:
DW_AT_discr_value (<0x10> fe ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 )
This makes the `DW_AT_discr_value` encode at the bitwidth of the tag,
which:
1. Is probably closer to our intentions in terms of describing the data.
2. Doesn't invoke the 128-bit support which may not be supported by all
debuggers / downstream tools.
3. Will result in smaller debug information.
Rollup of 8 pull requests
Successful merges:
- #134981 ( Explain that in paths generics can't be set on both the enum and the variant)
- #136698 (Replace i686-unknown-redox target with i586-unknown-redox)
- #136767 (improve host/cross target checking)
- #136829 ([rustdoc] Move line numbers into the `<code>` directly)
- #136875 (Rustc dev guide subtree update)
- #136900 (compiler: replace `ExternAbi::name` calls with formatters)
- #136913 (Put kobzol back on review rotation)
- #136915 (documentation fix: `f16` and `f128` are not double-precision)
r? `@ghost`
`@rustbot` modify labels: rollup
compiler: replace `ExternAbi::name` calls with formatters
Most of these just format the ABI string, so... just format ExternAbi? This makes it more consistent and less jank when we can do it.
Explain that in paths generics can't be set on both the enum and the variant
```
error[E0109]: type arguments are not allowed on tuple variant `TSVariant`
--> $DIR/enum-variant-generic-args.rs:54:29
|
LL | Enum::<()>::TSVariant::<()>(());
| --------- ^^ type argument not allowed
| |
| not allowed on tuple variant `TSVariant`
|
= note: generic arguments are not allowed on both an enum and its variant's path segments simultaneously; they are only valid in one place or the other
help: remove the generics arguments from one of the path segments
|
LL - Enum::<()>::TSVariant::<()>(());
LL + Enum::TSVariant::<()>(());
|
LL - Enum::<()>::TSVariant::<()>(());
LL + Enum::<()>::TSVariant(());
|
```
Fix#93993.
Rollup of 8 pull requests
Successful merges:
- #135549 (Document some safety constraints and use more safe wrappers)
- #135965 (In "specify type" suggestion, skip type params that are already known)
- #136193 (Implement pattern type ffi checks)
- #136646 (Add a TyPat in the AST to reuse the generic arg lowering logic)
- #136874 (Change the issue number for `likely_unlikely` and `cold_path`)
- #136884 (Lower fn items as ZST valtrees and delay a bug)
- #136885 (i686-linux-android: increase CPU baseline to Pentium 4 (without an actual change)
- #136891 (Check sig for errors before checking for unconstrained anonymous lifetime)
r? `@ghost`
`@rustbot` modify labels: rollup
i686-linux-android: increase CPU baseline to Pentium 4 (without an actual change
As per ``@maurer's`` [comment](https://github.com/rust-lang/rust/issues/136495#issuecomment-2648743078), this shouldn't actually change anything since we anyway add a bunch of extensions that bump things up way beyond Pentium 4. But Pentium 4 is consistent with the other i686 targets and I don't know enough about the exact sequence of CPU generations to be confident with more than this. ;)
Lower fn items as ZST valtrees and delay a bug
Lower it as a ZST instead of a const error, which we can handle mostly fine. Delay a bug so we don't accidentally support it tho.
r? BoxyUwU
Fixes#136855Fixes#136853Fixes#136854Fixes#136337
Only added one test bc that's really the crux of the issue (fn item in array length position).
Add a TyPat in the AST to reuse the generic arg lowering logic
This simplifies ast lowering significantly with little cost to the pattern types parser.
Also fixes any problems we've had with generic args (well, pushes any problems onto the `generic_const_exprs` feature gate)
follow-up to https://github.com/rust-lang/rust/pull/136284#discussion_r1939292367
r? ``@BoxyUwU``
Implement pattern type ffi checks
Previously we just rejected pattern types outright in FFI, but that was never meant to be a permanent situation. We'll need them supported to use them as the building block for `NonZero` and `NonNull` after all (both of which are FFI safe).
best reviewed commit by commit.
In "specify type" suggestion, skip type params that are already known
When we suggest specifying a type for an expression or pattern, like in a `let` binding, we previously would print the entire type as the type system knew it. We now look at the params that have *no* inference variables, so they are fully known to the type system which means that they don't need to be specified.
This helps in suggestions for types that are really long, because we can usually skip most of the type params and make the annotation as short as possible:
```
error[E0282]: type annotations needed for `Result<_, ((..., ..., ..., ...), ..., ..., ...)>`
--> $DIR/really-long-type-in-let-binding-without-sufficient-type-info.rs:7:9
|
LL | let y = Err(x);
| ^ ------ type must be known at this point
|
help: consider giving `y` an explicit type, where the type for type parameter `T` is specified
|
LL | let y: Result<T, _> = Err(x);
| ++++++++++++++
```
Fix#135919.
Document some safety constraints and use more safe wrappers
Lots of unsafe codegen_llvm code has safe wrappers already, so I used some of them and added some where applicable. I stopped here because this diff is large enough and should probably be reviewed independently of other changes.
These were a way to ensure hashes were stable over time for ExternAbi,
but simply hashing the strings is more stable in the face of changes.
As a result, we can do away with them.
Directly map each ExternAbi variant to its string and back again.
This has a few advantages:
- By making the ABIs compare equal to their strings, we can easily
lexicographically sort them and use that sorted slice at runtime.
- We no longer need a workaround to make sure the hashes remain stable,
as they already naturally are (by being the hashes of unique strings).
- The compiler can carry around less &str wide pointers
Properly deeply normalize in the next solver
Turn deep normalization into a `TypeOp`. In the old solver, just dispatch to the `Normalize` type op, but in the new solver call `deeply_normalize`. I chose to separate it into a different type op b/c some normalization is a no-op in the new solver, so this distinguishes just the normalization we need for correctness.
Then use `DeeplyNormalize` in the callsites we used to be using a `CustomTypeOp` (for normalizing known type outlives obligations), and also use it to normalize function args and impl headers in the new solver.
Finally, use it to normalize signatures for WF checks in the new solver as well. This addresses https://github.com/rust-lang/trait-system-refactor-initiative/issues/146.
```
error[E0109]: type arguments are not allowed on tuple variant `TSVariant`
--> $DIR/enum-variant-generic-args.rs:54:29
|
LL | Enum::<()>::TSVariant::<()>(());
| --------- ^^ type argument not allowed
| |
| not allowed on tuple variant `TSVariant`
|
= note: generic arguments are not allowed on both an enum and its variant's path segments simultaneously; they are only valid in one place or the other
help: remove the generics arguments from one of the path segments
|
LL - Enum::<()>::TSVariant::<()>(());
LL + Enum::<()>::TSVariant(());
|
```
```
error[E0109]: type arguments are not allowed on enum `Enum` and tuple variant `TSVariant`
--> $DIR/enum-variant-generic-args.rs:54:12
|
LL | Enum::<()>::TSVariant::<()>(());
| ---- ^^ --------- ^^ type argument not allowed
| | |
| | not allowed on tuple variant `TSVariant`
| not allowed on enum `Enum`
|
= note: generic arguments are not allowed on both an enum and its variant's path segments simultaneously; they are only valid in one place or the other
help: remove the generics arguments from one of the path segments
|
LL - Enum::<()>::TSVariant::<()>(());
LL + Enum::<()>::TSVariant(());
|
```
Fix#93993.
Simplify intra-crate qualifiers.
The following is a weird pattern for a file within `rustc_middle`:
```
use rustc_middle::aaa;
use crate::bbb;
```
More sensible and standard would be this:
```
use crate::{aaa, bbb};
```
I.e. we generally prefer using `crate::` to using a crate's own name. (Exceptions are things like in macros where `crate::` doesn't work because the macro is used in multiple crates.)
This commit fixes a bunch of these weird qualifiers.
r? `@jieyouxu`
compiler: die immediately instead of handling unknown target codegen
We cannot produce anything useful if asked to compile unknown targets. We should handle the error immediately at the point of discovery instead of propagating it upward, and preferably in the simplest way: Die.
This allows cleaning up our "error-handling" spread across 5 crates.
show supported register classes in error message
a simple diagnostic change that shows the supported register classes when an invalid one is found.
This information can be hard to find (especially for unstable targets), and this message now gives at least something to try or search for. I've followed the pattern for invalid clobber ABIs.
`@rustbot` label +A-inline-assembly
fix ensure_monomorphic_enough
When polymorphization was still a thing, the visitor was used to only recurse into *used generic parameters* of function/closure/coroutine types and allow unused parameters (i.e. the polymorphized parameters) to remain generic.
When polymorphization got removed, this got changed to always treat all parameters as polymorphic and never recurse into them: https://github.com/rust-lang/rust/pull/133883/files#diff-210c59e321070d0ca4625c04e9fb064bf43ddc34082e7e33a7ee8a6c577e95afL44-L62
This is clearly wrong and can cause MIR opts to misbehave, for example this currently prints "false" in release mode:
```rust
#![feature(core_intrinsics)]
fn generic<T>() {}
const fn type_id_of_val<T: 'static>(_: &T) -> u128 {
std::intrinsics::type_id::<T>()
}
fn cursed_is_i32<T: 'static>() -> bool {
(const { type_id_of_val(&generic::<T>) } == const { type_id_of_val(&generic::<i32>) })
}
fn main() {
dbg!(cursed_is_i32::<i32>());
}
```
This PR reverts to the old behavior of always treating all types that contain type parameters as too generic, like we used to do without `-Zpolymorphize` before.
~~I'm not including the above as a test case here, because I think there is little value in testing code paths that have been removed and this seems unlikely to regress in a way that would be caught by a regression test, but let me know if you disagree and want me to add a test anyway.~~
Overhaul how contracts are lowered on fn-like bodies
Consolidates all of the contracts lowering logic into `lower_fn_body`, rather than having it be split between `lower_item_kind` and `lower_fn_body`. This should fix#136683.
r? celinval
Stop using span hack for contracts feature gating
The contracts machinery is a pretty straightforward case of an *external* feature using a (perma-unstable) *internal* feature within its implementation. There's no reason why it needs to be implemented any differently than other features by using global span tracking hacks to change whether the internals are gated behind the `contracts` or `contracts_internals` feature gate -- for the case of macro expansions we already have `allow_internal_unstable` for exactly this situation.
This PR changes the internal, perma-unstable AST syntax to use the `contracts_internals` gate always, and adjusts the macro expansion to use the right spans so that `allow_internal_unstable` works correctly.
As a follow-up, there's really no reason to have `contracts` be a *compiler feature* since it's at this point fully a *library feature*; the only reason it's a compiler feature today is so we can mark it as incomplete, but that seems like a weak reason. I didn't do anything in this PR for this.
r? ``@celinval``
cg_llvm: Reduce visibility of some items outside the `llvm` module
Next piece of #135502
This reduces the visibility of items (other than those in the `llvm` module) so that dead code analysis will correctly identify unused items.