Skip to content

Commit 8122127

Browse files
committed
Auto merge of #633 - Areredify:discriminant_kind, r=nikomatsakis
Add `DiscriminantKind` builtin trait
2 parents 40c4789 + fc05789 commit 8122127

File tree

18 files changed

+447
-81
lines changed

18 files changed

+447
-81
lines changed

chalk-integration/src/db.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ impl RustIrDatabase<ChalkIr> for ChalkDatabase {
129129
self.program_ir().unwrap().generator_witness_datum(id)
130130
}
131131

132-
fn adt_repr(&self, id: AdtId<ChalkIr>) -> AdtRepr {
132+
fn adt_repr(&self, id: AdtId<ChalkIr>) -> Arc<AdtRepr<ChalkIr>> {
133133
self.program_ir().unwrap().adt_repr(id)
134134
}
135135

@@ -242,6 +242,10 @@ impl RustIrDatabase<ChalkIr> for ChalkDatabase {
242242
fn fn_def_name(&self, fn_def_id: FnDefId<ChalkIr>) -> String {
243243
self.program_ir().unwrap().fn_def_name(fn_def_id)
244244
}
245+
246+
fn discriminant_type(&self, ty: Ty<ChalkIr>) -> Ty<ChalkIr> {
247+
self.program_ir().unwrap().discriminant_type(ty)
248+
}
245249
}
246250

247251
impl fmt::Debug for ChalkDatabase {

chalk-integration/src/lowering.rs

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -321,14 +321,15 @@ impl LowerWithEnv for (&AdtDefn, chalk_ir::AdtId<ChalkIr>) {
321321
}
322322
}
323323

324-
impl Lower for AdtRepr {
325-
type Lowered = rust_ir::AdtRepr;
324+
impl LowerWithEnv for AdtRepr {
325+
type Lowered = rust_ir::AdtRepr<ChalkIr>;
326326

327-
fn lower(&self) -> Self::Lowered {
328-
rust_ir::AdtRepr {
329-
repr_c: self.repr_c,
330-
repr_packed: self.repr_packed,
331-
}
327+
fn lower(&self, env: &Env) -> LowerResult<Self::Lowered> {
328+
Ok(rust_ir::AdtRepr {
329+
c: self.c,
330+
packed: self.packed,
331+
int: self.int.as_ref().map(|i| i.lower(env)).transpose()?,
332+
})
332333
}
333334
}
334335

@@ -1131,6 +1132,7 @@ impl Lower for WellKnownTrait {
11311132
WellKnownTrait::Unsize => rust_ir::WellKnownTrait::Unsize,
11321133
WellKnownTrait::Unpin => rust_ir::WellKnownTrait::Unpin,
11331134
WellKnownTrait::CoerceUnsized => rust_ir::WellKnownTrait::CoerceUnsized,
1135+
WellKnownTrait::DiscriminantKind => rust_ir::WellKnownTrait::DiscriminantKind,
11341136
}
11351137
}
11361138
}
@@ -1160,31 +1162,55 @@ impl Kinded for chalk_ir::GenericArg<ChalkIr> {
11601162
}
11611163
}
11621164

