about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChayim Refael Friedman <chayimfr@gmail.com>2025-02-27 11:21:01 +0200
committerChayim Refael Friedman <chayimfr@gmail.com>2025-03-06 20:55:50 +0200
commit860637abc36c5ab3cdc1cf6a5b4130a2d8fecd03 (patch)
tree2574bc3b4f2c96d09ddf6240c186fbafc7cefa3c
parent6a3ede12405d2f167d23609b081d11b7e3cc1036 (diff)
downloadrust-860637abc36c5ab3cdc1cf6a5b4130a2d8fecd03.tar.gz
rust-860637abc36c5ab3cdc1cf6a5b4130a2d8fecd03.zip
Normalize projections in evaluated const display and layout calculation
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/display.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/layout.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/tests.rs34
3 files changed, 39 insertions, 0 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
index 6ee4780d206..b3613b372bf 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -45,6 +45,7 @@ use crate::{
     db::{HirDatabase, InternedClosure},
     from_assoc_type_id, from_foreign_def_id, from_placeholder_idx,
     generics::generics,
+    infer::normalize,
     layout::Layout,
     lt_from_placeholder_idx,
     mapping::from_chalk,
@@ -657,6 +658,7 @@ fn render_const_scalar(
     // infrastructure and have it here as a field on `f`.
     let trait_env =
         TraitEnvironment::empty(*f.db.crate_graph().crates_in_topological_order().last().unwrap());
+    let ty = normalize(f.db, trait_env.clone(), ty.clone());
     match ty.kind(Interner) {
         TyKind::Scalar(s) => match s {
             Scalar::Bool => write!(f, "{}", b[0] != 0),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
index a4e49e0aa10..6b5c712159a 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
@@ -435,6 +435,9 @@ pub fn layout_of_ty_query(
         TyKind::Error => return Err(LayoutError::HasErrorType),
         TyKind::AssociatedType(id, subst) => {
             // Try again with `TyKind::Alias` to normalize the associated type.
+            // Usually we should not try to normalize `TyKind::AssociatedType`, but layout calculation is used
+            // in monomorphized MIR where this is okay. If outside monomorphization, this will lead to cycle,
+            // which we will recover from with an error.
             let ty = TyKind::Alias(chalk_ir::AliasTy::Projection(ProjectionTy {
                 associated_ty_id: *id,
                 substitution: subst.clone(),
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
index 7c720d97cb6..964b1d7eb7d 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
@@ -10947,3 +10947,37 @@ pub struct ManuallyDrop$0<T: ?Sized> {
         "#]],
     );
 }
+
+#[test]
+fn projection_const() {
+    check(
+        r#"
+pub trait PublicFlags {
+    type Internal;
+}
+
+pub struct NoteDialects(<NoteDialects as PublicFlags>::Internal);
+
+impl NoteDialects {
+    pub const CLAP$0: Self = Self(InternalBitFlags);
+}
+
+pub struct InternalBitFlags;
+
+impl PublicFlags for NoteDialects {
+    type Internal = InternalBitFlags;
+}
+    "#,
+        expect![[r#"
+            *CLAP*
+
+            ```rust
+            ra_test_fixture::NoteDialects
+            ```
+
+            ```rust
+            pub const CLAP: Self = NoteDialects(InternalBitFlags)
+            ```
+        "#]],
+    );
+}