Skip to content

Commit 8b2671e

Browse files
authored
Merge pull request #20647 from ChayimFriedman2/ns-projections
fix: Fix normalization in the new solver
2 parents 07b68bd + 287a6e9 commit 8b2671e

File tree

16 files changed

+266
-199
lines changed

16 files changed

+266
-199
lines changed

crates/hir-ty/src/infer.rs

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ use rustc_hash::{FxHashMap, FxHashSet};
5454
use stdx::{always, never};
5555
use triomphe::Arc;
5656

57+
use crate::next_solver::DbInterner;
58+
use crate::next_solver::mapping::NextSolverToChalk;
5759
use crate::{
5860
AliasEq, AliasTy, Binders, ClosureId, Const, DomainGoal, GenericArg, ImplTraitId, ImplTraitIdx,
5961
IncorrectGenericsLenKind, Interner, Lifetime, OpaqueTyId, ParamLoweringMode,
@@ -922,13 +924,15 @@ impl<'db> InferenceContext<'db> {
922924
});
923925
diagnostics.shrink_to_fit();
924926
for (_, subst) in method_resolutions.values_mut() {
925-
*subst = table.resolve_completely(subst.clone());
927+
*subst =
928+
table.resolve_completely::<_, crate::next_solver::GenericArgs<'db>>(subst.clone());
926929
*has_errors =
927930
*has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
928931
}
929932
method_resolutions.shrink_to_fit();
930933
for (_, subst) in assoc_resolutions.values_mut() {
931-
*subst = table.resolve_completely(subst.clone());
934+
*subst =
935+
table.resolve_completely::<_, crate::next_solver::GenericArgs<'db>>(subst.clone());
932936
*has_errors =
933937
*has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
934938
}
@@ -946,7 +950,12 @@ impl<'db> InferenceContext<'db> {
946950
result.tuple_field_access_types = tuple_field_accesses_rev
947951
.into_iter()
948952
.enumerate()
949-
.map(|(idx, subst)| (TupleId(idx as u32), table.resolve_completely(subst)))
953+
.map(|(idx, subst)| {
954+
(
955+
TupleId(idx as u32),
956+
table.resolve_completely::<_, crate::next_solver::GenericArgs<'db>>(subst),
957+
)
958+
})
950959
.inspect(|(_, subst)| {
951960
*has_errors =
952961
*has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
@@ -1015,14 +1024,12 @@ impl<'db> InferenceContext<'db> {
10151024
if let Some(self_param) = self.body.self_param
10161025
&& let Some(ty) = param_tys.next()
10171026
{
1018-
let ty = self.insert_type_vars(ty);
1019-
let ty = self.normalize_associated_types_in(ty);
1027+
let ty = self.process_user_written_ty(ty);
10201028
self.write_binding_ty(self_param, ty);
10211029
}
10221030
let mut tait_candidates = FxHashSet::default();
10231031
for (ty, pat) in param_tys.zip(&*self.body.params) {
1024-
let ty = self.insert_type_vars(ty);
1025-
let ty = self.normalize_associated_types_in(ty);
1032+
let ty = self.process_user_written_ty(ty);
10261033

10271034
self.infer_top_pat(*pat, &ty, None);
10281035
if ty
@@ -1073,7 +1080,7 @@ impl<'db> InferenceContext<'db> {
10731080
None => self.result.standard_types.unit.clone(),
10741081
};
10751082

1076-
self.return_ty = self.normalize_associated_types_in(return_ty);
1083+
self.return_ty = self.process_user_written_ty(return_ty);
10771084
self.return_coercion = Some(CoerceMany::new(self.return_ty.clone()));
10781085

10791086
// Functions might be defining usage sites of TAITs.
@@ -1415,8 +1422,7 @@ impl<'db> InferenceContext<'db> {
14151422
) -> Ty {
14161423
let ty = self
14171424
.with_ty_lowering(store, type_source, lifetime_elision, |ctx| ctx.lower_ty(type_ref));
1418-
let ty = self.insert_type_vars(ty);
1419-
self.normalize_associated_types_in(ty)
1425+
self.process_user_written_ty(ty)
14201426
}
14211427

14221428
fn make_body_ty(&mut self, type_ref: TypeRefId) -> Ty {
@@ -1562,15 +1568,35 @@ impl<'db> InferenceContext<'db> {
15621568
ty
15631569
}
15641570

1571+
/// Whenever you lower a user-written type, you should call this.
1572+
fn process_user_written_ty<T, U>(&mut self, ty: T) -> T
1573+
where
1574+
T: HasInterner<Interner = Interner> + TypeFoldable<Interner> + ChalkToNextSolver<'db, U>,
1575+
U: NextSolverToChalk<'db, T> + rustc_type_ir::TypeFoldable<DbInterner<'db>>,
1576+
{
1577+
self.table.process_user_written_ty(ty)
1578+
}
1579+
1580+
/// The difference of this method from `process_user_written_ty()` is that this method doesn't register a well-formed obligation,
1581+
/// while `process_user_written_ty()` should (but doesn't currently).
1582+
fn process_remote_user_written_ty<T, U>(&mut self, ty: T) -> T
1583+
where
1584+
T: HasInterner<Interner = Interner> + TypeFoldable<Interner> + ChalkToNextSolver<'db, U>,
1585+
U: NextSolverToChalk<'db, T> + rustc_type_ir::TypeFoldable<DbInterner<'db>>,
1586+
{
1587+
self.table.process_remote_user_written_ty(ty)
1588+
}
1589+
15651590
/// Recurses through the given type, normalizing associated types mentioned
15661591
/// in it by replacing them by type variables and registering obligations to
15671592
/// resolve later. This should be done once for every type we get from some
15681593
/// type annotation (e.g. from a let type annotation, field type or function
15691594
/// call). `make_ty` handles this already, but e.g. for field types we need
15701595
/// to do it as well.
1571-
fn normalize_associated_types_in<T>(&mut self, ty: T) -> T
1596+
fn normalize_associated_types_in<T, U>(&mut self, ty: T) -> T
15721597
where
1573-
T: HasInterner<Interner = Interner> + TypeFoldable<Interner>,
1598+
T: HasInterner<Interner = Interner> + TypeFoldable<Interner> + ChalkToNextSolver<'db, U>,
1599+
U: NextSolverToChalk<'db, T> + rustc_type_ir::TypeFoldable<DbInterner<'db>>,
15741600
{
15751601
self.table.normalize_associated_types_in(ty)
15761602
}

crates/hir-ty/src/infer/closure.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub(super) struct ClosureSignature {
5353
pub(super) expected_sig: FnPointer,
5454
}
5555

56-
impl InferenceContext<'_> {
56+
impl<'db> InferenceContext<'db> {
5757
pub(super) fn infer_closure(
5858
&mut self,
5959
body: &ExprId,
@@ -71,9 +71,13 @@ impl InferenceContext<'_> {
7171
None => (None, None),
7272
};
7373

74-
let ClosureSignature { expected_sig: bound_sig, ret_ty: body_ret_ty } =
74+
let ClosureSignature { expected_sig: mut bound_sig, ret_ty: body_ret_ty } =
7575
self.sig_of_closure(body, ret_type, arg_types, closure_kind, expected_sig);
76-
let bound_sig = self.normalize_associated_types_in(bound_sig);
76+
bound_sig.substitution.0 = self
77+
.normalize_associated_types_in::<_, crate::next_solver::GenericArgs<'db>>(
78+
bound_sig.substitution.0,
79+
);
80+
let bound_sig = bound_sig;
7781
let sig_ty = TyKind::Function(bound_sig.clone()).intern(Interner);
7882

7983
let (id, ty, resume_yield_tys) = match closure_kind {

crates/hir-ty/src/infer/expr.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,7 +1419,7 @@ impl InferenceContext<'_> {
14191419
None => self.err_ty(),
14201420
};
14211421

1422-
let ret_ty = self.normalize_associated_types_in(ret_ty);
1422+
let ret_ty = self.process_remote_user_written_ty(ret_ty);
14231423

14241424
if self.is_builtin_binop(&lhs_ty, &rhs_ty, op) {
14251425
// use knowledge of built-in binary ops, which can sometimes help inference
@@ -1630,8 +1630,7 @@ impl InferenceContext<'_> {
16301630
Some(match res {
16311631
Some((field_id, ty)) => {
16321632
let adjustments = auto_deref_adjust_steps(&autoderef);
1633-
let ty = self.insert_type_vars(ty);
1634-
let ty = self.normalize_associated_types_in(ty);
1633+
let ty = self.process_remote_user_written_ty(ty);
16351634

16361635
(ty, field_id, adjustments, true)
16371636
}
@@ -1641,8 +1640,7 @@ impl InferenceContext<'_> {
16411640
let ty = self.db.field_types(field_id.parent)[field_id.local_id]
16421641
.clone()
16431642
.substitute(Interner, &subst);
1644-
let ty = self.insert_type_vars(ty);
1645-
let ty = self.normalize_associated_types_in(ty);
1643+
let ty = self.process_remote_user_written_ty(ty);
16461644

16471645
(ty, Either::Left(field_id), adjustments, false)
16481646
}

crates/hir-ty/src/infer/pat.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ impl InferenceContext<'_> {
8888
Some(substs) => f.substitute(Interner, substs),
8989
None => f.substitute(Interner, &Substitution::empty(Interner)),
9090
};
91-
self.normalize_associated_types_in(expected_ty)
91+
self.process_remote_user_written_ty(expected_ty)
9292
}
9393
None => self.err_ty(),
9494
}
@@ -152,7 +152,7 @@ impl InferenceContext<'_> {
152152
Some(substs) => f.substitute(Interner, substs),
153153
None => f.substitute(Interner, &Substitution::empty(Interner)),
154154
};
155-
self.normalize_associated_types_in(expected_ty)
155+
self.process_remote_user_written_ty(expected_ty)
156156
}
157157
None => {
158158
self.push_diagnostic(InferenceDiagnostic::NoSuchField {

crates/hir-ty/src/infer/path.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,21 @@ use crate::{
2323

2424
use super::{ExprOrPatId, InferenceContext, InferenceTyDiagnosticSource};
2525

26-
impl InferenceContext<'_> {
26+
impl<'db> InferenceContext<'db> {
2727
pub(super) fn infer_path(&mut self, path: &Path, id: ExprOrPatId) -> Option<Ty> {
2828
let (value_def, generic_def, substs) = match self.resolve_value_path(path, id)? {
2929
ValuePathResolution::GenericDef(value_def, generic_def, substs) => {
3030
(value_def, generic_def, substs)
3131
}
3232
ValuePathResolution::NonGeneric(ty) => return Some(ty),
3333
};
34-
let substs = self.insert_type_vars(substs);
35-
let substs = self.normalize_associated_types_in(substs);
34+
let substs =
35+
self.process_remote_user_written_ty::<_, crate::next_solver::GenericArgs<'db>>(substs);
3636

3737
self.add_required_obligations_for_value_path(generic_def, &substs);
3838

3939
let ty = self.db.value_ty(value_def)?.substitute(Interner, &substs);
40-
let ty = self.normalize_associated_types_in(ty);
40+
let ty = self.process_remote_user_written_ty(ty);
4141
Some(ty)
4242
}
4343

@@ -173,14 +173,12 @@ impl InferenceContext<'_> {
173173
let last = path.segments().last()?;
174174

175175
let (ty, orig_ns) = path_ctx.ty_ctx().lower_ty_ext(type_ref);
176-
let ty = self.table.insert_type_vars(ty);
177-
let ty = self.table.normalize_associated_types_in(ty);
176+
let ty = self.table.process_user_written_ty(ty);
178177

179178
path_ctx.ignore_last_segment();
180179
let (ty, _) = path_ctx.lower_ty_relative_path(ty, orig_ns, true);
181180
drop_ctx(ctx, no_diagnostics);
182-
let ty = self.table.insert_type_vars(ty);
183-
let ty = self.table.normalize_associated_types_in(ty);
181+
let ty = self.table.process_user_written_ty(ty);
184182
self.resolve_ty_assoc_item(ty, last.name, id).map(|(it, substs)| (it, Some(substs)))?
185183
} else {
186184
let hygiene = self.body.expr_or_pat_path_hygiene(id);
@@ -223,8 +221,7 @@ impl InferenceContext<'_> {
223221
return None;
224222
}
225223

226-
let ty = self.insert_type_vars(ty);
227-
let ty = self.normalize_associated_types_in(ty);
224+
let ty = self.process_user_written_ty(ty);
228225

229226
self.resolve_ty_assoc_item(ty, last_segment.name, id)
230227
}

0 commit comments

Comments
 (0)