1165+
impl Lower for IntTy {
1166+
type Lowered = chalk_ir::IntTy;
1167+
1168+
fn lower(&self) -> Self::Lowered {
1169+
match self {
1170+
IntTy::I8 => chalk_ir::IntTy::I8,
1171+
IntTy::I16 => chalk_ir::IntTy::I16,
1172+
IntTy::I32 => chalk_ir::IntTy::I32,
1173+
IntTy::I64 => chalk_ir::IntTy::I64,
1174+
IntTy::I128 => chalk_ir::IntTy::I128,
1175+
IntTy::Isize => chalk_ir::IntTy::Isize,
1176+
}
1177+
}
1178+
}
1179+
1180+
impl Lower for UintTy {
1181+
type Lowered = chalk_ir::UintTy;
1182+
1183+
fn lower(&self) -> Self::Lowered {
1184+
match self {
1185+
UintTy::U8 => chalk_ir::UintTy::U8,
1186+
UintTy::U16 => chalk_ir::UintTy::U16,
1187+
UintTy::U32 => chalk_ir::UintTy::U32,
1188+
UintTy::U64 => chalk_ir::UintTy::U64,
1189+
UintTy::U128 => chalk_ir::UintTy::U128,
1190+
UintTy::Usize => chalk_ir::UintTy::Usize,
1191+
}
1192+
}
1193+
}
1194+
1195+
impl Lower for FloatTy {
1196+
type Lowered = chalk_ir::FloatTy;
1197+
1198+
fn lower(&self) -> Self::Lowered {
1199+
match self {
1200+
FloatTy::F32 => chalk_ir::FloatTy::F32,
1201+
FloatTy::F64 => chalk_ir::FloatTy::F64,
1202+
}
1203+
}
1204+
}
1205+
11631206
impl Lower for ScalarType {
11641207
type Lowered = chalk_ir::Scalar;
11651208

11661209
fn lower(&self) -> Self::Lowered {
11671210
match self {
1168-
ScalarType::Int(int) => chalk_ir::Scalar::Int(match int {
1169-
IntTy::I8 => chalk_ir::IntTy::I8,
1170-
IntTy::I16 => chalk_ir::IntTy::I16,
1171-
IntTy::I32 => chalk_ir::IntTy::I32,
1172-
IntTy::I64 => chalk_ir::IntTy::I64,
1173-
IntTy::I128 => chalk_ir::IntTy::I128,
1174-
IntTy::Isize => chalk_ir::IntTy::Isize,
1175-
}),
1176-
ScalarType::Uint(uint) => chalk_ir::Scalar::Uint(match uint {
1177-
UintTy::U8 => chalk_ir::UintTy::U8,
1178-
UintTy::U16 => chalk_ir::UintTy::U16,
1179-
UintTy::U32 => chalk_ir::UintTy::U32,
1180-
UintTy::U64 => chalk_ir::UintTy::U64,
1181-
UintTy::U128 => chalk_ir::UintTy::U128,
1182-
UintTy::Usize => chalk_ir::UintTy::Usize,
1183-
}),
1184-
ScalarType::Float(float) => chalk_ir::Scalar::Float(match float {
1185-
FloatTy::F32 => chalk_ir::FloatTy::F32,
1186-
FloatTy::F64 => chalk_ir::FloatTy::F64,
1187-
}),
1211+
ScalarType::Int(int) => chalk_ir::Scalar::Int(int.lower()),
1212+
ScalarType::Uint(uint) => chalk_ir::Scalar::Uint(uint.lower()),
1213+
ScalarType::Float(float) => chalk_ir::Scalar::Float(float.lower()),
11881214
ScalarType::Bool => chalk_ir::Scalar::Bool,
11891215
ScalarType::Char => chalk_ir::Scalar::Char,
11901216
}

chalk-integration/src/lowering/program_lowerer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ impl ProgramLowerer {
185185
let identifier = d.name.clone();
186186
let adt_id = AdtId(raw_id);
187187
adt_data.insert(adt_id, Arc::new((d, adt_id).lower(&empty_env)?));
188-
adt_reprs.insert(adt_id, d.repr.lower());
188+
adt_reprs.insert(adt_id, Arc::new(d.repr.lower(&empty_env)?));
189189
let n_params = d.all_parameters().len();
190190
let variances = match d.variances.clone() {
191191
Some(v) => {

chalk-integration/src/program.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ use chalk_ir::{could_match::CouldMatch, UnificationDatabase};
44
use chalk_ir::{debug::Angle, Variance};
55
use chalk_ir::{
66
debug::SeparatorTraitRef, AdtId, AliasTy, AssocTypeId, Binders, CanonicalVarKinds, ClosureId,
7-
FnDefId, ForeignDefId, GeneratorId, GenericArg, Goal, Goals, ImplId, Lifetime, OpaqueTy,
8-
OpaqueTyId, ProgramClause, ProgramClauseImplication, ProgramClauses, ProjectionTy,
9-
Substitution, TraitId, Ty, TyKind, Variances,
7+
FnDefId, ForeignDefId, GeneratorId, GenericArg, Goal, Goals, ImplId, IntTy, Lifetime, OpaqueTy,
8+
OpaqueTyId, ProgramClause, ProgramClauseImplication, ProgramClauses, ProjectionTy, Scalar,
9+
Substitution, TraitId, Ty, TyKind, UintTy, Variances,
1010
};
1111
use chalk_solve::rust_ir::{
1212
AdtDatum, AdtRepr, AssociatedTyDatum, AssociatedTyValue, AssociatedTyValueId, ClosureKind,
@@ -59,7 +59,7 @@ pub struct Program {
5959
/// For each ADT:
6060
pub adt_data: BTreeMap<AdtId<ChalkIr>, Arc<AdtDatum<ChalkIr>>>,
6161

62-
pub adt_reprs: BTreeMap<AdtId<ChalkIr>, AdtRepr>,
62+
pub adt_reprs: BTreeMap<AdtId<ChalkIr>, Arc<AdtRepr<ChalkIr>>>,
6363

6464
pub fn_def_data: BTreeMap<FnDefId<ChalkIr>, Arc<FnDefDatum<ChalkIr>>>,
6565

@@ -426,8 +426,8 @@ impl RustIrDatabase<ChalkIr> for Program {
426426
self.generator_witness_data[&id].clone()
427427
}
428428

429-
fn adt_repr(&self, id: AdtId<ChalkIr>) -> AdtRepr {
430-
self.adt_reprs[&id]
429+
fn adt_repr(&self, id: AdtId<ChalkIr>) -> Arc<AdtRepr<ChalkIr>> {
430+
self.adt_reprs[&id].clone()
431431
}
432432

433433
fn fn_def_datum(&self, id: FnDefId<ChalkIr>) -> Arc<FnDefDatum<ChalkIr>> {
@@ -589,4 +589,19 @@ impl RustIrDatabase<ChalkIr> for Program {
589589
.name
590590
.to_string()
591591
}
592+
593+
// Mirrors current (07a63e6d1fabf3560e8e1e17c1d56b10a06152d9) implementation in rustc
594+
fn discriminant_type(&self, ty: Ty<ChalkIr>) -> Ty<ChalkIr> {
595+
let interner = self.interner();
596+
match ty.data(interner).kind {
597+
TyKind::Adt(id, _) => {
598+
let repr = self.adt_repr(id);
599+
repr.int
600+
.clone()
601+
.unwrap_or(TyKind::Scalar(Scalar::Int(IntTy::Isize)).intern(interner))
602+
}
603+
TyKind::Generator(..) => TyKind::Scalar(Scalar::Uint(UintTy::U32)).intern(interner),
604+
_ => TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(interner),
605+
}
606+
}
592607
}

chalk-parse/src/ast.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,18 @@ pub enum AdtKind {
7878
Union,
7979
}
8080

81+
#[derive(Clone, PartialEq, Eq, Debug)]
82+
pub enum AdtReprAttr {
83+
C,
84+
Packed,
85+
Int(Ty),
86+
}
87+
8188
#[derive(Clone, PartialEq, Eq, Debug)]
8289
pub struct AdtRepr {
83-
pub repr_c: bool,
84-
pub repr_packed: bool,
90+
pub c: bool,
91+
pub packed: bool,
92+
pub int: Option<Ty>,
8593
}
8694

8795
#[derive(Clone, PartialEq, Eq, Debug)]
@@ -143,6 +151,7 @@ pub enum WellKnownTrait {
143151
Unsize,
144152
Unpin,
145153
CoerceUnsized,
154+
DiscriminantKind,
146155
}
147156

148157
#[derive(Clone, PartialEq, Eq, Debug)]

chalk-parse/src/parser.lalrpop

Lines changed: 60 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,31 @@ WellKnownTrait: WellKnownTrait = {
6565
"#" "[" "lang" "(" "unsize" ")" "]" => WellKnownTrait::Unsize,
6666
"#" "[" "lang" "(" "unpin" ")" "]" => WellKnownTrait::Unpin,
6767
"#" "[" "lang" "(" "coerce_unsized" ")" "]" => WellKnownTrait::CoerceUnsized,
68+
"#" "[" "lang" "(" "discriminant_kind" ")" "]" => WellKnownTrait::DiscriminantKind,
6869
};
6970

70-
AdtRepr: Atom = "#" "[" "repr" "(" <name:Id> ")" "]" => name.str;
71+
AdtReprAttr: AdtReprAttr = {
72+
"#" "[" "repr" "(" <t:ReprIntTy> ")" "]" => AdtReprAttr::Int(t),
73+
"#" "[" "repr" "(" <attr:Id> ")" "]" =>? match &*attr.str {
74+
"C" => Ok(AdtReprAttr::C),
75+
"packed" => Ok(AdtReprAttr::Packed),
76+
_ => Err(lalrpop_util::ParseError::User {
77+
error: "unknown adt repr flag"
78+
})
79+
},
80+
};
81+
82+
ReprIntTy: Ty = {
83+
<i:IntTy> => Ty::Scalar {
84+
ty: ScalarType::Int(i),
85+
},
86+
<u:UintTy> => Ty::Scalar {
87+
ty: ScalarType::Uint(u),
88+
},
89+
}
7190

7291
AdtDefn: AdtDefn = {
73-
<variances:Variances?> <upstream:UpstreamKeyword?> <fundamental:FundamentalKeyword?> <phantom_data:PhantomDataKeyword?> <repr:AdtRepr*>
92+
<variances:Variances?> <upstream:UpstreamKeyword?> <fundamental:FundamentalKeyword?> <phantom_data:PhantomDataKeyword?> <repr:AdtReprAttr*>
7493
"enum" <n:Id><p:Angle<VariableKind>>
7594
<w:QuantifiedWhereClauses> "{" <v:Variants> "}" => AdtDefn
7695
{
@@ -85,12 +104,17 @@ AdtDefn: AdtDefn = {
85104
kind: AdtKind::Enum,
86105
},
87106
repr: AdtRepr {
88-
repr_c: repr.iter().any(|s| s == "C"),
89-
repr_packed: repr.iter().any(|s| s == "packed"),
107+
c: repr.iter().any(|s| s == &AdtReprAttr::C),
108+
packed: repr.iter().any(|s| s == &AdtReprAttr::Packed),
109+
int: repr.iter().find_map(|s| if let AdtReprAttr::Int(i) = s {
110+
Some(i.clone())
111+
} else {
112+
None
113+
})
90114
},
91115
variances,
92116
},
93-
<variances:Variances?> <upstream:UpstreamKeyword?> <fundamental:FundamentalKeyword?> <phantom_data:PhantomDataKeyword?> <repr:AdtRepr*>
117+
<variances:Variances?> <upstream:UpstreamKeyword?> <fundamental:FundamentalKeyword?> <phantom_data:PhantomDataKeyword?> <repr:AdtReprAttr*>
94118
"struct" <n:Id><p:Angle<VariableKind>>
95119
<w:QuantifiedWhereClauses> "{" <f:Fields> "}" => AdtDefn
96120
{
@@ -112,8 +136,9 @@ AdtDefn: AdtDefn = {
112136
kind: AdtKind::Struct,
113137
},
114138
repr: AdtRepr {
115-
repr_c: repr.iter().any(|s| s == "C"),
116-
repr_packed: repr.iter().any(|s| s == "packed"),
139+
c: repr.iter().any(|s| s == &AdtReprAttr::C),
140+
packed: repr.iter().any(|s| s == &AdtReprAttr::Packed),
141+
int: None
117142
},
118143
variances,
119144
}
@@ -405,23 +430,35 @@ TyWithoutId: Ty = {
405430
ExistsLifetimes: Vec<Identifier> = "exists" "<" <Comma<LifetimeId>> ">" => <>;
406431
ForLifetimes: Vec<Identifier> = "for" "<" <Comma<LifetimeId>> ">" => <>;
407432

433+
IntTy: IntTy = {
434+
"i8" => IntTy::I8,
435+
"i16" => IntTy::I16,
436+
"i32" => IntTy::I32,
437+
"i64" => IntTy::I64,
438+
"i128" => IntTy::I128,
439+
"isize" => IntTy::Isize,
440+
};
441+
442+
UintTy: UintTy = {
443+
"u8" => UintTy::U8,
444+
"u16" => UintTy::U16,
445+
"u32" => UintTy::U32,
446+
"u64" => UintTy::U64,
447+
"u128" => UintTy::U128,
448+
"usize" => UintTy::Usize,
449+
};
450+
451+
FloatTy: FloatTy = {
452+
"f32" => FloatTy::F32,
453+
"f64" => FloatTy::F64,
454+
};
455+
408456
ScalarType: ScalarType = {
409-
"u8" => ScalarType::Uint(UintTy::U8),
410-
"u16" => ScalarType::Uint(UintTy::U16),
411-
"u32" => ScalarType::Uint(UintTy::U32),
412-
"u64" => ScalarType::Uint(UintTy::U64),
413-
"u128" => ScalarType::Uint(UintTy::U128),
414-
"usize" => ScalarType::Uint(UintTy::Usize),
415-
"i8" => ScalarType::Int(IntTy::I8),
416-
"i16" => ScalarType::Int(IntTy::I16),
417-
"i32" => ScalarType::Int(IntTy::I32),
418-
"i64" => ScalarType::Int(IntTy::I64),
419-
"i128" => ScalarType::Int(IntTy::I128),
420-
"isize" => ScalarType::Int(IntTy::Isize),
421-
"f32" => ScalarType::Float(FloatTy::F32),
422-
"f64" => ScalarType::Float(FloatTy::F64),
423-
"bool" => ScalarType::Bool,
424-
"char" => ScalarType::Char,
457+
<i:IntTy> => ScalarType::Int(i),
458+
<u:UintTy> => ScalarType::Uint(u),
459+
<f:FloatTy> => ScalarType::Float(f),
460+
"bool" => ScalarType::Bool,
461+
"char" => ScalarType::Char,
425462
};
426463

427464
TupleOrParensInner: Ty = {

chalk-solve/src/clauses/builtin_traits.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use chalk_ir::{Floundered, Substitution, Ty};
44

55
mod clone;
66
mod copy;
7+
mod discriminant_kind;
78
mod fn_family;
89
mod sized;
910
mod unsize;
@@ -41,6 +42,8 @@ pub fn add_builtin_program_clauses<I: Interner>(
4142
WellKnownTrait::Unsize => {
4243
unsize::add_unsize_program_clauses(db, builder, trait_ref, ty)
4344
}
45+
// DiscriminantKind is automatically implemented for all types
46+
WellKnownTrait::DiscriminantKind => builder.push_fact(trait_ref),
4447
// There are no builtin impls provided for the following traits:
4548
WellKnownTrait::Unpin | WellKnownTrait::Drop | WellKnownTrait::CoerceUnsized => (),
4649
}
@@ -67,6 +70,9 @@ pub fn add_builtin_assoc_program_clauses<I: Interner>(
6770
Ok(())
6871
})
6972
}
73+
WellKnownTrait::DiscriminantKind => {
74+
discriminant_kind::add_discriminant_clauses(db, builder, self_ty)
75+
}
7076
_ => Ok(()),
7177
}
7278
}

0 commit comments

Comments
 (0)