Skip to content

Commit 1b5523a

Browse files
committed
Auto merge of rust-lang#14913 - HKalbasi:fix14844, r=HKalbasi
Evaluate `UnevalutedConst` before trait solving cc rust-lang#14844
2 parents 7c81fff + cd4bffd commit 1b5523a

File tree

4 files changed

+80
-14
lines changed

4 files changed

+80
-14
lines changed

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

+7-7
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ use triomphe::Arc;
1515

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

2525
impl<'a> InferenceContext<'a> {
@@ -256,10 +256,10 @@ impl<'a> InferenceTable<'a> {
256256
{
257257
eval
258258
} else {
259-
c
259+
unknown_const(c.data(Interner).ty.clone())
260260
}
261261
} else {
262-
c
262+
unknown_const(c.data(Interner).ty.clone())
263263
}
264264
}
265265
_ => c,

crates/hir-ty/src/tests/regression.rs

+23
Original file line numberDiff line numberDiff line change
@@ -1912,3 +1912,26 @@ fn main() {
19121912
"#,
19131913
);
19141914
}
1915+
1916+
#[test]
1917+
fn regression_14844_2() {
1918+
check_no_mismatches(
1919+
r#"
1920+
//- minicore: fn
1921+
pub const ONE: usize = 1;
1922+
1923+
pub type MyInner = Inner<ONE>;
1924+
1925+
pub struct Inner<const P: usize>();
1926+
1927+
impl Inner<1> {
1928+
fn map<F>(&self, func: F) -> bool
1929+
where
1930+
F: Fn(&MyInner) -> bool,
1931+
{
1932+
func(self)
1933+
}
1934+
}
1935+
"#,
1936+
);
1937+
}

crates/hir-ty/src/traits.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use std::env::var;
44

5-
use chalk_ir::GoalData;
5+
use chalk_ir::{fold::TypeFoldable, DebruijnIndex, GoalData};
66
use chalk_recursive::Cache;
77
use chalk_solve::{logging_db::LoggingRustIrDatabase, rust_ir, Solver};
88

@@ -16,9 +16,9 @@ use stdx::panic_context;
1616
use triomphe::Arc;
1717

1818
use crate::{
19-
db::HirDatabase, infer::unify::InferenceTable, AliasEq, AliasTy, Canonical, DomainGoal, Goal,
20-
Guidance, InEnvironment, Interner, ProjectionTy, ProjectionTyExt, Solution, TraitRefExt, Ty,
21-
TyKind, WhereClause,
19+
db::HirDatabase, infer::unify::InferenceTable, utils::UnevaluatedConstEvaluatorFolder, AliasEq,
20+
AliasTy, Canonical, DomainGoal, Goal, Guidance, InEnvironment, Interner, ProjectionTy,
21+
ProjectionTyExt, Solution, TraitRefExt, Ty, TyKind, WhereClause,
2222
};
2323

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

109+
// Chalk see `UnevaluatedConst` as a unique concrete value, but we see it as an alias for another const. So
110+
// we should get rid of it when talking to chalk.
111+
let goal = goal
112+
.try_fold_with(&mut UnevaluatedConstEvaluatorFolder { db }, DebruijnIndex::INNERMOST)
113+
.unwrap();
114+
109115
// We currently don't deal with universes (I think / hope they're not yet
110116
// relevant for our use cases?)
111117
let u_canonical = chalk_ir::UCanonical { canonical: goal, universes: 1 };

crates/hir-ty/src/utils.rs

+40-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
use std::iter;
55

66
use base_db::CrateId;
7-
use chalk_ir::{cast::Cast, fold::Shift, BoundVar, DebruijnIndex, Mutability};
7+
use chalk_ir::{
8+
cast::Cast,
9+
fold::{FallibleTypeFolder, Shift},
10+
BoundVar, DebruijnIndex, Mutability,
11+
};
812
use either::Either;
913
use hir_def::{
1014
db::DefDatabase,
@@ -26,8 +30,8 @@ use smallvec::{smallvec, SmallVec};
2630
use stdx::never;
2731

2832
use crate::{
29-
db::HirDatabase, ChalkTraitId, GenericArg, Interner, Substitution, TraitRef, TraitRefExt, Ty,
30-
TyExt, WhereClause,
33+
consteval::unknown_const, db::HirDatabase, ChalkTraitId, Const, ConstScalar, GenericArg,
34+
Interner, Substitution, TraitRef, TraitRefExt, Ty, TyExt, WhereClause,
3135
};
3236

3337
pub(crate) fn fn_traits(
@@ -403,3 +407,36 @@ pub(crate) fn pattern_matching_dereference_count(
403407
}
404408
r
405409
}
410+
411+
pub(crate) struct UnevaluatedConstEvaluatorFolder<'a> {
412+
pub(crate) db: &'a dyn HirDatabase,
413+
}
414+
415+
impl FallibleTypeFolder<Interner> for UnevaluatedConstEvaluatorFolder<'_> {
416+
type Error = ();
417+
418+
fn as_dyn(&mut self) -> &mut dyn FallibleTypeFolder<Interner, Error = ()> {
419+
self
420+
}
421+
422+
fn interner(&self) -> Interner {
423+
Interner
424+
}
425+
426+
fn try_fold_const(
427+
&mut self,
428+
constant: Const,
429+
_outer_binder: DebruijnIndex,
430+
) -> Result<Const, Self::Error> {
431+
if let chalk_ir::ConstValue::Concrete(c) = &constant.data(Interner).value {
432+
if let ConstScalar::UnevaluatedConst(id, subst) = &c.interned {
433+
if let Ok(eval) = self.db.const_eval(*id, subst.clone()) {
434+
return Ok(eval);
435+
} else {
436+
return Ok(unknown_const(constant.data(Interner).ty.clone()));
437+
}
438+
}
439+
}
440+
Ok(constant)
441+
}
442+
}

0 commit comments

Comments
 (0)