Skip to content

Commit 3f6d9e2

Browse files
Merge pull request #20765 from ChayimFriedman2/infer-ns-types
internal: Migrate inference to next solver
2 parents 472037b + d1288f6 commit 3f6d9e2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+4558
-4902
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/hir-def/src/expr_store/path.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ pub struct AssociatedTypeBinding {
8888
}
8989

9090
/// A single generic argument.
91-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
91+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9292
pub enum GenericArg {
9393
Type(TypeRefId),
9494
Lifetime(LifetimeRefId),

crates/hir-ty/src/autoderef.rs

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@
55
66
use std::fmt;
77

8+
use hir_def::TraitId;
89
use hir_def::{TypeAliasId, lang_item::LangItem};
910
use rustc_type_ir::inherent::{IntoKind, Ty as _};
1011
use tracing::debug;
1112
use triomphe::Arc;
1213

14+
use crate::next_solver::TraitRef;
1315
use crate::next_solver::infer::InferOk;
16+
use crate::next_solver::infer::traits::Obligation;
1417
use crate::{
1518
TraitEnvironment,
1619
db::HirDatabase,
@@ -38,14 +41,14 @@ pub fn autoderef<'db>(
3841
ty: crate::Canonical<crate::Ty>,
3942
) -> impl Iterator<Item = crate::Ty> + use<> {
4043
let mut table = InferenceTable::new(db, env);
41-
let interner = table.interner;
42-
let ty = table.instantiate_canonical(ty);
43-
let mut autoderef = Autoderef::new_no_tracking(&mut table, ty.to_nextsolver(interner));
44+
let interner = table.interner();
45+
let ty = table.instantiate_canonical(ty.to_nextsolver(interner));
46+
let mut autoderef = Autoderef::new_no_tracking(&mut table, ty);
4447
let mut v = Vec::new();
4548
while let Some((ty, _steps)) = autoderef.next() {
4649
// `ty` may contain unresolved inference variables. Since there's no chance they would be
4750
// resolved, just replace with fallback type.
48-
let resolved = autoderef.table.resolve_completely(ty.to_chalk(interner));
51+
let resolved = autoderef.table.resolve_completely(ty).to_chalk(interner);
4952

5053
// If the deref chain contains a cycle (e.g. `A` derefs to `B` and `B` derefs to `A`), we
5154
// would revisit some already visited types. Stop here to avoid duplication.
@@ -101,6 +104,7 @@ struct AutoderefSnapshot<'db, Steps> {
101104

102105
#[derive(Clone, Copy)]
103106
struct AutoderefTraits {
107+
trait_: TraitId,
104108
trait_target: TypeAliasId,
105109
}
106110

@@ -215,16 +219,26 @@ impl<'a, 'db, Steps: TrackAutoderefSteps<'db>> Autoderef<'a, 'db, Steps> {
215219
Some(it) => Some(*it),
216220
None => {
217221
let traits = if self.use_receiver_trait {
218-
AutoderefTraits {
219-
trait_target: LangItem::ReceiverTarget
220-
.resolve_type_alias(self.table.db, self.table.trait_env.krate)
221-
.or_else(|| {
222-
LangItem::DerefTarget
223-
.resolve_type_alias(self.table.db, self.table.trait_env.krate)
224-
})?,
225-
}
222+
(|| {
223+
Some(AutoderefTraits {
224+
trait_: LangItem::Receiver
225+
.resolve_trait(self.table.db, self.table.trait_env.krate)?,
226+
trait_target: LangItem::ReceiverTarget
227+
.resolve_type_alias(self.table.db, self.table.trait_env.krate)?,
228+
})
229+
})()
230+
.or_else(|| {
231+
Some(AutoderefTraits {
232+
trait_: LangItem::Deref
233+
.resolve_trait(self.table.db, self.table.trait_env.krate)?,
234+
trait_target: LangItem::DerefTarget
235+
.resolve_type_alias(self.table.db, self.table.trait_env.krate)?,
236+
})
237+
})?
226238
} else {
227239
AutoderefTraits {
240+
trait_: LangItem::Deref
241+
.resolve_trait(self.table.db, self.table.trait_env.krate)?,
228242
trait_target: LangItem::DerefTarget
229243
.resolve_type_alias(self.table.db, self.table.trait_env.krate)?,
230244
}
@@ -236,10 +250,22 @@ impl<'a, 'db, Steps: TrackAutoderefSteps<'db>> Autoderef<'a, 'db, Steps> {
236250

237251
fn overloaded_deref_ty(&mut self, ty: Ty<'db>) -> Option<Ty<'db>> {
238252
debug!("overloaded_deref_ty({:?})", ty);
239-
let interner = self.table.interner;
253+
let interner = self.table.interner();
240254

241255
// <ty as Deref>, or whatever the equivalent trait is that we've been asked to walk.
242-
let AutoderefTraits { trait_target } = self.autoderef_traits()?;
256+
let AutoderefTraits { trait_, trait_target } = self.autoderef_traits()?;
257+
258+
let trait_ref = TraitRef::new(interner, trait_.into(), [ty]);
259+
let obligation =
260+
Obligation::new(interner, ObligationCause::new(), self.table.trait_env.env, trait_ref);
261+
// We detect whether the self type implements `Deref` before trying to
262+
// structurally normalize. We use `predicate_may_hold_opaque_types_jank`
263+
// to support not-yet-defined opaque types. It will succeed for `impl Deref`
264+
// but fail for `impl OtherTrait`.
265+
if !self.table.infer_ctxt.predicate_may_hold_opaque_types_jank(&obligation) {
266+
debug!("overloaded_deref_ty: cannot match obligation");
267+
return None;
268+
}
243269

244270
let (normalized_ty, obligations) = structurally_normalize_ty(
245271
self.table,
@@ -316,7 +342,7 @@ pub(crate) fn overloaded_deref_ty<'db>(
316342
table: &InferenceTable<'db>,
317343
ty: Ty<'db>,
318344
) -> Option<InferOk<'db, Ty<'db>>> {
319-
let interner = table.interner;
345+
let interner = table.interner();
320346

321347
let trait_target = LangItem::DerefTarget.resolve_type_alias(table.db, table.trait_env.krate)?;
322348

crates/hir-ty/src/builder.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ use crate::{
1515
error_lifetime,
1616
generics::generics,
1717
infer::unify::InferenceTable,
18-
next_solver::{DbInterner, EarlyBinder, mapping::ChalkToNextSolver},
18+
next_solver::{
19+
DbInterner, EarlyBinder,
20+
mapping::{ChalkToNextSolver, NextSolverToChalk},
21+
},
1922
primitive, to_assoc_type_id, to_chalk_trait_id,
2023
};
2124

@@ -141,10 +144,13 @@ impl<D> TyBuilder<D> {
141144

142145
#[tracing::instrument(skip_all)]
143146
pub(crate) fn fill_with_inference_vars(self, table: &mut InferenceTable<'_>) -> Self {
144-
self.fill(|x| match x {
145-
ParamKind::Type => table.new_type_var().cast(Interner),
146-
ParamKind::Const(ty) => table.new_const_var(ty.clone()).cast(Interner),
147-
ParamKind::Lifetime => table.new_lifetime_var().cast(Interner),
147+
self.fill(|x| {
148+
match x {
149+
ParamKind::Type => crate::next_solver::GenericArg::Ty(table.next_ty_var()),
150+
ParamKind::Const(_) => table.next_const_var().into(),
151+
ParamKind::Lifetime => table.next_region_var().into(),
152+
}
153+
.to_chalk(table.interner())
148154
})
149155
}
150156

crates/hir-ty/src/chalk_db.rs

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//! about the code that Chalk needs.
33
use hir_def::{CallableDefId, GenericDefId};
44

5-
use crate::{Interner, Substitution, db::HirDatabase, mapping::from_chalk};
5+
use crate::{Interner, db::HirDatabase, mapping::from_chalk};
66

77
pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
88
pub(crate) type TraitId = chalk_ir::TraitId<Interner>;
@@ -53,16 +53,3 @@ pub(crate) fn adt_variance_query(db: &dyn HirDatabase, adt_id: hir_def::AdtId) -
5353
}),
5454
)
5555
}
56-
57-
/// Returns instantiated predicates.
58-
pub(super) fn convert_where_clauses(
59-
db: &dyn HirDatabase,
60-
def: GenericDefId,
61-
substs: &Substitution,
62-
) -> Vec<chalk_ir::QuantifiedWhereClause<Interner>> {
63-
db.generic_predicates(def)
64-
.iter()
65-
.cloned()
66-
.map(|pred| pred.substitute(Interner, substs))
67-
.collect()
68-
}

crates/hir-ty/src/consteval.rs

Lines changed: 31 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use base_db::Crate;
44
use chalk_ir::{BoundVar, DebruijnIndex, cast::Cast};
55
use hir_def::{
66
EnumVariantId, GeneralConstId, HasModule as _, StaticId,
7-
expr_store::{Body, HygieneId, path::Path},
8-
hir::{Expr, ExprId},
7+
expr_store::{HygieneId, path::Path},
8+
hir::Expr,
99
resolver::{Resolver, ValueNs},
1010
type_ref::LiteralConstRef,
1111
};
@@ -19,13 +19,12 @@ use crate::{
1919
db::HirDatabase,
2020
display::DisplayTarget,
2121
generics::Generics,
22-
infer::InferenceContext,
2322
lower::ParamLoweringMode,
2423
next_solver::{DbInterner, mapping::ChalkToNextSolver},
2524
to_placeholder_idx,
2625
};
2726

28-
use super::mir::{MirEvalError, MirLowerError, interpret_mir, lower_to_mir, pad16};
27+
use super::mir::{MirEvalError, MirLowerError, interpret_mir, pad16};
2928

3029
/// Extension trait for [`Const`]
3130
pub trait ConstExt {
@@ -56,12 +55,12 @@ impl ConstExt for Const {
5655
}
5756

5857
#[derive(Debug, Clone, PartialEq, Eq)]
59-
pub enum ConstEvalError {
60-
MirLowerError(MirLowerError),
61-
MirEvalError(MirEvalError),
58+
pub enum ConstEvalError<'db> {
59+
MirLowerError(MirLowerError<'db>),
60+
MirEvalError(MirEvalError<'db>),
6261
}
6362

64-
impl ConstEvalError {
63+
impl ConstEvalError<'_> {
6564
pub fn pretty_print(
6665
&self,
6766
f: &mut String,
@@ -80,17 +79,17 @@ impl ConstEvalError {
8079
}
8180
}
8281

83-
impl From<MirLowerError> for ConstEvalError {
84-
fn from(value: MirLowerError) -> Self {
82+
impl<'db> From<MirLowerError<'db>> for ConstEvalError<'db> {
83+
fn from(value: MirLowerError<'db>) -> Self {
8584
match value {
8685
MirLowerError::ConstEvalError(_, e) => *e,
8786
_ => ConstEvalError::MirLowerError(value),
8887
}
8988
}
9089
}
9190

92-
impl From<MirEvalError> for ConstEvalError {
93-
fn from(value: MirEvalError) -> Self {
91+
impl<'db> From<MirEvalError<'db>> for ConstEvalError<'db> {
92+
fn from(value: MirEvalError<'db>) -> Self {
9493
ConstEvalError::MirEvalError(value)
9594
}
9695
}
@@ -225,35 +224,35 @@ pub fn try_const_isize(db: &dyn HirDatabase, c: &Const) -> Option<i128> {
225224
}
226225
}
227226

228-
pub(crate) fn const_eval_cycle_result(
229-
_: &dyn HirDatabase,
227+
pub(crate) fn const_eval_cycle_result<'db>(
228+
_: &'db dyn HirDatabase,
230229
_: GeneralConstId,
231230
_: Substitution,
232-
_: Option<Arc<TraitEnvironment<'_>>>,
233-
) -> Result<Const, ConstEvalError> {
231+
_: Option<Arc<TraitEnvironment<'db>>>,
232+
) -> Result<Const, ConstEvalError<'db>> {
234233
Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
235234
}
236235

237-
pub(crate) fn const_eval_static_cycle_result(
238-
_: &dyn HirDatabase,
236+
pub(crate) fn const_eval_static_cycle_result<'db>(
237+
_: &'db dyn HirDatabase,
239238
_: StaticId,
240-
) -> Result<Const, ConstEvalError> {
239+
) -> Result<Const, ConstEvalError<'db>> {
241240
Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
242241
}
243242

244-
pub(crate) fn const_eval_discriminant_cycle_result(
245-
_: &dyn HirDatabase,
243+
pub(crate) fn const_eval_discriminant_cycle_result<'db>(
244+
_: &'db dyn HirDatabase,
246245
_: EnumVariantId,
247-
) -> Result<i128, ConstEvalError> {
246+
) -> Result<i128, ConstEvalError<'db>> {
248247
Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
249248
}
250249

251-
pub(crate) fn const_eval_query(
252-
db: &dyn HirDatabase,
250+
pub(crate) fn const_eval_query<'db>(
251+
db: &'db dyn HirDatabase,
253252
def: GeneralConstId,
254253
subst: Substitution,
255-
trait_env: Option<Arc<TraitEnvironment<'_>>>,
256-
) -> Result<Const, ConstEvalError> {
254+
trait_env: Option<Arc<TraitEnvironment<'db>>>,
255+
) -> Result<Const, ConstEvalError<'db>> {
257256
let body = match def {
258257
GeneralConstId::ConstId(c) => {
259258
db.monomorphized_mir_body(c.into(), subst, db.trait_environment(c.into()))?
@@ -267,10 +266,10 @@ pub(crate) fn const_eval_query(
267266
Ok(c)
268267
}
269268

270-
pub(crate) fn const_eval_static_query(
271-
db: &dyn HirDatabase,
269+
pub(crate) fn const_eval_static_query<'db>(
270+
db: &'db dyn HirDatabase,
272271
def: StaticId,
273-
) -> Result<Const, ConstEvalError> {
272+
) -> Result<Const, ConstEvalError<'db>> {
274273
let body = db.monomorphized_mir_body(
275274
def.into(),
276275
Substitution::empty(Interner),
@@ -280,10 +279,10 @@ pub(crate) fn const_eval_static_query(
280279
Ok(c)
281280
}
282281

283-
pub(crate) fn const_eval_discriminant_variant(
284-
db: &dyn HirDatabase,
282+
pub(crate) fn const_eval_discriminant_variant<'db>(
283+
db: &'db dyn HirDatabase,
285284
variant_id: EnumVariantId,
286-
) -> Result<i128, ConstEvalError> {
285+
) -> Result<i128, ConstEvalError<'db>> {
287286
let def = variant_id.into();
288287
let body = db.body(def);
289288
let loc = variant_id.lookup(db);
@@ -317,44 +316,5 @@ pub(crate) fn const_eval_discriminant_variant(
317316
Ok(c)
318317
}
319318

320-
// FIXME: Ideally constants in const eval should have separate body (issue #7434), and this function should
321-
// get an `InferenceResult` instead of an `InferenceContext`. And we should remove `ctx.clone().resolve_all()` here
322-
// and make this function private. See the fixme comment on `InferenceContext::resolve_all`.
323-
pub(crate) fn eval_to_const(
324-
expr: ExprId,
325-
mode: ParamLoweringMode,
326-
ctx: &mut InferenceContext<'_>,
327-
debruijn: DebruijnIndex,
328-
) -> Const {
329-
let db = ctx.db;
330-
let infer = ctx.fixme_resolve_all_clone();
331-
fn has_closure(body: &Body, expr: ExprId) -> bool {
332-
if matches!(body[expr], Expr::Closure { .. }) {
333-
return true;
334-
}
335-
let mut r = false;
336-
body.walk_child_exprs(expr, |idx| r |= has_closure(body, idx));
337-
r
338-
}
339-
if has_closure(ctx.body, expr) {
340-
// Type checking clousres need an isolated body (See the above FIXME). Bail out early to prevent panic.
341-
return unknown_const(infer[expr].clone());
342-
}
343-
if let Expr::Path(p) = &ctx.body[expr] {
344-
let resolver = &ctx.resolver;
345-
if let Some(c) =
346-
path_to_const(db, resolver, p, mode, || ctx.generics(), debruijn, infer[expr].clone())
347-
{
348-
return c;
349-
}
350-
}
351-
if let Ok(mir_body) = lower_to_mir(ctx.db, ctx.owner, ctx.body, &infer, expr)
352-
&& let Ok((Ok(result), _)) = interpret_mir(db, Arc::new(mir_body), true, None)
353-
{
354-
return result;
355-
}
356-
unknown_const(infer[expr].clone())
357-
}
358-
359319
#[cfg(test)]
360320
mod tests;

0 commit comments

Comments
 (0)