Skip to content

Commit eefa158

Browse files
Merge pull request #22237 from ChayimFriedman2/infcx-ty-lowering
fix: Provide an InferCtxt to TyLoweringContext
2 parents ecc571a + 9fc3180 commit eefa158

17 files changed

Lines changed: 413 additions & 263 deletions

File tree

crates/hir-ty/src/consteval.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,15 @@ use crate::{
2525
generics::Generics,
2626
mir::{MirEvalError, MirLowerError, pad16},
2727
next_solver::{
28-
Allocation, Const, ConstKind, Consts, DbInterner, DefaultAny, ErrorGuaranteed, GenericArg,
29-
GenericArgs, ParamConst, ScalarInt, StoredAllocation, StoredEarlyBinder, StoredGenericArgs,
30-
Ty, TyKind, UnevaluatedConst, ValTreeKind, default_types, infer::InferCtxt,
28+
Allocation, Const, ConstKind, Consts, DbInterner, DefaultAny, GenericArgs, ParamConst,
29+
ScalarInt, StoredAllocation, StoredEarlyBinder, StoredGenericArgs, Ty, TyKind,
30+
UnevaluatedConst, ValTreeKind, default_types, infer::InferCtxt,
3131
},
3232
traits::StoredParamEnvAndCrate,
3333
};
3434

3535
use super::mir::interpret_mir;
3636

37-
pub fn unknown_const<'db>(_ty: Ty<'db>) -> Const<'db> {
38-
Const::new(DbInterner::conjure(), rustc_type_ir::ConstKind::Error(ErrorGuaranteed))
39-
}
40-
41-
pub fn unknown_const_as_generic<'db>(ty: Ty<'db>) -> GenericArg<'db> {
42-
unknown_const(ty).into()
43-
}
44-
4537
#[derive(Debug, Clone, PartialEq, Eq)]
4638
pub enum ConstEvalError {
4739
MirLowerError(MirLowerError),

crates/hir-ty/src/generics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub(crate) fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics<'_>
3939
}
4040

4141
#[derive(Debug)]
42-
pub(crate) struct Generics<'db> {
42+
pub struct Generics<'db> {
4343
chain: ArrayVec<SingleGenerics<'db>, 2>,
4444
}
4545

crates/hir-ty/src/infer.rs

