From 8a72e40ca91cc51a93b8145582feaccb7254abb6 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 10 Jul 2020 19:14:33 +0200 Subject: [PATCH] Fix #4966 We add a level of binders when converting our function pointer to Chalk's; we need to remove it again on the way back. --- crates/ra_hir_ty/src/tests/regression.rs | 57 ++++++++++++++++++++ crates/ra_hir_ty/src/traits/chalk/mapping.rs | 8 ++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs index d806e0ffb3..4367621fc8 100644 --- a/crates/ra_hir_ty/src/tests/regression.rs +++ b/crates/ra_hir_ty/src/tests/regression.rs @@ -779,3 +779,60 @@ pub trait Service { "### ); } + +#[test] +fn issue_4966() { + assert_snapshot!( + infer(r#" +pub trait IntoIterator { + type Item; +} + +struct Repeat { element: A } + +struct Map { f: F } + +struct Vec {} + +#[lang = "deref"] +pub trait Deref { + type Target; +} + +impl Deref for Vec { + type Target = [T]; +} + +fn from_iter>(iter: T) -> Vec {} + +fn main() { + let inner = Map { f: |_: &f64| 0.0 }; + + let repeat = Repeat { element: inner }; + + let vec = from_iter(repeat); + + vec.foo_bar(); +} +"#), + @r###" + 270..274 'iter': T + 289..291 '{}': () + 303..447 '{ ...r(); }': () + 313..318 'inner': Map<|&f64| -> f64> + 321..345 'Map { ... 0.0 }': Map<|&f64| -> f64> + 330..343 '|_: &f64| 0.0': |&f64| -> f64 + 331..332 '_': &f64 + 340..343 '0.0': f64 + 356..362 'repeat': Repeat f64>> + 365..390 'Repeat...nner }': Repeat f64>> + 383..388 'inner': Map<|&f64| -> f64> + 401..404 'vec': Vec f64>>>> + 407..416 'from_iter': fn from_iter f64>>>, Repeat f64>>>(Repeat f64>>) -> Vec f64>>>> + 407..424 'from_i...epeat)': Vec f64>>>> + 417..423 'repeat': Repeat f64>> + 431..434 'vec': Vec f64>>>> + 431..444 'vec.foo_bar()': {unknown} + "### + ); +} diff --git a/crates/ra_hir_ty/src/traits/chalk/mapping.rs b/crates/ra_hir_ty/src/traits/chalk/mapping.rs index 433d6aa03d..cb354d586b 100644 --- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs +++ b/crates/ra_hir_ty/src/traits/chalk/mapping.rs @@ -115,8 +115,12 @@ impl ToChalk for Ty { let parameters = from_chalk(db, opaque_ty.substitution); Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters }) } - chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: _, substitution }) => { - let parameters: Substs = from_chalk(db, substitution); + chalk_ir::TyData::Function(chalk_ir::Fn { num_binders, substitution }) => { + assert_eq!(num_binders, 0); + let parameters: Substs = from_chalk( + db, + substitution.shifted_out(&Interner).expect("fn ptr should have no binders"), + ); Ty::Apply(ApplicationTy { ctor: TypeCtor::FnPtr { num_args: (parameters.len() - 1) as u16 }, parameters,