Commit Graph

1115 Commits

Author SHA1 Message Date
bjorn3 973c7527b4 Unify the configuration of the compiler docs
Previously it was rather inconsistent which crates got the rust logo and
which didn't and setting html_root_url was forgotten in many cases.
2025-11-05 11:25:27 +00:00
Stuart Cook b40a20f16d Rollup merge of #147017 - RalfJung:repr-c-big-discriminant, r=davidtwco
FCW for repr(C) enums whose discriminant values do not fit into a c_int or c_uint

Context: https://github.com/rust-lang/rust/issues/124403

The current behavior of repr(C) enums is as follows:
- The discriminant values are interpreted as const expressions of type `isize`
- We compute the smallest size that can hold all discriminant values
- The target spec contains the smallest size for repr(C) enums
- We take the larger of these two sizes

Unfortunately, this doesn't always match what C compilers do. In particular, MSVC seems to *always* give enums a size of 4 bytes, whereas the algorithm above will give enums a size of up to 8 bytes on 64bit targets. Here's an example enum affected by this:
```
// We give this size 4 on 32bit targets (with a warning since the discriminant is wrapped to fit an isize)
// and size 8 on 64bit targets.
#[repr(C)]
enum OverflowingEnum {
    A = 9223372036854775807, // i64::MAX
}

// MSVC always gives this size 4 (without any warning).
// GCC always gives it size 8 (without any warning).
// Godbolt: https://godbolt.org/z/P49MaYvMd
enum overflowing_enum {
    OVERFLOWING_ENUM_A = 9223372036854775807,
};
```

If we look at the C standard, then up until C20, there was no official support enums without an explicit underlying type and with discriminants that do not fit an `int`. With C23, this has changed: now enums have to grow automatically if there is an integer type that can hold all their discriminants. MSVC does not implement this part of C23.

