rust/compiler/rustc_data_structures/src
bors df8ac8f1d7 Auto merge of #122568 - RalfJung:mentioned-items, r=oli-obk
recursively evaluate the constants in everything that is 'mentioned'

This is another attempt at fixing https://github.com/rust-lang/rust/issues/107503. The previous attempt at https://github.com/rust-lang/rust/pull/112879 seems stuck in figuring out where the [perf regression](https://perf.rust-lang.org/compare.html?start=c55d1ee8d4e3162187214692229a63c2cc5e0f31&end=ec8de1ebe0d698b109beeaaac83e60f4ef8bb7d1&stat=instructions:u) comes from. In  https://github.com/rust-lang/rust/pull/122258 I learned some things, which informed the approach this PR is taking.

Quoting from the new collector docs, which explain the high-level idea:
```rust
//! One important role of collection is to evaluate all constants that are used by all the items
//! which are being collected. Codegen can then rely on only encountering constants that evaluate
//! successfully, and if a constant fails to evaluate, the collector has much better context to be
//! able to show where this constant comes up.
//!
//! However, the exact set of "used" items (collected as described above), and therefore the exact
//! set of used constants, can depend on optimizations. Optimizing away dead code may optimize away
//! a function call that uses a failing constant, so an unoptimized build may fail where an
//! optimized build succeeds. This is undesirable.
//!
//! To fix this, the collector has the concept of "mentioned" items. Some time during the MIR
//! pipeline, before any optimization-level-dependent optimizations, we compute a list of all items
//! that syntactically appear in the code. These are considered "mentioned", and even if they are in
//! dead code and get optimized away (which makes them no longer "used"), they are still
//! "mentioned". For every used item, the collector ensures that all mentioned items, recursively,
//! do not use a failing constant. This is reflected via the [`CollectionMode`], which determines
//! whether we are visiting a used item or merely a mentioned item.
//!
//! The collector and "mentioned items" gathering (which lives in `rustc_mir_transform::mentioned_items`)
//! need to stay in sync in the following sense:
//!
//! - For every item that the collector gather that could eventually lead to build failure (most
//!   likely due to containing a constant that fails to evaluate), a corresponding mentioned item
//!   must be added. This should use the exact same strategy as the ecollector to make sure they are
//!   in sync. However, while the collector works on monomorphized types, mentioned items are
//!   collected on generic MIR -- so any time the collector checks for a particular type (such as
//!   `ty::FnDef`), we have to just onconditionally add this as a mentioned item.
//! - In `visit_mentioned_item`, we then do with that mentioned item exactly what the collector
//!   would have done during regular MIR visiting. Basically you can think of the collector having
//!   two stages, a pre-monomorphization stage and a post-monomorphization stage (usually quite
//!   literally separated by a call to `self.monomorphize`); the pre-monomorphizationn stage is
//!   duplicated in mentioned items gathering and the post-monomorphization stage is duplicated in
//!   `visit_mentioned_item`.
//! - Finally, as a performance optimization, the collector should fill `used_mentioned_item` during
//!   its MIR traversal with exactly what mentioned item gathering would have added in the same
//!   situation. This detects mentioned items that have *not* been optimized away and hence don't
//!   need a dedicated traversal.

enum CollectionMode {
    /// Collect items that are used, i.e., actually needed for codegen.
    ///
    /// Which items are used can depend on optimization levels, as MIR optimizations can remove
    /// uses.
    UsedItems,
    /// Collect items that are mentioned. The goal of this mode is that it is independent of
    /// optimizations: the set of "mentioned" items is computed before optimizations are run.
    ///
    /// The exact contents of this set are *not* a stable guarantee. (For instance, it is currently
    /// computed after drop-elaboration. If we ever do some optimizations even in debug builds, we
    /// might decide to run them before computing mentioned items.) The key property of this set is
    /// that it is optimization-independent.
    MentionedItems,
}
```
And the `mentioned_items` MIR body field docs:
```rust
    /// Further items that were mentioned in this function and hence *may* become monomorphized,
    /// depending on optimizations. We use this to avoid optimization-dependent compile errors: the
    /// collector recursively traverses all "mentioned" items and evaluates all their
    /// `required_consts`.
    ///
    /// This is *not* soundness-critical and the contents of this list are *not* a stable guarantee.
    /// All that's relevant is that this set is optimization-level-independent, and that it includes
    /// everything that the collector would consider "used". (For example, we currently compute this
    /// set after drop elaboration, so some drop calls that can never be reached are not considered
    /// "mentioned".) See the documentation of `CollectionMode` in
    /// `compiler/rustc_monomorphize/src/collector.rs` for more context.
    pub mentioned_items: Vec<Spanned<MentionedItem<'tcx>>>,
```

