Repository: rust-lang/rust
File: compiler/rustc_query_impl/src/plumbing.rs (Rust)

Code before:
                        None
                    }),
                    is_loadable_from_disk_fn: if_cache_on_disk!([$($modifiers)*] {
                        Some(|tcx, key, index| -> bool {
                            ::rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) &&
                                $crate::plumbing::loadable_from_disk(tcx, index)
                        })
                    } {
                        None
                    }),
                    value_from_cycle_error: |tcx, cycle, guar| {
                        let result: queries::$name::Value<'tcx> = Value::from_cycle_error(tcx, cycle, guar);
                        erase::erase_val(result)
                    },
                    hash_result: hash_result!([$($modifiers)*][queries::$name::Value<'tcx>]),
                    format_value: |value| format!("{:?}", erase::restore_val::<queries::$name::Value<'tcx>>(*value)),
                    description_fn: $crate::queries::_description_fns::$name,
                }
            }

            #[derive(Copy, Clone, Default)]
            pub(crate) struct QueryType<'tcx> {
                data: PhantomData<&'tcx ()>
            }

            pub(crate) const IS_EVAL_ALWAYS: bool = is_eval_always!([$($modifiers)*]);

            const FLAGS: QueryFlags = QueryFlags {
                is_anon: is_anon!([$($modifiers)*]),
                is_depth_limit: depth_limit!([$($modifiers)*]),
                is_feedable: feedable!([$($modifiers)*]),
            };

            impl<'tcx> QueryDispatcherUnerased<'tcx, queries::$name::Storage<'tcx>, FLAGS>
                for QueryType<'tcx>
            {
                type UnerasedValue = queries::$name::Value<'tcx>;

                const NAME: &'static &'static str = &stringify!($name);

                #[inline(always)]
                fn query_dispatcher(tcx: TyCtxt<'tcx>)
                    -> SemiDynamicQueryDispatcher<'tcx, queries::$name::Storage<'tcx>, FLAGS>
                {
                    SemiDynamicQueryDispatcher {
                        vtable: &tcx.query_system.query_vtables.$name,
                    }
                }

                #[inline(always)]
                fn restore_val(value: <queries::$name::Storage<'tcx> as QueryCache>::Value)

Review comment (suggestion):
In https://github.com/rust-lang/rust/pull/152435 I experimented with making this a field in `QueryFlags` instead.

The perf results were inconclusive, so for this PR I decided not to bundle that change.

Code after:
                                return None;
                            }

                            let value: queries::$name::ProvidedValue<'tcx> =
                                $crate::plumbing::try_load_from_disk(tcx, prev_index, index)?;

                            // Arena-alloc the value if appropriate, and erase it.
                            Some(queries::$name::provided_to_erased(tcx, value))
                        })
                    } {
                        None
                    }),
                    is_loadable_from_disk_fn: if_cache_on_disk!([$($modifiers)*] {
                        Some(|tcx, key, index| -> bool {
                            ::rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) &&
                                $crate::plumbing::loadable_from_disk(tcx, index)
                        })
                    } {
                        None
                    }),
                    value_from_cycle_error: |tcx, cycle, guar| {
                        let result: queries::$name::Value<'tcx> = Value::from_cycle_error(tcx, cycle, guar);
                        erase::erase_val(result)
                    },
                    hash_result: hash_result!([$($modifiers)*][queries::$name::Value<'tcx>]),
                    format_value: |value| format!("{:?}", erase::restore_val::<queries::$name::Value<'tcx>>(*value)),
                    description_fn: $crate::queries::_description_fns::$name,
                }
            }

            #[derive(Copy, Clone, Default)]
            pub(crate) struct QueryType<'tcx> {
                data: PhantomData<&'tcx ()>
            }

            const FLAGS: QueryFlags = QueryFlags {
                is_anon: is_anon!([$($modifiers)*]),
                is_depth_limit: depth_limit!([$($modifiers)*]),
                is_feedable: feedable!([$($modifiers)*]),
            };

            impl<'tcx> QueryDispatcherUnerased<'tcx, queries::$name::Storage<'tcx>, FLAGS>
                for QueryType<'tcx>
            {
                type UnerasedValue = queries::$name::Value<'tcx>;

                const NAME: &'static &'static str = &stringify!($name);

                #[inline(always)]
                fn query_dispatcher(tcx: TyCtxt<'tcx>)
                    -> SemiDynamicQueryDispatcher<'tcx, queries::$name::Storage<'tcx>, FLAGS>