about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRyo Yoshida <low.ryoshida@gmail.com>2023-06-04 19:38:47 +0900
committerRyo Yoshida <low.ryoshida@gmail.com>2023-06-04 19:38:47 +0900
commit275afd6e79f4e23d870a8017c805f786e400af72 (patch)
tree6041d9f66e388d52e21b21327d1c66b52b14f864
parent4fb1df6b7a410ffbb2bfd7d5172d14435f059616 (diff)
downloadrust-275afd6e79f4e23d870a8017c805f786e400af72.tar.gz
rust-275afd6e79f4e23d870a8017c805f786e400af72.zip
fix: consider outer binders when folding captured items' type
-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 754ac88bb50..e98905f4eee 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 dabc76ba15b..ca4268b8fb0 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(&());
+}
+"#,
+    );
+}