Skip to content

Commit ac7f9ec

Browse files
committed
Auto merge of #151746 - jdonszelmann:eagerly-normalize-in-generalize, r=lcnr
Eagerly normalize in generalize *[View all comments](https://triagebot.infra.rust-lang.org/gh-comments/rust-lang/rust/pull/151746)* r? @lcnr cc: rust-lang/trait-system-refactor-initiative#262
2 parents bfc05d6 + d665c0b commit ac7f9ec

24 files changed

Lines changed: 454 additions & 130 deletions

File tree

compiler/rustc_borrowck/src/type_check/relate_tys.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,4 +616,9 @@ impl<'b, 'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for NllTypeRelating<'_
616616
}
617617
})]);
618618
}
619+
620+
fn try_eagerly_normalize_alias(&mut self, _alias: ty::AliasTy<'tcx>) -> Ty<'tcx> {
621+
// Past hir typeck, so we don't have to worry about type inference anymore.
622+
self.type_checker.infcx.next_ty_var(self.span())
623+
}
619624
}

compiler/rustc_infer/src/infer/at.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ impl<'a, 'tcx> At<'a, 'tcx> {
140140
ty::Contravariant,
141141
actual,
142142
self.cause.span,
143+
&mut |alias| {
144+
self.infcx.try_eagerly_normalize_alias(self.param_env, self.cause.span, alias)
145+
},
143146
)
144147
.map(|goals| self.goals_to_obligations(goals))
145148
} else {
@@ -173,6 +176,9 @@ impl<'a, 'tcx> At<'a, 'tcx> {
173176
ty::Covariant,
174177
actual,
175178
self.cause.span,
179+
&mut |alias| {
180+
self.infcx.try_eagerly_normalize_alias(self.param_env, self.cause.span, alias)
181+
},
176182
)
177183
.map(|goals| self.goals_to_obligations(goals))
178184
} else {
@@ -225,6 +231,9 @@ impl<'a, 'tcx> At<'a, 'tcx> {
225231
ty::Invariant,
226232
actual,
227233
self.cause.span,
234+
&mut |alias| {
235+
self.infcx.try_eagerly_normalize_alias(self.param_env, self.cause.span, alias)
236+
},
228237
)
229238
.map(|goals| self.goals_to_obligations(goals))
230239
} else {

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::cell::{Cell, RefCell};
2-
use std::fmt;
2+
use std::{fmt, mem};
33

44
pub use at::DefineOpaqueTypes;
55
use free_regions::RegionRelations;
@@ -21,6 +21,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
2121
use rustc_macros::extension;
2222
pub use rustc_macros::{TypeFoldable, TypeVisitable};
2323
use rustc_middle::bug;
24+
use rustc_middle::hooks::TypeErasedInfcx;
2425
use rustc_middle::infer::canonical::{CanonicalQueryInput, CanonicalVarValues};
2526
use rustc_middle::mir::ConstraintCategory;
2627
use rustc_middle::traits::select;
@@ -1528,6 +1529,17 @@ impl<'tcx> InferCtxt<'tcx> {
15281529
}
15291530
}
15301531

1532+
pub fn try_eagerly_normalize_alias<'a>(
1533+
&'a self,
1534+
param_env: ty::ParamEnv<'tcx>,
1535+
span: Span,
1536+
alias: ty::AliasTy<'tcx>,
1537+
) -> Ty<'tcx> {
1538+
let erased =
1539+
unsafe { mem::transmute::<&'a InferCtxt<'tcx>, TypeErasedInfcx<'a, 'tcx>>(self) };
1540+
self.tcx.try_eagerly_normalize_alias(erased, param_env, span, alias)
1541+
}
1542+
15311543
/// Attach a callback to be invoked on each root obligation evaluated in the new trait solver.
15321544
pub fn attach_obligation_inspector(&self, inspector: ObligationInspector<'tcx>) {
15331545
debug_assert!(

compiler/rustc_infer/src/infer/relate/generalize.rs

Lines changed: 187 additions & 63 deletions
Large diffs are not rendered by default.

compiler/rustc_infer/src/infer/relate/lattice.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,4 +299,8 @@ impl<'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for LatticeOp<'_, 'tcx> {
299299
ty::AliasRelationDirection::Equate,
300300
))]);
301301
}
302+
303+
fn try_eagerly_normalize_alias(&mut self, alias: ty::AliasTy<'tcx>) -> Ty<'tcx> {
304+
self.infcx.try_eagerly_normalize_alias(self.param_env(), self.span(), alias)
305+
}
302306
}

compiler/rustc_infer/src/infer/relate/type_relating.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,4 +396,13 @@ impl<'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for TypeRelating<'_, 'tcx>
396396
}
397397
})]);
398398
}
399+
400+
fn try_eagerly_normalize_alias(
401+
&mut self,
402+
_alias: rustc_type_ir::AliasTy<<InferCtxt<'tcx> as rustc_type_ir::InferCtxtLike>::Interner>,
403+
) -> <<InferCtxt<'tcx> as rustc_type_ir::InferCtxtLike>::Interner as rustc_type_ir::Interner>::Ty
404+
{
405+
// We only try to eagerly normalize aliases if we're using the new solver.
406+
unreachable!()
407+
}
399408
}

compiler/rustc_interface/src/passes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,7 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
904904
rustc_hir_typeck::provide(&mut providers.queries);
905905
ty::provide(&mut providers.queries);
906906
traits::provide(&mut providers.queries);
907-
solve::provide(&mut providers.queries);
907+
solve::provide(providers);
908908
rustc_passes::provide(&mut providers.queries);
909909
rustc_traits::provide(&mut providers.queries);
910910
rustc_ty_utils::provide(&mut providers.queries);

compiler/rustc_middle/src/hooks/mod.rs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
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+
68
use rustc_hir::def_id::{DefId, DefPathHash};
79
use rustc_session::StableCrateId;
810
use rustc_span::def_id::{CrateNum, LocalDefId};
9-
use rustc_span::{ExpnHash, ExpnId};
11+
use rustc_span::{ExpnHash, ExpnId, Span};
1012

11-
use crate::mir;
1213
use crate::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex};
1314
use crate::ty::{Ty, TyCtxt};
15+
use crate::{mir, ty};
1416

1517
macro_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
}

compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,11 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
177177
cache: Default::default(),
178178
};
179179
let param_env = param_env.fold_with(&mut env_canonicalizer);
180-
debug_assert!(env_canonicalizer.sub_root_lookup_table.is_empty());
180+
debug_assert!(
181+
env_canonicalizer.sub_root_lookup_table.is_empty(),
182+
"{:?}",
183+
env_canonicalizer.sub_root_lookup_table
184+
);
181185
(
182186
param_env,
183187
env_canonicalizer.variables,

compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -987,7 +987,12 @@ where
987987
let replacement = self.ecx.instantiate_binder_with_infer(*replacement);
988988
self.nested.extend(
989989
self.ecx
990-
.eq_and_get_goals(self.param_env, alias_term, replacement.projection_term)
990+
.relate_and_get_goals(
991+
self.param_env,
992+
alias_term,
993+
ty::Invariant,
994+
replacement.projection_term,
995+
)
991996
.expect("expected to be able to unify goal projection with dyn's projection"),
992997
);
993998

0 commit comments

Comments
 (0)