Auto merge of #14913 - HKalbasi:fix14844, r=HKalbasi
Evaluate `UnevalutedConst` before trait solving cc #14844
This commit is contained in:
commit
1b5523a8cd
@ -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> {
|
||||
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
@ -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};
|
||||
|
||||
@ -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.
|
||||
@ -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 };
|
||||
|
@ -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,
|
||||
@ -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(
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user