diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-07-12 21:31:51 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-07-12 21:31:51 +0100 |
commit | 5ca7cd960b908944a2f3f66a1d0ee5df98b78959 (patch) | |
tree | 5f4b29e4d2dbfc02e178a4d33731319e510468bb /crates/ra_hir_ty | |
parent | 39e049d2a1d7e0adbd9546f9e8124843443b31ce (diff) | |
parent | 8a72e40ca91cc51a93b8145582feaccb7254abb6 (diff) |
Merge #5331
5331: Fix #4966 r=flodiebold a=flodiebold
We add a level of binders when converting our function pointer to Chalk's; we need to remove it again on the way back.
Fixes #4966.
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r-- | crates/ra_hir_ty/src/tests/regression.rs | 57 | ||||
-rw-r--r-- | 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 d806e0ffb..4367621fc 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<Request> { | |||
779 | "### | 779 | "### |
780 | ); | 780 | ); |
781 | } | 781 | } |
782 | |||
783 | #[test] | ||
784 | fn issue_4966() { | ||
785 | assert_snapshot!( | ||
786 | infer(r#" | ||
787 | pub trait IntoIterator { | ||
788 | type Item; | ||
789 | } | ||
790 | |||
791 | struct Repeat<A> { element: A } | ||
792 | |||
793 | struct Map<F> { f: F } | ||
794 | |||
795 | struct Vec<T> {} | ||
796 | |||
797 | #[lang = "deref"] | ||
798 | pub trait Deref { | ||
799 | type Target; | ||
800 | } | ||
801 | |||
802 | impl<T> Deref for Vec<T> { | ||
803 | type Target = [T]; | ||
804 | } | ||
805 | |||
806 | fn from_iter<A, T: IntoIterator<Item = A>>(iter: T) -> Vec<A> {} | ||
807 | |||
808 | fn main() { | ||
809 | let inner = Map { f: |_: &f64| 0.0 }; | ||
810 | |||
811 | let repeat = Repeat { element: inner }; | ||
812 | |||
813 | let vec = from_iter(repeat); | ||
814 | |||
815 | vec.foo_bar(); | ||
816 | } | ||
817 | "#), | ||
818 | @r###" | ||
819 | 270..274 'iter': T | ||
820 | 289..291 '{}': () | ||
821 | 303..447 '{ ...r(); }': () | ||
822 | 313..318 'inner': Map<|&f64| -> f64> | ||
823 | 321..345 'Map { ... 0.0 }': Map<|&f64| -> f64> | ||
824 | 330..343 '|_: &f64| 0.0': |&f64| -> f64 | ||
825 | 331..332 '_': &f64 | ||
826 | 340..343 '0.0': f64 | ||
827 | 356..362 'repeat': Repeat<Map<|&f64| -> f64>> | ||
828 | 365..390 'Repeat...nner }': Repeat<Map<|&f64| -> f64>> | ||
829 | 383..388 'inner': Map<|&f64| -> f64> | ||
830 | 401..404 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> | ||
831 | 407..416 'from_iter': fn from_iter<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>, Repeat<Map<|&f64| -> f64>>>(Repeat<Map<|&f64| -> f64>>) -> Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> | ||
832 | 407..424 'from_i...epeat)': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> | ||
833 | 417..423 'repeat': Repeat<Map<|&f64| -> f64>> | ||
834 | 431..434 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> | ||
835 | 431..444 'vec.foo_bar()': {unknown} | ||
836 | "### | ||
837 | ); | ||
838 | } | ||
diff --git a/crates/ra_hir_ty/src/traits/chalk/mapping.rs b/crates/ra_hir_ty/src/traits/chalk/mapping.rs index 7dc9ee759..06453ef82 100644 --- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs +++ b/crates/ra_hir_ty/src/traits/chalk/mapping.rs | |||
@@ -117,8 +117,12 @@ impl ToChalk for Ty { | |||
117 | let parameters = from_chalk(db, opaque_ty.substitution); | 117 | let parameters = from_chalk(db, opaque_ty.substitution); |
118 | Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters }) | 118 | Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters }) |
119 | } | 119 | } |
120 | chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: _, substitution }) => { | 120 | chalk_ir::TyData::Function(chalk_ir::Fn { num_binders, substitution }) => { |
121 | let parameters: Substs = from_chalk(db, substitution); | 121 | assert_eq!(num_binders, 0); |
122 | let parameters: Substs = from_chalk( | ||
123 | db, | ||
124 | substitution.shifted_out(&Interner).expect("fn ptr should have no binders"), | ||
125 | ); | ||
122 | Ty::Apply(ApplicationTy { | 126 | Ty::Apply(ApplicationTy { |
123 | ctor: TypeCtor::FnPtr { num_args: (parameters.len() - 1) as u16 }, | 127 | ctor: TypeCtor::FnPtr { num_args: (parameters.len() - 1) as u16 }, |
124 | parameters, | 128 | parameters, |