Fixes #107503
2024-03-21 09:01:18 +00:00
..
base_n Adapt rustc_data_structures tests to run in strict miri 2022-06-04 17:46:29 +02:00
binary_search_util Remove invariant comments 2023-11-05 17:35:37 -06:00
fingerprint remove redundant imports 2023-12-10 10:56:22 +08:00
flock windows bump to 0.52 2024-02-18 16:02:16 +03:00
graph Inline dominator check. 2023-12-31 00:37:45 +00:00
intern remove redundant imports 2023-12-10 10:56:22 +08:00
obligation_forest remove redundant imports 2023-12-10 10:56:22 +08:00
owned_slice Don't leak the function that is called on drop 2023-05-23 14:53:36 +00:00
profiling Don't use serde_json to serialize a simple JSON object 2023-04-16 15:00:06 +02:00
sip128 remove redundant imports 2023-12-10 10:56:22 +08:00
small_c_str Fix SmallCStr conversion from CStr 2024-02-14 18:40:53 -08:00
snapshot_map Call the method fork instead of clone and add proper comments 2022-02-14 12:57:20 -03:00
sorted_map Split {Idx, IndexVec, IndexSlice} into their own modules 2023-04-24 13:53:35 +00:00
sso rustc_data_structures: use either instead of itertools 2024-01-24 15:36:57 -08:00
stable_hasher Store hashes in special types so they aren't accidentally encoded as numbers 2023-04-18 10:52:47 -04:00
sync Workaround for rustdoc bug in new beta 2024-03-20 08:49:13 -04:00
tagged_ptr Replace NonZero::<_>::new with NonZero::new. 2024-02-15 08:09:42 +01:00
tiny_list rustc_data_structures: remove ref patterns and other artifacts of the past 2023-01-17 07:48:19 +00:00
transitive_relation get rid of RefCell in TransitiveRelation 2022-08-22 18:08:46 +08:00
aligned.rs fix broken intradoclinks 2023-04-14 13:04:58 +00:00
atomic_ref.rs mv compiler to compiler/ 2020-08-30 18:45:07 +03:00
base_n.rs [rustc_data_structures][base_n][perf] Remove unnecessary utf8 check. 2023-08-01 11:10:17 -07:00
captures.rs Remove #[allow(unused_lifetimes)] which is now unnecessary 2021-06-17 08:56:54 +09:00
fingerprint.rs Use the full Fingerprint when stringifying Svh 2023-04-30 14:28:30 -04:00
flat_map_in_place.rs Rename MapInPlace as FlatMapInPlace. 2023-03-08 15:53:56 +11:00
flock.rs Initiate the inner usage of cfg_match 2023-10-19 20:18:51 -03:00
frozen.rs Remove double spaces after dots in comments 2023-01-17 08:09:33 +00:00
fx.rs rustc_mir_transform: Make DestinationPropagation stable for queries 2024-01-05 20:55:32 +01:00
hashes.rs Use UnhashMap for a few more maps 2024-01-17 17:09:55 -05:00
intern.rs Don't print Interned or PrivateZst 2023-06-09 00:20:37 +00:00
jobserver.rs Update jobserver-rs to 0.1.28 2024-02-09 19:13:07 +03:00
lib.rs Use generic NonZero internally. 2024-02-15 08:09:42 +01:00
macros.rs Introduce ChunkedBitSet and use it for some dataflow analyses. 2022-02-23 10:18:49 +11:00
marker.rs Remove OneThread 2024-01-18 03:30:05 +01:00
memmap.rs Issue 122262: MAP_PRIVATE for more reliability on virtualised filesystems. 2024-03-15 18:31:07 -04:00
owned_slice.rs By tracking import use types to check whether it is scope uses or the other situations like module-relative uses, we can do more accurate redundant import checking. 2024-02-18 16:38:11 +08:00
packed.rs Add Pu128 = #[repr(packed(8))] u128 2024-01-19 20:10:38 -08:00
profiling.rs windows bump to 0.52 2024-02-18 16:02:16 +03:00
sharded.rs rustc_data_structures: use either instead of itertools 2024-01-24 15:36:57 -08:00
sip128.rs deny(unsafe_op_in_unsafe_fn) in rustc_data_structures 2023-04-19 18:00:48 +00:00
small_c_str.rs Fix SmallCStr conversion from CStr 2024-02-14 18:40:53 -08:00
sorted_map.rs Avoid specialization for the Span Encodable and Decodable impls 2023-12-31 20:42:17 +00:00
stable_hasher.rs Use generic NonZero internally. 2024-02-15 08:09:42 +01:00
stack.rs Fix some clippy::complexity 2023-04-09 23:22:14 +02:00
steal.rs Harden the pre-tyctxt query system against accidental recomputation 2023-01-12 09:26:28 +00:00
svh.rs Avoid specialization for the Span Encodable and Decodable impls 2023-12-31 20:42:17 +00:00
sync.rs collector: recursively traverse 'mentioned' items to evaluate their constants 2024-03-20 11:07:12 +01:00
tagged_ptr.rs Simplify bits_for_tags impl 2023-04-20 19:54:10 +00:00
temp_dir.rs Update dependencies with reported vulnerabilities 2023-06-02 12:34:01 -05:00
tiny_list.rs rustc_data_structures: remove ref patterns and other artifacts of the past 2023-01-17 07:48:19 +00:00
transitive_relation.rs Remove double spaces after dots in comments 2023-01-17 08:09:33 +00:00
unhash.rs Avoid rehashing Fingerprint as a map key 2020-09-01 18:27:02 -07:00
unord.rs clean up potential_query_instability with FxIndexMap and UnordMap 2024-02-14 18:36:37 +08:00
vec_linked_list.rs Split {Idx, IndexVec, IndexSlice} into their own modules 2023-04-24 13:53:35 +00:00
work_queue.rs Split {Idx, IndexVec, IndexSlice} into their own modules 2023-04-24 13:53:35 +00:00