Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-ty/src/display.rs2
-rw-r--r--crates/hir-ty/src/layout.rs3
-rw-r--r--crates/ide/src/hover/tests.rs34
3 files changed, 39 insertions, 0 deletions
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index 6ee4780d20..b3613b372b 100644
--- a/crates/hir-ty/src/display.rs
+++ b/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/crates/hir-ty/src/layout.rs b/crates/hir-ty/src/layout.rs
index a4e49e0aa1..6b5c712159 100644
--- a/crates/hir-ty/src/layout.rs
+++ b/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/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs
index 7c720d97cb..964b1d7eb7 100644
--- a/crates/ide/src/hover/tests.rs
+++ b/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)
+ ```
+ "#]],
+ );
+}