Consider ADT generic parameter defaults for unsubstituted layout calculations
This commit is contained in:
parent
c3b8c2a254
commit
86967032f7
@ -74,6 +74,10 @@ fn build_internal(self) -> (D, Substitution) {
|
|||||||
(self.data, subst)
|
(self.data, subst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn build_into_subst(self) -> Substitution {
|
||||||
|
self.build_internal().1
|
||||||
|
}
|
||||||
|
|
||||||
pub fn push(mut self, arg: impl CastTo<GenericArg>) -> Self {
|
pub fn push(mut self, arg: impl CastTo<GenericArg>) -> Self {
|
||||||
assert!(self.remaining() > 0);
|
assert!(self.remaining() > 0);
|
||||||
let arg = arg.cast(Interner);
|
let arg = arg.cast(Interner);
|
||||||
@ -291,7 +295,6 @@ pub fn fill_with_defaults(
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
// Note that we're building ADT, so we never have parent generic parameters.
|
// Note that we're building ADT, so we never have parent generic parameters.
|
||||||
let defaults = db.generic_defaults(self.data.into());
|
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()) {
|
for default_ty in defaults.iter().skip(self.vec.len()) {
|
||||||
// NOTE(skip_binders): we only check if the arg type is error type.
|
// NOTE(skip_binders): we only check if the arg type is error type.
|
||||||
if let Some(x) = default_ty.skip_binders().ty(Interner) {
|
if let Some(x) = default_ty.skip_binders().ty(Interner) {
|
||||||
@ -301,13 +304,16 @@ pub fn fill_with_defaults(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Each default can only depend on the previous parameters.
|
// Each default can only depend on the previous parameters.
|
||||||
// FIXME: we don't handle const generics here.
|
|
||||||
let subst_so_far = Substitution::from_iter(
|
let subst_so_far = Substitution::from_iter(
|
||||||
Interner,
|
Interner,
|
||||||
self.vec
|
self.vec
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.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()),
|
.take(self.param_kinds.len()),
|
||||||
);
|
);
|
||||||
self.vec.push(default_ty.clone().substitute(Interner, &subst_so_far).cast(Interner));
|
self.vec.push(default_ty.clone().substitute(Interner, &subst_so_far).cast(Interner));
|
||||||
|
@ -1418,16 +1418,14 @@ pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn layout(self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
|
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(
|
db.layout_of_adt(
|
||||||
self.into(),
|
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()),
|
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
|
/// Turns this ADT into a type. Any type parameters of the ADT will be
|
||||||
|
@ -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]
|
#[test]
|
||||||
fn test_hover_layout_of_enum() {
|
fn test_hover_layout_of_enum() {
|
||||||
check(
|
check(
|
||||||
@ -3673,6 +3716,7 @@ fn const_generic_order() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
// size = 0, align = 1
|
||||||
struct ST<const C: usize = 1, T = Foo>(T)
|
struct ST<const C: usize = 1, T = Foo>(T)
|
||||||
```
|
```
|
||||||
"#]],
|
"#]],
|
||||||
@ -3694,6 +3738,7 @@ fn const_generic_default_value() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
// size = 0, align = 1
|
||||||
struct ST<const C: usize = {const}, T = Foo>(T)
|
struct ST<const C: usize = {const}, T = Foo>(T)
|
||||||
```
|
```
|
||||||
"#]],
|
"#]],
|
||||||
@ -3716,6 +3761,7 @@ fn const_generic_default_value_2() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
// size = 0, align = 1
|
||||||
struct ST<const C: usize = VAL, T = Foo>(T)
|
struct ST<const C: usize = VAL, T = Foo>(T)
|
||||||
```
|
```
|
||||||
"#]],
|
"#]],
|
||||||
@ -7872,6 +7918,7 @@ struct Pedro$0<'a> {
|
|||||||
```
|
```
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
// size = 16 (0x10), align = 8, niches = 1
|
||||||
struct Pedro<'a>
|
struct Pedro<'a>
|
||||||
```
|
```
|
||||||
"#]],
|
"#]],
|
||||||
|
@ -37,7 +37,7 @@ pub enum ProcMacroKind {
|
|||||||
CustomDerive,
|
CustomDerive,
|
||||||
Attr,
|
Attr,
|
||||||
// This used to be called FuncLike, so that's what the server expects currently.
|
// 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"))]
|
#[serde(rename(serialize = "FuncLike", deserialize = "FuncLike"))]
|
||||||
Bang,
|
Bang,
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user