Skip to content

Commit

Permalink
Auto merge of rust-lang#14913 - HKalbasi:fix14844, r=HKalbasi
Browse files Browse the repository at this point in the history
Evaluate `UnevalutedConst` before trait solving

cc rust-lang#14844
  • Loading branch information
bors committed May 26, 2023
2 parents 7c81fff + cd4bffd commit 1b5523a
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 14 deletions.
14 changes: 7 additions & 7 deletions crates/hir-ty/src/infer/unify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ use triomphe::Arc;

use super::{InferOk, InferResult, InferenceContext, TypeError};
use crate::{
db::HirDatabase, fold_tys_and_consts, static_lifetime, to_chalk_trait_id, traits::FnTrait,
AliasEq, AliasTy, BoundVar, Canonical, Const, ConstValue, DebruijnIndex, GenericArg,
GenericArgData, Goal, Guidance, InEnvironment, InferenceVar, Interner, Lifetime, ParamKind,
ProjectionTy, ProjectionTyExt, Scalar, Solution, Substitution, TraitEnvironment, Ty, TyBuilder,
TyExt, TyKind, VariableKind,
consteval::unknown_const, db::HirDatabase, fold_tys_and_consts, static_lifetime,
to_chalk_trait_id, traits::FnTrait, AliasEq, AliasTy, BoundVar, Canonical, Const, ConstValue,
DebruijnIndex, GenericArg, GenericArgData, Goal, Guidance, InEnvironment, InferenceVar,
Interner, Lifetime, ParamKind, ProjectionTy, ProjectionTyExt, Scalar, Solution, Substitution,
TraitEnvironment, Ty, TyBuilder, TyExt, TyKind, VariableKind,
};

impl<'a> InferenceContext<'a> {
Expand Down Expand Up @@ -256,10 +256,10 @@ impl<'a> InferenceTable<'a> {
{
eval
} else {
c
unknown_const(c.data(Interner).ty.clone())
}
} else {
c
unknown_const(c.data(Interner).ty.clone())
}
}
_ => c,
Expand Down
23 changes: 23 additions & 0 deletions crates/hir-ty/src/tests/regression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1912,3 +1912,26 @@ fn main() {
"#,
);
}

#[test]
fn regression_14844_2() {
check_no_mismatches(
r#"
//- minicore: fn
pub const ONE: usize = 1;
pub type MyInner = Inner<ONE>;
pub struct Inner<const P: usize>();
impl Inner<1> {
fn map<F>(&self, func: F) -> bool
where
F: Fn(&MyInner) -> bool,
{
func(self)
}
}
"#,
);
}
14 changes: 10 additions & 4 deletions crates/hir-ty/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use std::env::var;

use chalk_ir::GoalData;
use chalk_ir::{fold::TypeFoldable, DebruijnIndex, GoalData};
use chalk_recursive::Cache;
use chalk_solve::{logging_db::LoggingRustIrDatabase, rust_ir, Solver};

Expand All @@ -16,9 +16,9 @@ use stdx::panic_context;
use triomphe::Arc;

use crate::{
db::HirDatabase, infer::unify::InferenceTable, AliasEq, AliasTy, Canonical, DomainGoal, Goal,
Guidance, InEnvironment, Interner, ProjectionTy, ProjectionTyExt, Solution, TraitRefExt, Ty,
TyKind, WhereClause,
db::HirDatabase, infer::unify::InferenceTable, utils::UnevaluatedConstEvaluatorFolder, AliasEq,
AliasTy, Canonical, DomainGoal, Goal, Guidance, InEnvironment, Interner, ProjectionTy,
ProjectionTyExt, Solution, TraitRefExt, Ty, TyKind, WhereClause,
};

/// This controls how much 'time' we give the Chalk solver before giving up.
Expand Down Expand Up @@ -106,6 +106,12 @@ pub(crate) fn trait_solve_query(
}
}

// Chalk see `UnevaluatedConst` as a unique concrete value, but we see it as an alias for another const. So
// we should get rid of it when talking to chalk.
let goal = goal
.try_fold_with(&mut UnevaluatedConstEvaluatorFolder { db }, DebruijnIndex::INNERMOST)
.unwrap();

// We currently don't deal with universes (I think / hope they're not yet
// relevant for our use cases?)
let u_canonical = chalk_ir::UCanonical { canonical: goal, universes: 1 };
Expand Down
43 changes: 40 additions & 3 deletions crates/hir-ty/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
use std::iter;

use base_db::CrateId;
use chalk_ir::{cast::Cast, fold::Shift, BoundVar, DebruijnIndex, Mutability};
use chalk_ir::{
cast::Cast,
fold::{FallibleTypeFolder, Shift},
BoundVar, DebruijnIndex, Mutability,
};
use either::Either;
use hir_def::{
db::DefDatabase,
Expand All @@ -26,8 +30,8 @@ use smallvec::{smallvec, SmallVec};
use stdx::never;

use crate::{
db::HirDatabase, ChalkTraitId, GenericArg, Interner, Substitution, TraitRef, TraitRefExt, Ty,
TyExt, WhereClause,
consteval::unknown_const, db::HirDatabase, ChalkTraitId, Const, ConstScalar, GenericArg,
Interner, Substitution, TraitRef, TraitRefExt, Ty, TyExt, WhereClause,
};

pub(crate) fn fn_traits(
Expand Down Expand Up @@ -403,3 +407,36 @@ pub(crate) fn pattern_matching_dereference_count(
}
r
}

pub(crate) struct UnevaluatedConstEvaluatorFolder<'a> {
pub(crate) db: &'a dyn HirDatabase,
}

impl FallibleTypeFolder<Interner> for UnevaluatedConstEvaluatorFolder<'_> {
type Error = ();

fn as_dyn(&mut self) -> &mut dyn FallibleTypeFolder<Interner, Error = ()> {
self
}

fn interner(&self) -> Interner {
Interner
}

fn try_fold_const(
&mut self,
constant: Const,
_outer_binder: DebruijnIndex,
) -> Result<Const, Self::Error> {
if let chalk_ir::ConstValue::Concrete(c) = &constant.data(Interner).value {
if let ConstScalar::UnevaluatedConst(id, subst) = &c.interned {
if let Ok(eval) = self.db.const_eval(*id, subst.clone()) {
return Ok(eval);
} else {
return Ok(unknown_const(constant.data(Interner).ty.clone()));
}
}
}
Ok(constant)
}
}

0 comments on commit 1b5523a

Please sign in to comment.