Lines changed: 76 additions & 78 deletions
Large diffs are not rendered by default.

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ use crate::{
2323
db::{InternedClosure, InternedClosureId, InternedCoroutineClosureId, InternedCoroutineId},
2424
infer::{BreakableKind, Diverges, coerce::CoerceMany, pat::PatOrigin},
2525
next_solver::{
26-
AliasTy, Binder, ClauseKind, DbInterner, ErrorGuaranteed, FnSig, GenericArg, GenericArgs,
27-
PolyFnSig, PolyProjectionPredicate, Predicate, PredicateKind, SolverDefId, TermId, Ty,
28-
TyKind, Unnormalized,
26+
AliasTy, Binder, ClauseKind, DbInterner, ErrorGuaranteed, FnSig, GenericArg, PolyFnSig,
27+
PolyProjectionPredicate, Predicate, PredicateKind, SolverDefId, TermId, Ty, TyKind,
28+
Unnormalized,
2929
abi::Safety,
3030
infer::{
3131
BoundRegionConversionTime, InferOk, InferResult,
@@ -99,7 +99,7 @@ impl<'db> InferenceContext<'_, 'db> {
9999

100100
debug!(?bound_sig, ?liberated_sig);
101101

102-
let parent_args = GenericArgs::identity_for_item(interner, self.store_owner.into());
102+
let parent_args = self.identity_args();
103103

104104
let tupled_upvars_ty = self.table.next_ty_var(closure_expr.into());
105105

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//! and a wrapper around [`TyLoweringContext`] ([`InferenceTyLoweringContext`]) that replaces
33
//! it and takes care of diagnostics in inference.
44
5-
use std::cell::RefCell;
5+
use std::cell::{OnceCell, RefCell};
66
use std::ops::{Deref, DerefMut};
77

88
use either::Either;
@@ -16,8 +16,9 @@ use thin_vec::ThinVec;
1616
use crate::{
1717
InferenceDiagnostic, InferenceTyDiagnosticSource, TyLoweringDiagnostic,
1818
db::{AnonConstId, HirDatabase},
19+
generics::Generics,
1920
lower::{
20-
ForbidParamsAfterReason, LifetimeElisionKind, TyLoweringContext,
21+
ForbidParamsAfterReason, LifetimeElisionKind, TyLoweringContext, TyLoweringInferVarsCtx,
2122
path::{PathDiagnosticCallback, PathLoweringContext},
2223
},
2324
};
@@ -71,12 +72,22 @@ impl<'db, 'a> InferenceTyLoweringContext<'db, 'a> {
7172
source: InferenceTyDiagnosticSource,
7273
def: ExpressionStoreOwnerId,
7374
generic_def: GenericDefId,
75+
generics: &'a OnceCell<Generics<'db>>,
7476
lifetime_elision: LifetimeElisionKind<'db>,
7577
allow_using_generic_params: bool,
78+
infer_vars: Option<TyLoweringInferVarsCtx<'a, 'db>>,
7679
defined_anon_consts: &'a RefCell<ThinVec<AnonConstId>>,
7780
) -> Self {
78-
let mut ctx =
79-
TyLoweringContext::new(db, resolver, store, def, generic_def, lifetime_elision);
81+
let mut ctx = TyLoweringContext::new(
82+
db,
83+
resolver,
84+
store,
85+
def,
86+
generic_def,
87+
generics,
88+
lifetime_elision,
89+
)
90+
.with_infer_vars_behavior(infer_vars);
8091
if !allow_using_generic_params {
8192
ctx.forbid_params_after(0, ForbidParamsAfterReason::AnonConst);
8293
}

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

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use stdx::never;
1313
use crate::{
1414
InferenceDiagnostic, Span, ValueTyDefId,
1515
infer::diagnostics::InferenceTyLoweringContext as TyLoweringContext,
16-
lower::{GenericPredicates, LifetimeElisionKind},
16+
lower::{GenericPredicates, LifetimeElisionKind, TyLoweringInferVarsCtx},
1717
method_resolution::{self, CandidateId, MethodError},
1818
next_solver::{
1919
GenericArg, GenericArgs, TraitRef, Ty, Unnormalized, infer::traits::ObligationCause,
@@ -38,7 +38,7 @@ impl<'db> InferenceContext<'_, 'db> {
3838
}
3939
ValuePathResolution::NonGeneric(ty) => return Some((value, ty)),
4040
};
41-
let args = self.insert_type_vars(substs, id.into());
41+
let args = self.insert_type_vars(substs);
4242

4343
self.add_required_obligations_for_value_path(id, generic_def, args);
4444

@@ -117,7 +117,7 @@ impl<'db> InferenceContext<'_, 'db> {
117117
if let Some(last_segment) = last_segment {
118118
path_ctx.set_current_segment(last_segment)
119119
}
120-
path_ctx.substs_from_path(value_def, true, false)
120+
path_ctx.substs_from_path(value_def, true, false, id.into())
121121
})
122122
};
123123

@@ -147,8 +147,13 @@ impl<'db> InferenceContext<'_, 'db> {
147147
InferenceTyDiagnosticSource::Body,
148148
self.store_owner,
149149
self.generic_def,
150+
&self.generics,
150151
LifetimeElisionKind::Infer,
151152
self.allow_using_generic_params,
153+
Some(TyLoweringInferVarsCtx {
154+
table: &mut self.table,
155+
type_of_placeholder: &mut self.result.type_of_type_placeholder,
156+
}),
152157
&self.defined_anon_consts,
153158
);
154159
let mut path_ctx = if no_diagnostics {
@@ -160,12 +165,12 @@ impl<'db> InferenceContext<'_, 'db> {
160165
let last = path.segments().last()?;
161166

162167
let (ty, orig_ns) = path_ctx.ty_ctx().lower_ty_ext(type_ref);
163-
let ty = self.table.process_user_written_ty(type_ref.into(), ty);
168+
let ty = path_ctx.expect_table().process_user_written_ty(ty);
164169

165170
path_ctx.ignore_last_segment();
166-
let (ty, _) = path_ctx.lower_ty_relative_path(ty, orig_ns, true);
171+
let (ty, _) = path_ctx.lower_ty_relative_path(ty, orig_ns, true, id.into());
167172
drop_ctx(ctx, no_diagnostics);
168-
let ty = self.table.process_user_written_ty(id.into(), ty);
173+
let ty = self.table.process_user_written_ty(ty);
169174
self.resolve_ty_assoc_item(ty, last.name, id).map(|(it, substs)| (it, Some(substs)))?
170175
} else {
171176
let hygiene = self.store.expr_or_pat_path_hygiene(id);
@@ -190,9 +195,13 @@ impl<'db> InferenceContext<'_, 'db> {
190195

191196
let (resolution, substs) = match (def, is_before_last) {
192197
(TypeNs::TraitId(trait_), true) => {
193-
let self_ty = self.table.next_ty_var(id.into());
194-
let trait_ref =
195-
path_ctx.lower_trait_ref_from_resolved_path(trait_, self_ty, true);
198+
let self_ty = path_ctx.expect_table().next_ty_var(id.into());
199+
let trait_ref = path_ctx.lower_trait_ref_from_resolved_path(
200+
trait_,
201+
self_ty,
202+
true,
203+
id.into(),
204+
);
196205
drop_ctx(ctx, no_diagnostics);
197206
self.resolve_trait_assoc_item(trait_ref, last_segment, id)
198207
}
@@ -202,13 +211,13 @@ impl<'db> InferenceContext<'_, 'db> {
202211
// should resolve to an associated type of that trait (e.g. `<T
203212
// as Iterator>::Item::default`)
204213
path_ctx.ignore_last_segment();
205-
let (ty, _) = path_ctx.lower_partly_resolved_path(def, true);
214+
let (ty, _) = path_ctx.lower_partly_resolved_path(def, true, id.into());
206215
drop_ctx(ctx, no_diagnostics);
207216
if ty.is_ty_error() {
208217
return None;
209218
}
210219

211-
let ty = self.process_user_written_ty(id.into(), ty);
220+
let ty = self.process_user_written_ty(ty);
212221

213222
self.resolve_ty_assoc_item(ty, last_segment.name, id)
214223
}

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

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -442,23 +442,22 @@ impl<'db> InferenceTable<'db> {
442442
}
443443
}
444444

