about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-03-01 12:23:52 +0000
committerbors <bors@rust-lang.org>2023-03-01 12:23:52 +0000
commitef9d5db8571117911d8e039aed46fdff59bd65a2 (patch)
treefba748cdc1224e68962a5e55dc6b2a551fc7e0c3
parentd1fd6356c48ee37e45df6875e714804db94434eb (diff)
parentf64fe66c2a4a8e721ccb1f8971051c7caad8c100 (diff)
downloadrust-ef9d5db8571117911d8e039aed46fdff59bd65a2.tar.gz
rust-ef9d5db8571117911d8e039aed46fdff59bd65a2.zip
Auto merge of #14223 - HKalbasi:mir, r=HKalbasi
Add tuple to render_const_scalar

cc `@lowr`
-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#"