mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-14 22:24:14 +00:00
Give real discriminant_type to chalk
This commit is contained in:
parent
5208bf8f55
commit
50559118fb
6 changed files with 135 additions and 24 deletions
|
@ -416,6 +416,44 @@ fn test_hash_expand() {
|
||||||
//- minicore: derive, hash
|
//- minicore: derive, hash
|
||||||
use core::hash::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)]
|
#[derive(Hash)]
|
||||||
enum Command {
|
enum Command {
|
||||||
Move { x: i32, y: i32 },
|
Move { x: i32, y: i32 },
|
||||||
|
|
|
@ -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! {
|
quote! {
|
||||||
fn hash<H: #krate::hash::Hasher>(&self, ra_expand_state: &mut H) {
|
fn hash<H: #krate::hash::Hasher>(&self, ra_expand_state: &mut H) {
|
||||||
#krate::mem::discriminant(self).hash(ra_expand_state);
|
#check_discriminant
|
||||||
match self {
|
match self {
|
||||||
##arms
|
##arms
|
||||||
}
|
}
|
||||||
|
@ -742,9 +747,6 @@ fn ord_expand(
|
||||||
// FIXME: Return expand error here
|
// FIXME: Return expand error here
|
||||||
return quote!();
|
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 (self_patterns, other_patterns) = self_and_other_patterns(adt, &adt.name);
|
||||||
let arms = izip!(self_patterns, other_patterns, adt.shape.field_names()).map(
|
let arms = izip!(self_patterns, other_patterns, adt.shape.field_names()).map(
|
||||||
|(pat1, pat2, fields)| {
|
|(pat1, pat2, fields)| {
|
||||||
|
@ -759,17 +761,17 @@ fn ord_expand(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let fat_arrow = fat_arrow();
|
let fat_arrow = fat_arrow();
|
||||||
let body = compare(
|
let mut body = quote! {
|
||||||
krate,
|
match (self, other) {
|
||||||
left,
|
##arms
|
||||||
right,
|
_unused #fat_arrow #krate::cmp::Ordering::Equal
|
||||||
quote! {
|
}
|
||||||
match (self, other) {
|
};
|
||||||
##arms
|
if matches!(&adt.shape, AdtShape::Enum { .. }) {
|
||||||
_unused #fat_arrow #krate::cmp::Ordering::Equal
|
let left = quote!(#krate::intrinsics::discriminant_value(self));
|
||||||
}
|
let right = quote!(#krate::intrinsics::discriminant_value(other));
|
||||||
},
|
body = compare(krate, left, right, body);
|
||||||
);
|
}
|
||||||
quote! {
|
quote! {
|
||||||
fn cmp(&self, other: &Self) -> #krate::cmp::Ordering {
|
fn cmp(&self, other: &Self) -> #krate::cmp::Ordering {
|
||||||
#body
|
#body
|
||||||
|
|
|
@ -60,9 +60,37 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
|
||||||
// FIXME: keep track of these
|
// FIXME: keep track of these
|
||||||
Arc::new(rust_ir::AdtRepr { c: false, packed: false, int: None })
|
Arc::new(rust_ir::AdtRepr { c: false, packed: false, int: None })
|
||||||
}
|
}
|
||||||
fn discriminant_type(&self, _ty: chalk_ir::Ty<Interner>) -> chalk_ir::Ty<Interner> {
|
fn discriminant_type(&self, ty: chalk_ir::Ty<Interner>) -> chalk_ir::Ty<Interner> {
|
||||||
// FIXME: keep track of this
|
if let chalk_ir::TyKind::Adt(id, _) = ty.kind(Interner) {
|
||||||
chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::U32)).intern(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> {
|
fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> {
|
||||||
self.db.impl_datum(self.krate, impl_id)
|
self.db.impl_datum(self.krate, impl_id)
|
||||||
|
|
|
@ -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>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -474,7 +474,7 @@ fn main() {
|
||||||
file_id: FileId(
|
file_id: FileId(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
range: 9288..9296,
|
range: 9289..9297,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
|
@ -487,7 +487,7 @@ fn main() {
|
||||||
file_id: FileId(
|
file_id: FileId(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
range: 9320..9324,
|
range: 9321..9325,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
|
@ -511,7 +511,7 @@ fn main() {
|
||||||
file_id: FileId(
|
file_id: FileId(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
range: 9288..9296,
|
range: 9289..9297,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
|
@ -524,7 +524,7 @@ fn main() {
|
||||||
file_id: FileId(
|
file_id: FileId(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
range: 9320..9324,
|
range: 9321..9325,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
|
@ -548,7 +548,7 @@ fn main() {
|
||||||
file_id: FileId(
|
file_id: FileId(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
range: 9288..9296,
|
range: 9289..9297,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
|
@ -561,7 +561,7 @@ fn main() {
|
||||||
file_id: FileId(
|
file_id: FileId(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
range: 9320..9324,
|
range: 9321..9325,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
|
|
|
@ -364,6 +364,11 @@ pub mod mem {
|
||||||
pub fn size_of<T>() -> usize;
|
pub fn size_of<T>() -> usize;
|
||||||
}
|
}
|
||||||
// endregion:size_of
|
// endregion:size_of
|
||||||
|
|
||||||
|
// region:discriminant
|
||||||
|
use crate::marker::DiscriminantKind;
|
||||||
|
pub struct Discriminant<T>(<T as DiscriminantKind>::Discriminant);
|
||||||
|
// endregion:discriminant
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod ptr {
|
pub mod ptr {
|
||||||
|
|
Loading…
Reference in a new issue