Replace early-bound normalization hack with per-query key/value type aliases.

This commit is contained in:
Eduard-Mihai Burtescu 2020-07-05 22:58:46 +03:00
parent 0cd7ff7ddf
commit f25811e34b
2 changed files with 24 additions and 8 deletions

View File

@ -17,7 +17,6 @@ use rustc_middle::middle::cstore::{CrateSource, CrateStore, EncodedMetadata};
use rustc_middle::middle::exported_symbols::ExportedSymbol;
use rustc_middle::middle::stability::DeprecationEntry;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::query::QueryConfig;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::utils::NativeLibKind;
use rustc_session::{CrateDisambiguator, Session};
@ -32,12 +31,10 @@ macro_rules! provide {
(<$lt:tt> $tcx:ident, $def_id:ident, $other:ident, $cdata:ident,
$($name:ident => $compute:block)*) => {
pub fn provide_extern<$lt>(providers: &mut Providers<$lt>) {
// HACK(eddyb) `$lt: $lt` forces `$lt` to be early-bound, which
// allows the associated type in the return type to be normalized.
$(fn $name<$lt: $lt, T: IntoArgs>(
$(fn $name<$lt>(
$tcx: TyCtxt<$lt>,
def_id_arg: T,
) -> <ty::queries::$name<$lt> as QueryConfig<TyCtxt<$lt>>>::Value {
def_id_arg: ty::query::query_keys::$name<$lt>,
) -> ty::query::query_values::$name<$lt> {
let _prof_timer =
$tcx.prof.generic_activity("metadata_decode_entry");

View File

@ -318,15 +318,34 @@ macro_rules! define_queries_inner {
}
}
#[allow(nonstandard_style)]
pub mod queries {
use std::marker::PhantomData;
$(#[allow(nonstandard_style)]
pub struct $name<$tcx> {
$(pub struct $name<$tcx> {
data: PhantomData<&$tcx ()>
})*
}
// HACK(eddyb) this is like the `impl QueryConfig for queries::$name`
// below, but using type aliases instead of associated types, to bypass
// the limitations around normalizing under HRTB - for example, this:
// `for<'tcx> fn(...) -> <queries::$name<'tcx> as QueryConfig<TyCtxt<'tcx>>>::Value`
// doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`.
// This is primarily used by the `provide!` macro in `rustc_metadata`.
#[allow(nonstandard_style, unused_lifetimes)]
pub mod query_keys {
use super::*;
$(pub type $name<$tcx> = $($K)*;)*
}
#[allow(nonstandard_style, unused_lifetimes)]
pub mod query_values {
use super::*;
$(pub type $name<$tcx> = $V;)*
}
$(impl<$tcx> QueryConfig<TyCtxt<$tcx>> for queries::$name<$tcx> {
type Key = $($K)*;
type Value = $V;