Unnamed repository; edit this file 'description' to name the repository.
fix: consider outer binders when folding captured items' type
Ryo Yoshida 2023-06-04
parent 4fb1df6 · commit 275afd6
-rw-r--r--crates/hir-ty/src/infer/closure.rs17
-rw-r--r--crates/hir-ty/src/mir/eval/tests.rs34
2 files changed, 40 insertions, 11 deletions
diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs
index 754ac88bb5..e98905f4ee 100644
--- a/crates/hir-ty/src/infer/closure.rs
+++ b/crates/hir-ty/src/infer/closure.rs
@@ -5,7 +5,7 @@ use std::{cmp, collections::HashMap, convert::Infallible, mem};
use chalk_ir::{
cast::Cast,
fold::{FallibleTypeFolder, TypeFoldable},
- AliasEq, AliasTy, BoundVar, ConstData, DebruijnIndex, FnSubst, Mutability, TyKind, WhereClause,
+ AliasEq, AliasTy, BoundVar, DebruijnIndex, FnSubst, Mutability, TyKind, WhereClause,
};
use hir_def::{
data::adt::VariantData,
@@ -26,8 +26,8 @@ use crate::{
static_lifetime, to_chalk_trait_id,
traits::FnTrait,
utils::{self, generics, Generics},
- Adjust, Adjustment, Binders, BindingMode, ChalkTraitId, ClosureId, ConstValue, DynTy,
- FnPointer, FnSig, Interner, Substitution, Ty, TyExt,
+ Adjust, Adjustment, Binders, BindingMode, ChalkTraitId, ClosureId, DynTy, FnPointer, FnSig,
+ Interner, Substitution, Ty, TyExt,
};
use super::{Expectation, InferenceContext};
@@ -266,24 +266,19 @@ impl CapturedItemWithoutTy {
let Some(idx) = self.generics.param_idx(x) else {
return Err(());
};
- Ok(ConstData {
- ty,
- value: ConstValue::BoundVar(BoundVar::new(outer_binder, idx)),
- }
- .intern(Interner))
+ Ok(BoundVar::new(outer_binder, idx).to_const(Interner, ty))
}
fn try_fold_free_placeholder_ty(
&mut self,
idx: chalk_ir::PlaceholderIndex,
- _outer_binder: DebruijnIndex,
+ outer_binder: DebruijnIndex,
) -> std::result::Result<Ty, Self::Error> {
let x = from_placeholder_idx(self.db, idx);
let Some(idx) = self.generics.param_idx(x) else {
return Err(());
};
- Ok(TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx))
- .intern(Interner))
+ Ok(BoundVar::new(outer_binder, idx).to_ty(Interner))
}
}
let g_def = match owner {
diff --git a/crates/hir-ty/src/mir/eval/tests.rs b/crates/hir-ty/src/mir/eval/tests.rs
index dabc76ba15..ca4268b8fb 100644
--- a/crates/hir-ty/src/mir/eval/tests.rs
+++ b/crates/hir-ty/src/mir/eval/tests.rs
@@ -640,3 +640,37 @@ fn main() {
"#,
);
}
+
+#[test]
+fn regression_14966() {
+ check_pass(
+ r#"
+//- minicore: fn, copy, coerce_unsized
+trait A<T> {
+ fn a(&self) {}
+}
+impl A<()> for () {}
+
+struct B;
+impl B {
+ pub fn b<T>(s: &dyn A<T>) -> Self {
+ B
+ }
+}
+struct C;
+impl C {
+ fn c<T>(a: &dyn A<T>) -> Self {
+ let mut c = C;
+ let b = B::b(a);
+ c.d(|| a.a());
+ c
+ }
+ fn d(&mut self, f: impl FnOnce()) {}
+}
+
+fn main() {
+ C::c(&());
+}
+"#,
+ );
+}