Give real discriminant_type to chalk

This commit is contained in:
hkalbasi 2023-07-14 20:15:18 +03:30
parent 5208bf8f55
commit 50559118fb
6 changed files with 135 additions and 24 deletions

View file

@ -416,6 +416,44 @@ fn test_hash_expand() {
//- minicore: derive, hash
use core::hash::Hash;
#[derive(Hash)]
struct Foo {
x: i32,
y: u64,
z: (i32, u64),
}
"#,
expect![[r#"
use core::hash::Hash;
#[derive(Hash)]
struct Foo {
x: i32,
y: u64,
z: (i32, u64),
}
impl < > core::hash::Hash for Foo< > where {
fn hash<H: core::hash::Hasher>(&self , ra_expand_state: &mut H) {
match self {
Foo {
x: x, y: y, z: z,
}
=> {
x.hash(ra_expand_state);
y.hash(ra_expand_state);
z.hash(ra_expand_state);
}
,
}
}
}"#]],
);
check(
r#"
//- minicore: derive, hash
use core::hash::Hash;
#[derive(Hash)]
enum Command {
Move { x: i32, y: i32 },

View file

@ -624,9 +624,14 @@ fn hash_expand(
}
},
);
let check_discriminant = if matches!(&adt.shape, AdtShape::Enum { .. }) {
quote! { #krate::mem::discriminant(self).hash(ra_expand_state); }
} else {
quote! {}
};
quote! {
fn hash<H: #krate::hash::Hasher>(&self, ra_expand_state: &mut H) {
#krate::mem::discriminant(self).hash(ra_expand_state);
#check_discriminant
match self {
##arms
}
@ -742,9 +747,6 @@ fn ord_expand(
// FIXME: Return expand error here
return quote!();
}
let left = quote!(#krate::intrinsics::discriminant_value(self));
let right = quote!(#krate::intrinsics::discriminant_value(other));
let (self_patterns, other_patterns) = self_and_other_patterns(adt, &adt.name);
let arms = izip!(self_patterns, other_patterns, adt.shape.field_names()).map(
|(pat1, pat2, fields)| {
@ -759,17 +761,17 @@ fn ord_expand(
},
);
let fat_arrow = fat_arrow();
let body = compare(
krate,
left,
right,
quote! {
let mut body = quote! {
match (self, other) {
##arms
_unused #fat_arrow #krate::cmp::Ordering::Equal
}
},
);
};
if matches!(&adt.shape, AdtShape::Enum { .. }) {
let left = quote!(#krate::intrinsics::discriminant_value(self));
let right = quote!(#krate::intrinsics::discriminant_value(other));
body = compare(krate, left, right, body);
}
quote! {
fn cmp(&self, other: &Self) -> #krate::cmp::Ordering {
#body

View file

@ -60,9 +60,37 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
// FIXME: keep track of these
Arc::new(rust_ir::AdtRepr { c: false, packed: false, int: None })
}
fn discriminant_type(&self, _ty: chalk_ir::Ty<Interner>) -> chalk_ir::Ty<Interner> {
// FIXME: keep track of this
chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::U32)).intern(Interner)
fn discriminant_type(&self, ty: chalk_ir::Ty<Interner>) -> chalk_ir::Ty<Interner> {
if let chalk_ir::TyKind::Adt(id, _) = ty.kind(Interner) {
if let hir_def::AdtId::EnumId(e) = id.0 {
let enum_data = self.db.enum_data(e);
let ty = enum_data.repr.unwrap_or_default().discr_type();
return chalk_ir::TyKind::Scalar(match ty {
hir_def::layout::IntegerType::Pointer(is_signed) => match is_signed {
true => chalk_ir::Scalar::Int(chalk_ir::IntTy::Isize),
false => chalk_ir::Scalar::Uint(chalk_ir::UintTy::Usize),
},
hir_def::layout::IntegerType::Fixed(size, is_signed) => match is_signed {
true => chalk_ir::Scalar::Int(match size {
hir_def::layout::Integer::I8 => chalk_ir::IntTy::I8,
hir_def::layout::Integer::I16 => chalk_ir::IntTy::I16,
hir_def::layout::Integer::I32 => chalk_ir::IntTy::I32,
hir_def::layout::Integer::I64 => chalk_ir::IntTy::I64,
hir_def::layout::Integer::I128 => chalk_ir::IntTy::I128,
}),
false => chalk_ir::Scalar::Uint(match size {
hir_def::layout::Integer::I8 => chalk_ir::UintTy::U8,
hir_def::layout::Integer::I16 => chalk_ir::UintTy::U16,
hir_def::layout::Integer::I32 => chalk_ir::UintTy::U32,
hir_def::layout::Integer::I64 => chalk_ir::UintTy::U64,
hir_def::layout::Integer::I128 => chalk_ir::UintTy::U128,
}),
},
})
.intern(Interner);
}
}
chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::U8)).intern(Interner)
}
fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> {
self.db.impl_datum(self.krate, impl_id)

View file

@ -464,3 +464,41 @@ fn enums_with_discriminants() {
}
}
}
#[test]
fn core_mem_discriminant() {
size_and_align! {
minicore: discriminant;
struct S(i32, u64);
struct Goal(core::mem::Discriminant<S>);
}
size_and_align! {
minicore: discriminant;
#[repr(u32)]
enum S {
A,
B,
C,
}
struct Goal(core::mem::Discriminant<S>);
}
size_and_align! {
minicore: discriminant;
enum S {
A(i32),
B(i64),
C(u8),
}
struct Goal(core::mem::Discriminant<S>);
}
size_and_align! {
minicore: discriminant;
#[repr(C, u16)]
enum S {
A(i32),
B(i64) = 200,
C = 1000,
}
struct Goal(core::mem::Discriminant<S>);
}
}

View file

@ -474,7 +474,7 @@ fn main() {
file_id: FileId(
1,
),
range: 9288..9296,
range: 9289..9297,
},
),
tooltip: "",
@ -487,7 +487,7 @@ fn main() {
file_id: FileId(
1,
),
range: 9320..9324,
range: 9321..9325,
},
),
tooltip: "",
@ -511,7 +511,7 @@ fn main() {
file_id: FileId(
1,
),
range: 9288..9296,
range: 9289..9297,
},
),
tooltip: "",
@ -524,7 +524,7 @@ fn main() {
file_id: FileId(
1,
),
range: 9320..9324,
range: 9321..9325,
},
),
tooltip: "",
@ -548,7 +548,7 @@ fn main() {
file_id: FileId(
1,
),
range: 9288..9296,
range: 9289..9297,
},
),
tooltip: "",
@ -561,7 +561,7 @@ fn main() {
file_id: FileId(
1,
),
range: 9320..9324,
range: 9321..9325,
},
),
tooltip: "",

View file

@ -364,6 +364,11 @@ pub mod mem {
pub fn size_of<T>() -> usize;
}
// endregion:size_of
// region:discriminant
use crate::marker::DiscriminantKind;
pub struct Discriminant<T>(<T as DiscriminantKind>::Discriminant);
// endregion:discriminant
}
pub mod ptr {