33//! similar to queries, but queries come with a lot of machinery for caching and incremental
44//! compilation, whereas hooks are just plain function pointers without any of the query magic.
55
6+ use std:: marker:: PhantomData ;
7+
68use rustc_hir:: def_id:: { DefId , DefPathHash } ;
79use rustc_session:: StableCrateId ;
810use rustc_span:: def_id:: { CrateNum , LocalDefId } ;
9- use rustc_span:: { ExpnHash , ExpnId } ;
11+ use rustc_span:: { ExpnHash , ExpnId , Span } ;
1012
11- use crate :: mir;
1213use crate :: query:: on_disk_cache:: { CacheEncoder , EncodedDepNodeIndex } ;
1314use crate :: ty:: { Ty , TyCtxt } ;
15+ use crate :: { mir, ty} ;
1416
1517macro_rules! declare_hooks {
1618 ( $( $( #[ $attr: meta] ) * hook $name: ident( $( $arg: ident: $K: ty) ,* ) -> $V: ty; ) * ) => {
@@ -35,8 +37,10 @@ macro_rules! declare_hooks {
3537
3638 impl Default for Providers {
3739 fn default ( ) -> Self {
40+ #[ allow( unused) ]
3841 Providers {
39- $( $name: |_, $( $arg, ) * | default_hook( stringify!( $name) , & ( $( $arg, ) * ) ) ) ,*
42+ $( $name:
43+ |_, $( $arg, ) * | default_hook( stringify!( $name) ) ) ,*
4044 }
4145 }
4246 }
@@ -113,11 +117,32 @@ declare_hooks! {
113117 encoder: & mut CacheEncoder <' _, ' tcx>,
114118 query_result_index: & mut EncodedDepNodeIndex
115119 ) -> ( ) ;
120+
121+ /// Tries to normalize an alias, ignoring any errors.
122+ ///
123+ /// Generalization with the new trait solver calls into this,
124+ /// when generalizing outside of the trait solver in `hir_typeck`.
125+ hook try_eagerly_normalize_alias(
126+ type_erased_infcx: TypeErasedInfcx <' _, ' tcx>,
127+ param_env: ty:: ParamEnv <' tcx>,
128+ span: Span ,
129+ alias: ty:: AliasTy <' tcx>
130+ ) -> Ty <' tcx>;
131+ }
132+
133+ /// The `try_eagerly_normalize_alias` hook passes an `Infcx` from where it's called (in `rustc_infer`)
134+ /// to where it's provided (in `rustc_trait_selection`).
135+ /// Both of those crates have that type available, but `rustc_middle` does not.
136+ /// Instead we pass this type-erased `Infcx` and transmute on both sides.
137+ ///
138+ /// Has to be `repr(transparent)` so we can transmute a `&'a Infcx<'tcx>` to this struct.
139+ #[ repr( transparent) ]
140+ pub struct TypeErasedInfcx < ' a , ' tcx > {
141+ _infcx : * const ( ) ,
142+ phantom : PhantomData < & ' a mut & ' tcx ( ) > ,
116143}
117144
118145#[ cold]
119- fn default_hook ( name : & str , args : & dyn std:: fmt:: Debug ) -> ! {
120- bug ! (
121- "`tcx.{name}{args:?}` cannot be called as `{name}` was never assigned to a provider function"
122- )
146+ fn default_hook ( name : & str ) -> ! {
147+ bug ! ( "`tcx.{name}` cannot be called as `{name}` was never assigned to a provider function" )
123148}
0 commit comments