Skip to content

Commit

Permalink
Normalize projections in evaluated const display and layout calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
ChayimFriedman2 committed Feb 26, 2025
1 parent 8925544 commit 0c26312
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 5 deletions.
24 changes: 22 additions & 2 deletions crates/hir-ty/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -890,12 +890,32 @@ fn render_const_scalar(
TyKind::Closure(_, _) => f.write_str("<closure>"),
TyKind::Coroutine(_, _) => f.write_str("<coroutine>"),
TyKind::CoroutineWitness(_, _) => f.write_str("<coroutine-witness>"),
TyKind::AssociatedType(id, subst) => render_const_scalar(
f,
b,
memory_map,
&TyKind::Alias(AliasTy::Projection(ProjectionTy {
associated_ty_id: *id,
substitution: subst.clone(),
}))
.intern(Interner),
),
TyKind::Alias(AliasTy::Projection(projection)) => {
let normalized = f.db.normalize_projection(projection.clone(), trait_env);
if !matches!(
normalized.kind(Interner),
TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(..)
) {
render_const_scalar(f, b, memory_map, &normalized)
} else {
f.write_str("<placeholder-or-unknown-type>")
}
}
// The below arms are unreachable, since const eval will bail out before here.
TyKind::Foreign(_) => f.write_str("<extern-type>"),
TyKind::Error
| TyKind::Placeholder(_)
| TyKind::Alias(_)
| TyKind::AssociatedType(_, _)
| TyKind::Alias(AliasTy::Opaque(_))
| TyKind::OpaqueType(_, _)
| TyKind::BoundVar(_)
| TyKind::InferenceVar(_, _) => f.write_str("<placeholder-or-unknown-type>"),
Expand Down
13 changes: 10 additions & 3 deletions crates/hir-ty/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::{
infer::normalize,
layout::adt::struct_variant_idx,
utils::ClosureSubst,
Interner, ProjectionTy, Substitution, TraitEnvironment, Ty,
AliasTy, Interner, ProjectionTy, Substitution, TraitEnvironment, Ty,
};

pub use self::{
Expand Down Expand Up @@ -435,14 +435,21 @@ 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.
let ty = TyKind::Alias(chalk_ir::AliasTy::Projection(ProjectionTy {
let ty = TyKind::Alias(AliasTy::Projection(ProjectionTy {
associated_ty_id: *id,
substitution: subst.clone(),
}))
.intern(Interner);
return db.layout_of_ty(ty, trait_env);
}
TyKind::Alias(_)
TyKind::Alias(AliasTy::Projection(projection)) => {
let normalized = db.normalize_projection(projection.clone(), trait_env.clone());
return match normalized.kind(Interner) {
TyKind::Alias(_) | TyKind::AssociatedType(..) => Err(LayoutError::HasPlaceholder),
_ => db.layout_of_ty(normalized, trait_env),
};
}
TyKind::Alias(AliasTy::Opaque(_))
| TyKind::Placeholder(_)
| TyKind::BoundVar(_)
| TyKind::InferenceVar(_, _) => return Err(LayoutError::HasPlaceholder),
Expand Down
34 changes: 34 additions & 0 deletions crates/ide/src/hover/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
```
"#]],
);
}

0 comments on commit 0c26312

Please sign in to comment.