Evaluate UnevalutedConst
before trait solving
This commit is contained in:
parent
08f0c29954
commit
cd4bffdd69
@ -15,11 +15,11 @@ use triomphe::Arc;
|
|||||||
|
|
||||||
use super::{InferOk, InferResult, InferenceContext, TypeError};
|
use super::{InferOk, InferResult, InferenceContext, TypeError};
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase, fold_tys_and_consts, static_lifetime, to_chalk_trait_id, traits::FnTrait,
|
consteval::unknown_const, db::HirDatabase, fold_tys_and_consts, static_lifetime,
|
||||||
AliasEq, AliasTy, BoundVar, Canonical, Const, ConstValue, DebruijnIndex, GenericArg,
|
to_chalk_trait_id, traits::FnTrait, AliasEq, AliasTy, BoundVar, Canonical, Const, ConstValue,
|
||||||
GenericArgData, Goal, Guidance, InEnvironment, InferenceVar, Interner, Lifetime, ParamKind,
|
DebruijnIndex, GenericArg, GenericArgData, Goal, Guidance, InEnvironment, InferenceVar,
|
||||||
ProjectionTy, ProjectionTyExt, Scalar, Solution, Substitution, TraitEnvironment, Ty, TyBuilder,
|
Interner, Lifetime, ParamKind, ProjectionTy, ProjectionTyExt, Scalar, Solution, Substitution,
|
||||||
TyExt, TyKind, VariableKind,
|
TraitEnvironment, Ty, TyBuilder, TyExt, TyKind, VariableKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<'a> InferenceContext<'a> {
|
impl<'a> InferenceContext<'a> {
|
||||||
@ -256,10 +256,10 @@ impl<'a> InferenceTable<'a> {
|
|||||||
{
|
{
|
||||||
eval
|
eval
|
||||||
} else {
|
} else {
|
||||||
c
|
unknown_const(c.data(Interner).ty.clone())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c
|
unknown_const(c.data(Interner).ty.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => c,
|
_ => 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 std::env::var;
|
||||||
|
|
||||||
use chalk_ir::GoalData;
|
use chalk_ir::{fold::TypeFoldable, DebruijnIndex, GoalData};
|
||||||
use chalk_recursive::Cache;
|
use chalk_recursive::Cache;
|
||||||
use chalk_solve::{logging_db::LoggingRustIrDatabase, rust_ir, Solver};
|
use chalk_solve::{logging_db::LoggingRustIrDatabase, rust_ir, Solver};
|
||||||
|
|
||||||
@ -16,9 +16,9 @@ use stdx::panic_context;
|
|||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase, infer::unify::InferenceTable, AliasEq, AliasTy, Canonical, DomainGoal, Goal,
|
db::HirDatabase, infer::unify::InferenceTable, utils::UnevaluatedConstEvaluatorFolder, AliasEq,
|
||||||
Guidance, InEnvironment, Interner, ProjectionTy, ProjectionTyExt, Solution, TraitRefExt, Ty,
|
AliasTy, Canonical, DomainGoal, Goal, Guidance, InEnvironment, Interner, ProjectionTy,
|
||||||
TyKind, WhereClause,
|
ProjectionTyExt, Solution, TraitRefExt, Ty, TyKind, WhereClause,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This controls how much 'time' we give the Chalk solver before giving up.
|
/// 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
|
// We currently don't deal with universes (I think / hope they're not yet
|
||||||
// relevant for our use cases?)
|
// relevant for our use cases?)
|
||||||
let u_canonical = chalk_ir::UCanonical { canonical: goal, universes: 1 };
|
let u_canonical = chalk_ir::UCanonical { canonical: goal, universes: 1 };
|
||||||
|
@ -4,7 +4,11 @@
|
|||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use base_db::CrateId;
|
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 either::Either;
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
@ -26,8 +30,8 @@ use smallvec::{smallvec, SmallVec};
|
|||||||
use stdx::never;
|
use stdx::never;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase, ChalkTraitId, GenericArg, Interner, Substitution, TraitRef, TraitRefExt, Ty,
|
consteval::unknown_const, db::HirDatabase, ChalkTraitId, Const, ConstScalar, GenericArg,
|
||||||
TyExt, WhereClause,
|
Interner, Substitution, TraitRef, TraitRefExt, Ty, TyExt, WhereClause,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) fn fn_traits(
|
pub(crate) fn fn_traits(
|
||||||
@ -403,3 +407,36 @@ pub(crate) fn pattern_matching_dereference_count(
|
|||||||
}
|
}
|
||||||
r
|
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