445-
pub(super) fn insert_type_vars<T>(&mut self, ty: T, span: Span) -> T
445+
pub(super) fn insert_type_vars<T>(&mut self, ty: T) -> T
446446
where
447447
T: TypeFoldable<DbInterner<'db>>,
448448
{
449-
self.infer_ctxt.insert_type_vars(ty, span)
449+
self.infer_ctxt.insert_type_vars(ty)
450450
}
451451

452452
/// Whenever you lower a user-written type, you should call this.
453-
pub(crate) fn process_user_written_ty(&mut self, span: Span, ty: Ty<'db>) -> Ty<'db> {
454-
let ty = self.insert_type_vars(ty, span);
455-
self.try_structurally_resolve_type(span, ty)
453+
pub(crate) fn process_user_written_ty(&mut self, ty: Ty<'db>) -> Ty<'db> {
454+
self.process_remote_user_written_ty(ty)
456455
}
457456

458457
/// The difference of this method from `process_user_written_ty()` is that this method doesn't register a well-formed obligation,
459458
/// while `process_user_written_ty()` should (but doesn't currently).
460459
pub(crate) fn process_remote_user_written_ty(&mut self, ty: Ty<'db>) -> Ty<'db> {
461-
let ty = self.insert_type_vars(ty, Span::Dummy);
460+
let ty = self.insert_type_vars(ty);
462461
// See https://github.com/rust-lang/rust/blob/cdb45c87e2cd43495379f7e867e3cc15dcee9f93/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs#L487-L495:
463462
// Even though the new solver only lazily normalizes usually, here we eagerly normalize so that not everything needs
464463
// to normalize before inspecting the `TyKind`.

crates/hir-ty/src/lib.rs

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -502,35 +502,6 @@ where
502502
Vec::from_iter(collector.params)
503503
}
504504

505-
struct TypeInferenceVarCollector<'db> {
506-
type_inference_vars: Vec<Ty<'db>>,
507-
}
508-
509-
impl<'db> rustc_type_ir::TypeVisitor<DbInterner<'db>> for TypeInferenceVarCollector<'db> {
510-
type Result = ();
511-
512-
fn visit_ty(&mut self, ty: Ty<'db>) -> Self::Result {
513-
use crate::rustc_type_ir::Flags;
514-
if ty.is_ty_var() {
515-
self.type_inference_vars.push(ty);
516-
} else if ty.flags().intersects(rustc_type_ir::TypeFlags::HAS_TY_INFER) {
517-
ty.super_visit_with(self);
518-
} else {
519-
// Fast path: don't visit inner types (e.g. generic arguments) when `flags` indicate
520-
// that there are no placeholders.
521-
}
522-
}
523-
}
524-
525-
pub fn collect_type_inference_vars<'db, T>(value: &T) -> Vec<Ty<'db>>
526-
where
527-
T: ?Sized + rustc_type_ir::TypeVisitable<DbInterner<'db>>,
528-
{
529-
let mut collector = TypeInferenceVarCollector { type_inference_vars: vec![] };
530-
value.visit_with(&mut collector);
531-
collector.type_inference_vars
532-
}
533-
534505
pub fn known_const_to_ast<'db>(
535506
konst: Const<'db>,
536507
db: &'db dyn HirDatabase,

0 commit comments

Comments
 (0)