Furthermore, Rust fundamentally cannot implement this (without major changes)! Enum discriminants work fundamentally different in Rust and C:
- In Rust, every enum has a discriminant type entirely determined by its repr flags, and then the discriminant values must be const expressions of that type. For repr(C), that type is `isize`. So from the outset we interpret 9223372036854775807 as an isize literal and never give it a chance to be stored in a bigger type. If the discriminant is given as a literal without type annotation, it gets wrapped implicitly with a warning; otherwise the user has to write `as isize` explicitly and thus trigger the wrapping. Later, we can then decide to make the *tag* that stores the discriminant smaller than the discriminant type if all discriminant values fit into a smaller type, but those values have allready all been made to fit an `isize` so nothing bigger than `isize` could ever come out of this. That makes the behavior of 32bit GCC impossible for us to match.
-  In C, things flow the other way around: every discriminant value has a type determined entirely by its constant expression, and then the type for the enum is determined based on that. IOW, the expression can have *any type* a priori, different variants can even use a different type, and then the compiler is supposed to look at the resulting *values* (presumably as mathematical integers) and find a type that can hold them all. For the example above, 9223372036854775807 is a signed integer, so the compiler looks for the smallest signed type that can hold it, which is `long long`, and then uses that to compute the size of the enum (at least that's what C23 says should happen and GCC does this correctly).

Realistically I think the best we can do is to not attempt to support C23 enums, and to require repr(C) enums to satisfy the C20 requirements: all discriminants must fit into a c_int. So that's what this PR implements, by adding a FCW for enums with discriminants that do not fit into `c_int`. As a slight extension, we do *not* lint enums where all discriminants fit into a `c_uint` (i.e. `unsigned int`): while C20 does (in my reading) not allow this, and C23 does not prescribe the size of such an enum, this seems to behave consistently across compilers (giving the enum the size of an `unsigned int`). IOW, the lint fires whenever our layout algorithm would make the enum larger than an `int`, irrespective of whether we pick a signed or unsigned discriminant. This extension was added because [crater found](https://github.com/rust-lang/rust/pull/147017#issuecomment-3357077199) multiple cases of such enums across the ecosystem.

Note that it is impossible to trigger this FCW on targets where isize and c_int are the same size (i.e., the typical 32bit target): since we interpret discriminant values as isize, by the time we look at them, they have already been wrapped. However, we have an existing lint (overflowing_literals) that should notify people when this kind of wrapping occurs implicitly. Also, 64bit targets are much more common. On the other hand, even on 64bit targets it is possible to fall into the same trap by writing a literal that is so big that it does not fit into isize, gets wrapped (triggering overflowing_literals), and the wrapped value fits into c_int. Furthermore, overflowing_literals is just a lint, so if it occurs in a dependency you won't notice. (Arguably there is also a more general problem here: for literals of type `usize`/`isize`, it is fairly easy to write code that only triggers `overflowing_literals` on 32bit targets, and to never see that lint if one develops on a 64bit target.)

Specifically, the above example triggers the FCW on 64bit targets, but on 32bit targets we get this err-by-default lint instead (which will be hidden if it occurs in a dependency):
```
error: literal out of range for `isize`
  --> $DIR/repr-c-big-discriminant1.rs:16:9
   |
LL |     A = 9223372036854775807,
   |         ^^^^^^^^^^^^^^^^^^^
   |
   = note: the literal `9223372036854775807` does not fit into the type `isize` whose range is `-2147483648..=2147483647`
   = note: `#[deny(overflowing_literals)]` on by default
```
Also see the tests added by this PR.

This isn't perfect, but so far I don't think I have seen a better option. In https://github.com/rust-lang/rust/pull/146504 I tried adjusting our enum logic to make the size of the example enum above actually match what C compilers do, but that's a massive breaking change since we have to change the expected type of the discriminant expression from `isize` to `i64` or even `i128` -- so that seems like a no-go. To improve the lint we could analyze things on the HIR level and specifically catch "repr(C) enums with discriminants defined as literals that are too big", but that would have to be on top of the lint in this PR I think since we'd still want to also always check the actually evaluated value (which we can't always determined on the HIR level).

Cc `@workingjubilee` `@CAD97`
2025-11-04 23:01:10 +11:00
Ralf Jung 8b96fbecb6 FCW for repr(C) enums whose discriminant values do not fit into a c_int 2025-11-04 11:44:55 +01:00
Ralf Jung add37c0c25 extend some comments and clarify some names around enum tag type computation 2025-11-04 11:32:16 +01:00
Folkert de Vries 1866b3a8cf assert that #[rustc_pass_indirectly_in_non_rustic_abis] is respected 2025-11-04 09:56:21 +01:00
Tomasz Miąsko 2a03a948b9 Deduce captures(none) for a return place and parameters
Extend attribute deduction to determine whether parameters using
indirect pass mode might have their address captured. Similarly to
the deduction of `readonly` attribute this information facilitates
memcpy optimizations.
2025-10-25 22:53:52 +02:00
Oli Scherer ad4bd083f3 Add not-null pointer patterns to pattern types 2025-10-21 11:22:51 +00:00
Oli Scherer d9f22d289c Pattern types have their base type as a field 2025-10-21 10:37:07 +00:00
bors 0c0f27afd4 Auto merge of #147695 - cjgillot:deduce-param-freeze, r=tmiasko
deduced_param_attrs: check Freeze on monomorphic types.

`deduced_param_attrs` currently checks `Freeze` bound on polymorphic MIR. This pessimizes the deduction, as generic types are not `Freeze` by default.

This moves the check to the ABI adjustment.
2025-10-18 12:37:45 +00:00
Camille Gillot 97f88f5603 Generalize the non-freeze and needs_drop handling. 2025-10-17 16:28:37 +00:00
Cameron Steffen e60e9f0826 Split impl_(opt_)trait_ref 2025-10-17 08:36:34 -05:00
Cameron Steffen ca5073759c Remove some impl_trait_ref usages 2025-10-17 08:36:34 -05:00
Cameron Steffen c17b2dc283 Split trait_id_of_impl into impl(_opt)_trait_id 2025-10-17 08:36:34 -05:00
Camille Gillot 031929c369 deduced_param_attrs: check Freeze on monomorphic types. 2025-10-15 21:21:05 +00:00
Boxy Uwu 8e9b0c4ca9 rename select_where_possible and select_all_or_error 2025-10-07 23:02:23 +01:00
bors 4b9c62b4da Auto merge of #147138 - jackh726:split-canonical-bound, r=lcnr
Split Bound index into Canonical and Bound

See [#t-types/trait-system-refactor > perf `async-closures/post-mono-higher-ranked-hang.rs`](https://rust-lang.zulipchat.com/#narrow/channel/364551-t-types.2Ftrait-system-refactor/topic/perf.20.60async-closures.2Fpost-mono-higher-ranked-hang.2Ers.60/with/541535613) for context

Things compile and tests pass, but not sure if this actually solves the perf issue (edit: it does). Opening up this to do a perf (and maybe crater) run.

r? lcnr
2025-10-02 08:09:33 +00:00
jackh726 d1bbd39c59 Split Bound into Canonical and Bound 2025-09-30 12:58:28 -04:00
Jubilee Young 0c9d0dfe04 remove explicit deref of AbiAlign for most methods
Much of the compiler calls functions on Align projected from AbiAlign.
AbiAlign impls Deref to its inner Align, so we can simplify these away.
Also, it will minimize disruption when AbiAlign is removed.

For now, preserve usages that might resolve to PartialOrd or PartialEq,
as those have odd inference.
2025-09-28 15:02:14 -07:00
Stuart Cook fab06469ee Rollup merge of #146667 - calebzulawski:simd-mono-lane-limit, r=lcnr,RalfJung
Add an attribute to check the number of lanes in a SIMD vector after monomorphization

Allows std::simd to drop the `LaneCount<N>: SupportedLaneCount` trait and maintain good error messages.

Also, extends rust-lang/rust#145967 by including spans in layout errors for all ADTs.

r? ``@RalfJung``

cc ``@workingjubilee`` ``@programmerjake``
2025-09-25 20:31:53 +10:00
Caleb Zulawski f5c6c9542e Add an attribute to check the number of lanes in a SIMD vector after monomorphization
Unify zero-length and oversized SIMD errors
2025-09-23 20:47:34 -04:00
Matthias Krüger b7ab58eb4d Rollup merge of #146597 - modhanami:add-struct-tail-recursion-limit-span, r=oli-obk
Add span for struct tail recursion limit error

Fixes rust-lang/rust#135629

Changes
1. Add span to RecursionLimitReached
2. Add ObligationCause parameter to struct_tail_raw
4. Update call sites to pass nearby ObligationCause or create one
5. Update affected .stderr
2025-09-18 17:20:57 +02:00
León Orell Valerian Liehr 26f3337d4e Remove DynKind 2025-09-17 04:46:46 +02:00
Tawan Muadmuenwai 6912631d3e Add span for struct tail recursion limit error 2025-09-16 23:04:59 +07:00
Cameron Steffen b995a55caf Don't store defaultness for inherent impl items 2025-09-12 15:14:15 -05:00
Cameron Steffen 9615ec7d10 Split AssocContainer::{InherentImpl,TraitImpl} 2025-09-12 15:14:15 -05:00
Cameron Steffen 88a8bfcaf0 Introduce hir::ImplItemImplKind 2025-09-12 15:14:15 -05:00
Cameron Steffen 5590e55b03 Rename AssocItemContainer -> AssocContainer 2025-09-12 15:10:30 -05:00
Cameron Steffen 16c218c57f Introduce trait_item_of 2025-09-12 15:10:30 -05:00
bors 364da5d88d Auto merge of #145717 - BoxyUwU:erase_regions_rename, r=lcnr
rename erase_regions to erase_and_anonymize_regions

I find it consistently confusing that `erase_regions` does more than replacing regions with `'erased`. it also makes some code look real goofy to be writing manual folders to erase regions with a comment saying "we cant use erase regions" :> or code that re-calls erase_regions on types with regions already erased just to anonymize all the bound regions.

r? lcnr

idk how i feel about the name being almost twice as long now
2025-09-09 15:04:44 +00:00
Boxy e379c77586 erase_regions to erase_and_anonymize_regions 2025-09-09 14:49:16 +02:00
Jana Dönszelmann 6087d89004 fixup limit handling code 2025-09-08 15:07:12 -07:00
lcnr a3993c5416 change order of nested_bodies_within 2025-08-27 14:11:07 +02:00
Nikita Popov d71ed8d19b Tell LLVM about read-only captures
`&Freeze` parameters are not only `readonly` within the function,
but any captures of the pointer can also only be used for reads.
This can now be encoded using the `captures(address, read_provenance)`
attribute.
2025-08-20 19:08:16 +02:00
Cameron Steffen bf266dc834 Propagate TraitImplHeader to hir 2025-08-11 17:05:42 -05:00
Stuart Cook b30fe4bb8b Rollup merge of #145147 - fee1-dead-contrib:push-mxxpmlpmzmsz, r=compiler-errors
rename `TraitRef::from_method` to `from_assoc`

also add a note to `GenericArgs::truncate_to`
2025-08-10 19:45:53 +10:00
Deadbeef 2736d66a1f rename TraitRef::from_method to from_assoc
also add a note to `GenericArgs::truncate_to`
2025-08-09 14:22:01 +08:00
bjorn3 7d88f657e9 Fix ICE 2025-08-06 18:31:58 +00:00
bjorn3 e2acc6c5f4 Avoid using unadjusted ABI for the thread-local shim
This restricts the uses of the unadjusted ABI to LLVM intrinsics. The
Rust ABI works fine for the thread-local shim as it always returns
pointers directly like the backend expects.
2025-08-06 16:05:30 +00:00
bjorn3 b0619327ef Change adjust_for_rust_scalar into arg_attrs_for_rust_scalar
Directly creating the ArgAttributes rather than adjusting one is a bit
clearer.
2025-08-06 16:05:30 +00:00
Michael Goulet d05bb98d6b Extract borrowck coroutine drop-liveness hack 2025-07-31 17:38:28 +00:00
Cameron Steffen 172af038a7 Rename trait_of_item -> trait_of_assoc 2025-07-28 09:53:50 -05:00
bors d242a8bd5a Auto merge of #144469 - Kivooeo:chains-cleanup, r=SparrowLii
Some `let chains` clean-up

Not sure if this kind of clean-up is welcoming because of size, but I decided to try out one

r? compiler
2025-07-28 05:25:23 +00:00
Kivooeo b8eb046e6e use let chains in mir, resolve, target 2025-07-28 06:10:36 +05:00
Matthias Krüger d88aa06cd9 Rollup merge of #144448 - camsteffen:defaultness-impl-trait-only, r=compiler-errors
Limit defaultness query to impl of trait

I separated this out from https://github.com/rust-lang/rust/pull/144386.
2025-07-26 15:28:02 +02:00
Cameron Steffen cf4d7938cf Limit defaultness to impl of trait 2025-07-25 08:49:31 -05:00
Oli Scherer e44a7386c2 Remove dead code and extend test coverage and diagnostics around it
We lost the following comment during refactorings:

The current code for niche-filling relies on variant indices instead of actual discriminants, so enums with explicit discriminants (RFC 2363) would misbehave.
2025-07-24 10:21:20 +00:00
Matthias Krüger f78cc42032 Rollup merge of #143793 - fmease:lta-opaq-inf-recur, r=oli-obk
Opaque type collection: Guard against endlessly recursing free alias types

See test description for technical details.

Fixes https://github.com/rust-lang/rust/issues/131994.

r? oli-obk (sry, your queue is large, so no rush & feel free to reassign)
2025-07-17 10:41:45 +02:00
Camille GILLOT 21fd82adbc Retire hir::*ItemRef. 2025-07-13 13:50:01 +00:00
Camille GILLOT 277b0ecf34 Remove hir::AssocItemKind. 2025-07-13 13:50:00 +00:00
Camille GILLOT 3ecd03bdfd Move trait_item_def_id from ImplItemRef to ImplItem. 2025-07-13 13:50:00 +00:00