]> git.lizzy.rs Git - rust.git/commitdiff
Fix #4966
authorFlorian Diebold <florian.diebold@freiheit.com>
Fri, 10 Jul 2020 17:14:33 +0000 (19:14 +0200)
committerFlorian Diebold <flodiebold@gmail.com>
Sun, 12 Jul 2020 13:37:32 +0000 (15:37 +0200)
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
crates/ra_hir_ty/src/traits/chalk/mapping.rs

index d806e0ffb34605b70cd45f69bdf2306178122b3d..4367621fc8dcaa86441a5c21d4d2980706a6123d 100644 (file)
@@ -779,3 +779,60 @@ pub trait Service<Request> {
     "###
     );
 }
+
+#[test]
+fn issue_4966() {
+    assert_snapshot!(
+        infer(r#"
+pub trait IntoIterator {
+    type Item;
+}
+
+struct Repeat<A> { element: A }
+
+struct Map<F> { f: F }
+
+struct Vec<T> {}
+
+#[lang = "deref"]
+pub trait Deref {
+    type Target;
+}
+
+impl<T> Deref for Vec<T> {
+    type Target = [T];
+}
+
+fn from_iter<A, T: IntoIterator<Item = A>>(iter: T) -> Vec<A> {}
+
+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<Map<|&f64| -> f64>>
+    365..390 'Repeat...nner }': Repeat<Map<|&f64| -> f64>>
+    383..388 'inner': Map<|&f64| -> f64>
+    401..404 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
+    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>>>>
+    407..424 'from_i...epeat)': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
+    417..423 'repeat': Repeat<Map<|&f64| -> f64>>
+    431..434 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
+    431..444 'vec.foo_bar()': {unknown}
+    "###
+    );
+}
index 433d6aa03de3fdf64ac0e6522868dcfec621cdb9..cb354d586bb3838670277298cdc436d1c72005e9 100644 (file)
@@ -115,8 +115,12 @@ fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self {
                 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,