about summary refs log tree commit diff
diff options
context:
space:
mode:
authorhkalbasi <hamidrezakalbasi@protonmail.com>2023-02-28 23:12:30 +0330
committerhkalbasi <hamidrezakalbasi@protonmail.com>2023-02-28 23:12:30 +0330
commitf64fe66c2a4a8e721ccb1f8971051c7caad8c100 (patch)
tree0701fc66eba61f6c2d06c80bb1dbb2a52b53d65a
parent7f01ae877dfd26277a52630c9e40724db23ff8fc (diff)
downloadrust-f64fe66c2a4a8e721ccb1f8971051c7caad8c100.tar.gz
rust-f64fe66c2a4a8e721ccb1f8971051c7caad8c100.zip
Add tuple to render_const_scalar
-rw-r--r--crates/hir-ty/src/display.rs34
-rw-r--r--crates/ide/src/hover/tests.rs21
2 files changed, 52 insertions, 3 deletions
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index b6165f629e7..3123ddb985b 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -425,8 +425,36 @@ fn render_const_scalar(
                 let s = std::str::from_utf8(bytes).unwrap_or("<utf8-error>");
                 write!(f, "{s:?}")
             }
-            _ => f.write_str("<error>"),
+            _ => f.write_str("<ref-not-supported>"),
         },
+        chalk_ir::TyKind::Tuple(_, subst) => {
+            // FIXME: Remove this line. If the target data layout is independent
+            // of the krate, the `db.target_data_layout` and its callers like `layout_of_ty` don't need
+            // to get krate. Otherwise, we need to get krate from the final callers of the hir display
+            // infrastructure and have it here as a field on `f`.
+            let krate = *f.db.crate_graph().crates_in_topological_order().last().unwrap();
+            let Ok(layout) = layout_of_ty(f.db, ty, krate) else {
+                return f.write_str("<layout-error>");
+            };
+            f.write_str("(")?;
+            let mut first = true;
+            for (id, ty) in subst.iter(Interner).enumerate() {
+                if first {
+                    first = false;
+                } else {
+                    f.write_str(", ")?;
+                }
+                let ty = ty.assert_ty_ref(Interner); // Tuple only has type argument
+                let offset = layout.fields.offset(id).bytes_usize();
+                let Ok(layout) = layout_of_ty(f.db, &ty, krate) else {
+                    f.write_str("<layout-error>")?;
+                    continue;
+                };
+                let size = layout.size.bytes_usize();
+                render_const_scalar(f, &b[offset..offset + size], memory_map, &ty)?;
+            }
+            f.write_str(")")
+        }
         chalk_ir::TyKind::Adt(adt, subst) => match adt.0 {
             hir_def::AdtId::StructId(s) => {
                 let data = f.db.struct_data(s);
@@ -457,7 +485,7 @@ fn render_const_scalar(
                                 render_field(f, id)?;
                             }
                             for (id, data) in it {
-                                write!(f, ",  {}: ", data.name)?;
+                                write!(f, ", {}: ", data.name)?;
                                 render_field(f, id)?;
                             }
                             write!(f, " }}")?;
@@ -481,7 +509,7 @@ fn render_const_scalar(
             hir_def::AdtId::UnionId(u) => write!(f, "{}", f.db.union_data(u).name),
             hir_def::AdtId::EnumId(_) => f.write_str("<enum-not-supported>"),
         },
-        _ => f.write_str("<error>"),
+        _ => f.write_str("<not-supported>"),
     }
 }
 
diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs
index d4eb314a381..b29b57d134e 100644
--- a/crates/ide/src/hover/tests.rs
+++ b/crates/ide/src/hover/tests.rs
@@ -574,6 +574,27 @@ const foo$0: u32 = {
 }
 
 #[test]
+fn hover_eval_complex_constants() {
+    check(
+        r#"
+        struct X { f1: (), f2: i32 }
+        const foo$0: (i8, X, i64) = (1, X { f2: 5 - 1, f1: () }, 1 - 2);
+        "#,
+        expect![[r#"
+            *foo*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            const foo: (i8, X, i64) = (1, X { f1: (), f2: 4 }, -1)
+            ```
+        "#]],
+    );
+}
+
+#[test]
 fn hover_default_generic_types() {
     check(
         r#"