diff options
| author | Ryo Yoshida <low.ryoshida@gmail.com> | 2023-06-04 19:38:47 +0900 |
|---|---|---|
| committer | Ryo Yoshida <low.ryoshida@gmail.com> | 2023-06-04 19:38:47 +0900 |
| commit | 275afd6e79f4e23d870a8017c805f786e400af72 (patch) | |
| tree | 6041d9f66e388d52e21b21327d1c66b52b14f864 | |
| parent | 4fb1df6b7a410ffbb2bfd7d5172d14435f059616 (diff) | |
| download | rust-275afd6e79f4e23d870a8017c805f786e400af72.tar.gz rust-275afd6e79f4e23d870a8017c805f786e400af72.zip | |
fix: consider outer binders when folding captured items' type
| -rw-r--r-- | crates/hir-ty/src/infer/closure.rs | 17 | ||||
| -rw-r--r-- | crates/hir-ty/src/mir/eval/tests.rs | 34 |
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(&()); +} +"#, + ); +} |
