Skip to content

Commit

Permalink
Auto merge of #17002 - Veykril:layout-defaults, r=Veykril
Browse files Browse the repository at this point in the history
internal: Consider ADT generic parameter defaults for unsubstituted layout calculations

For one, this brings back layout information for lifetime generic ADTs (which "regressed" when we started adding lifetimes to chalks-ir), but it also allows layout calculation to work for definitions that don't actually use the generics (where its only used in a `PhantomData` for example)
  • Loading branch information
bors committed Apr 3, 2024
2 parents c3b8c2a + 8696703 commit 0140272
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 10 deletions.
12 changes: 9 additions & 3 deletions crates/hir-ty/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ impl<D> TyBuilder<D> {
(self.data, subst)
}

pub fn build_into_subst(self) -> Substitution {
self.build_internal().1
}

pub fn push(mut self, arg: impl CastTo<GenericArg>) -> Self {
assert!(self.remaining() > 0);
let arg = arg.cast(Interner);
Expand Down Expand Up @@ -291,7 +295,6 @@ impl TyBuilder<hir_def::AdtId> {
) -> Self {
// Note that we're building ADT, so we never have parent generic parameters.
let defaults = db.generic_defaults(self.data.into());
let dummy_ty = TyKind::Error.intern(Interner).cast(Interner);
for default_ty in defaults.iter().skip(self.vec.len()) {
// NOTE(skip_binders): we only check if the arg type is error type.
if let Some(x) = default_ty.skip_binders().ty(Interner) {
Expand All @@ -301,13 +304,16 @@ impl TyBuilder<hir_def::AdtId> {
}
}
// Each default can only depend on the previous parameters.
// FIXME: we don't handle const generics here.
let subst_so_far = Substitution::from_iter(
Interner,
self.vec
.iter()
.cloned()
.chain(iter::repeat(dummy_ty.clone()))
.chain(self.param_kinds[self.vec.len()..].iter().map(|it| match it {
ParamKind::Type => TyKind::Error.intern(Interner).cast(Interner),
ParamKind::Lifetime => error_lifetime().cast(Interner),
ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
}))
.take(self.param_kinds.len()),
);
self.vec.push(default_ty.clone().substitute(Interner, &subst_so_far).cast(Interner));
Expand Down
10 changes: 4 additions & 6 deletions crates/hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1418,16 +1418,14 @@ impl Adt {
}

pub fn layout(self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
if !db.generic_params(self.into()).is_empty() {
return Err(LayoutError::HasPlaceholder);
}
let krate = self.krate(db).id;
db.layout_of_adt(
self.into(),
Substitution::empty(Interner),
TyBuilder::adt(db, self.into())
.fill_with_defaults(db, || TyKind::Error.intern(Interner))
.build_into_subst(),
db.trait_environment(self.into()),
)
.map(|layout| Layout(layout, db.target_data_layout(krate).unwrap()))
.map(|layout| Layout(layout, db.target_data_layout(self.krate(db).id).unwrap()))
}

/// Turns this ADT into a type. Any type parameters of the ADT will be
Expand Down
47 changes: 47 additions & 0 deletions crates/ide/src/hover/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2322,6 +2322,49 @@ fn test_hover_layout_of_variant() {
);
}

#[test]
fn test_hover_layout_of_variant_generic() {
check(
r#"enum Option<T> {
Some(T),
None$0
}"#,
expect![[r#"
*None*
```rust
test::Option
```
```rust
None
```
"#]],
);
}

#[test]
fn test_hover_layout_generic_unused() {
check(
r#"
//- minicore: phantom_data
struct S$0<T>(core::marker::PhantomData<T>);
"#,
expect![[r#"
*S*
```rust
test
```
```rust
// size = 0, align = 1
struct S<T>(PhantomData<T>)
```
"#]],
);
}

#[test]
fn test_hover_layout_of_enum() {
check(
Expand Down Expand Up @@ -3673,6 +3716,7 @@ struct S$0T<const C: usize = 1, T = Foo>(T);
```
```rust
// size = 0, align = 1
struct ST<const C: usize = 1, T = Foo>(T)
```
"#]],
Expand All @@ -3694,6 +3738,7 @@ struct S$0T<const C: usize = {40 + 2}, T = Foo>(T);
```
```rust
// size = 0, align = 1
struct ST<const C: usize = {const}, T = Foo>(T)
```
"#]],
Expand All @@ -3716,6 +3761,7 @@ struct S$0T<const C: usize = VAL, T = Foo>(T);
```
```rust
// size = 0, align = 1
struct ST<const C: usize = VAL, T = Foo>(T)
```
"#]],
Expand Down Expand Up @@ -7872,6 +7918,7 @@ struct Pedro$0<'a> {
```
```rust
// size = 16 (0x10), align = 8, niches = 1
struct Pedro<'a>
```
"#]],
Expand Down
2 changes: 1 addition & 1 deletion crates/proc-macro-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub enum ProcMacroKind {
CustomDerive,
Attr,
// This used to be called FuncLike, so that's what the server expects currently.
#[serde(alias = "bang")]
#[serde(alias = "Bang")]
#[serde(rename(serialize = "FuncLike", deserialize = "FuncLike"))]
Bang,
}
Expand Down

0 comments on commit 0140272

Please sign in to comment.