Skip to content

Commit 5055911

Browse files
committed
Give real discriminant_type to chalk
1 parent 5208bf8 commit 5055911

File tree

6 files changed

+135
-24
lines changed

6 files changed

+135
-24
lines changed

crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,44 @@ fn test_hash_expand() {
416416
//- minicore: derive, hash
417417
use core::hash::Hash;
418418
419+
#[derive(Hash)]
420+
struct Foo {
421+
x: i32,
422+
y: u64,
423+
z: (i32, u64),
424+
}
425+
"#,
426+
expect![[r#"
427+
use core::hash::Hash;
428+
429+
#[derive(Hash)]
430+
struct Foo {
431+
x: i32,
432+
y: u64,
433+
z: (i32, u64),
434+
}
435+
436+
impl < > core::hash::Hash for Foo< > where {
437+
fn hash<H: core::hash::Hasher>(&self , ra_expand_state: &mut H) {
438+
match self {
439+
Foo {
440+
x: x, y: y, z: z,
441+
}
442+
=> {
443+
x.hash(ra_expand_state);
444+
y.hash(ra_expand_state);
445+
z.hash(ra_expand_state);
446+
}
447+
,
448+
}
449+
}
450+
}"#]],
451+
);
452+
check(
453+
r#"
454+
//- minicore: derive, hash
455+
use core::hash::Hash;
456+
419457
#[derive(Hash)]
420458
enum Command {
421459
Move { x: i32, y: i32 },

crates/hir-expand/src/builtin_derive_macro.rs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -624,9 +624,14 @@ fn hash_expand(
624624
}
625625
},
626626
);
627+
let check_discriminant = if matches!(&adt.shape, AdtShape::Enum { .. }) {
628+
quote! { #krate::mem::discriminant(self).hash(ra_expand_state); }
629+
} else {
630+
quote! {}
631+
};
627632
quote! {
628633
fn hash<H: #krate::hash::Hasher>(&self, ra_expand_state: &mut H) {
629-
#krate::mem::discriminant(self).hash(ra_expand_state);
634+
#check_discriminant
630635
match self {
631636
##arms
632637
}
@@ -742,9 +747,6 @@ fn ord_expand(
742747
// FIXME: Return expand error here
743748
return quote!();
744749
}
745-
let left = quote!(#krate::intrinsics::discriminant_value(self));
746-
let right = quote!(#krate::intrinsics::discriminant_value(other));
747-
748750
let (self_patterns, other_patterns) = self_and_other_patterns(adt, &adt.name);
749751
let arms = izip!(self_patterns, other_patterns, adt.shape.field_names()).map(
750752
|(pat1, pat2, fields)| {
@@ -759,17 +761,17 @@ fn ord_expand(
759761
},
760762
);
761763
let fat_arrow = fat_arrow();
762-
let body = compare(
763-
krate,
764-
left,
765-
right,
766-
quote! {
767-
match (self, other) {
768-
##arms
769-
_unused #fat_arrow #krate::cmp::Ordering::Equal
770-
}
771-
},
772-
);
764+
let mut body = quote! {
765+
match (self, other) {
766+
##arms
767+
_unused #fat_arrow #krate::cmp::Ordering::Equal
768+
}
769+
};
770+
if matches!(&adt.shape, AdtShape::Enum { .. }) {
771+
let left = quote!(#krate::intrinsics::discriminant_value(self));
772+
let right = quote!(#krate::intrinsics::discriminant_value(other));
773+
body = compare(krate, left, right, body);
774+
}
773775
quote! {
774776
fn cmp(&self, other: &Self) -> #krate::cmp::Ordering {
775777
#body

crates/hir-ty/src/chalk_db.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,37 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
6060
// FIXME: keep track of these
6161
Arc::new(rust_ir::AdtRepr { c: false, packed: false, int: None })
6262
}
63-
fn discriminant_type(&self, _ty: chalk_ir::Ty<Interner>) -> chalk_ir::Ty<Interner> {
64-
// FIXME: keep track of this
65-
chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::U32)).intern(Interner)
63+
fn discriminant_type(&self, ty: chalk_ir::Ty<Interner>) -> chalk_ir::Ty<Interner> {
64+
if let chalk_ir::TyKind::Adt(id, _) = ty.kind(Interner) {
65+
if let hir_def::AdtId::EnumId(e) = id.0 {
66+
let enum_data = self.db.enum_data(e);
67+
let ty = enum_data.repr.unwrap_or_default().discr_type();
68+
return chalk_ir::TyKind::Scalar(match ty {
69+
hir_def::layout::IntegerType::Pointer(is_signed) => match is_signed {
70+
true => chalk_ir::Scalar::Int(chalk_ir::IntTy::Isize),
71+
false => chalk_ir::Scalar::Uint(chalk_ir::UintTy::Usize),
72+
},
73+
hir_def::layout::IntegerType::Fixed(size, is_signed) => match is_signed {
74+
true => chalk_ir::Scalar::Int(match size {
75+
hir_def::layout::Integer::I8 => chalk_ir::IntTy::I8,
76+
hir_def::layout::Integer::I16 => chalk_ir::IntTy::I16,
77+
hir_def::layout::Integer::I32 => chalk_ir::IntTy::I32,
78+
hir_def::layout::Integer::I64 => chalk_ir::IntTy::I64,
79+
hir_def::layout::Integer::I128 => chalk_ir::IntTy::I128,
80+
}),
81+
false => chalk_ir::Scalar::Uint(match size {
82+
hir_def::layout::Integer::I8 => chalk_ir::UintTy::U8,
83+
hir_def::layout::Integer::I16 => chalk_ir::UintTy::U16,
84+
hir_def::layout::Integer::I32 => chalk_ir::UintTy::U32,
85+
hir_def::layout::Integer::I64 => chalk_ir::UintTy::U64,
86+
hir_def::layout::Integer::I128 => chalk_ir::UintTy::U128,
87+
}),
88+
},
89+
})
90+
.intern(Interner);
91+
}
92+
}
93+
chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::U8)).intern(Interner)
6694
}
6795
fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> {
6896
self.db.impl_datum(self.krate, impl_id)

crates/hir-ty/src/layout/tests.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,3 +464,41 @@ fn enums_with_discriminants() {
464464
}
465465
}
466466
}
467+
468+
#[test]
469+
fn core_mem_discriminant() {
470+
size_and_align! {
471+
minicore: discriminant;
472+
struct S(i32, u64);
473+
struct Goal(core::mem::Discriminant<S>);
474+
}
475+
size_and_align! {
476+
minicore: discriminant;
477+
#[repr(u32)]
478+
enum S {
479+
A,
480+
B,
481+
C,
482+
}
483+
struct Goal(core::mem::Discriminant<S>);
484+
}
485+
size_and_align! {
486+
minicore: discriminant;
487+
enum S {
488+
A(i32),
489+
B(i64),
490+
C(u8),
491+
}
492+
struct Goal(core::mem::Discriminant<S>);
493+
}
494+
size_and_align! {
495+
minicore: discriminant;
496+
#[repr(C, u16)]
497+
enum S {
498+
A(i32),
499+
B(i64) = 200,
500+
C = 1000,
501+
}
502+
struct Goal(core::mem::Discriminant<S>);
503+
}
504+
}

crates/ide/src/inlay_hints/chaining.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ fn main() {
474474
file_id: FileId(
475475
1,
476476
),
477-
range: 9288..9296,
477+
range: 9289..9297,
478478
},
479479
),
480480
tooltip: "",
@@ -487,7 +487,7 @@ fn main() {
487487
file_id: FileId(
488488
1,
489489
),
490-
range: 9320..9324,
490+
range: 9321..9325,
491491
},
492492
),
493493
tooltip: "",
@@ -511,7 +511,7 @@ fn main() {
511511
file_id: FileId(
512512
1,
513513
),
514-
range: 9288..9296,
514+
range: 9289..9297,
515515
},
516516
),
517517
tooltip: "",
@@ -524,7 +524,7 @@ fn main() {
524524
file_id: FileId(
525525
1,
526526
),
527-
range: 9320..9324,
527+
range: 9321..9325,
528528
},
529529
),
530530
tooltip: "",
@@ -548,7 +548,7 @@ fn main() {
548548
file_id: FileId(
549549
1,
550550
),
551-
range: 9288..9296,
551+
range: 9289..9297,
552552
},
553553
),
554554
tooltip: "",
@@ -561,7 +561,7 @@ fn main() {
561561
file_id: FileId(
562562
1,
563563
),
564-
range: 9320..9324,
564+
range: 9321..9325,
565565
},
566566
),
567567
tooltip: "",

crates/test-utils/src/minicore.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,11 @@ pub mod mem {
364364
pub fn size_of<T>() -> usize;
365365
}
366366
// endregion:size_of
367+
368+
// region:discriminant
369+
use crate::marker::DiscriminantKind;
370+
pub struct Discriminant<T>(<T as DiscriminantKind>::Discriminant);
371+
// endregion:discriminant
367372
}
368373

369374
pub mod ptr {

0 commit comments

Comments
 (0)