Skip to content

Commit e966087

Browse files
committed
Add parsing for scalar types and tuples
1 parent 3400b1a commit e966087

File tree

14 files changed

+355
-182
lines changed

14 files changed

+355
-182
lines changed

chalk-integration/src/lowering.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,6 +1074,17 @@ impl LowerTy for Ty {
10741074
};
10751075
Ok(chalk_ir::TyData::Function(function).intern(interner))
10761076
}
1077+
Ty::Tuple { arity } => Ok(chalk_ir::TyData::Apply(chalk_ir::ApplicationTy {
1078+
name: chalk_ir::TypeName::Tuple(arity),
1079+
substitution: chalk_ir::Substitution::empty(interner),
1080+
})
1081+
.intern(interner)),
1082+
1083+
Ty::Scalar { ty } => Ok(chalk_ir::TyData::Apply(chalk_ir::ApplicationTy {
1084+
name: chalk_ir::TypeName::Scalar(ast_scalar_to_chalk_scalar(ty)),
1085+
substitution: chalk_ir::Substitution::empty(interner),
1086+
})
1087+
.intern(interner)),
10771088
}
10781089
}
10791090
}
@@ -1420,3 +1431,30 @@ impl Kinded for chalk_ir::Parameter<ChalkIr> {
14201431
self.data(interner).kind()
14211432
}
14221433
}
1434+
1435+
fn ast_scalar_to_chalk_scalar(scalar: ScalarType) -> chalk_ir::Scalar {
1436+
match scalar {
1437+
ScalarType::Int(int) => chalk_ir::Scalar::Int(match int {
1438+
IntTy::I8 => chalk_ir::IntTy::I8,
1439+
IntTy::I16 => chalk_ir::IntTy::I16,
1440+
IntTy::I32 => chalk_ir::IntTy::I32,
1441+
IntTy::I64 => chalk_ir::IntTy::I64,
1442+
IntTy::I128 => chalk_ir::IntTy::I128,
1443+
IntTy::Isize => chalk_ir::IntTy::Isize,
1444+
}),
1445+
ScalarType::Uint(uint) => chalk_ir::Scalar::Uint(match uint {
1446+
UintTy::U8 => chalk_ir::UintTy::U8,
1447+
UintTy::U16 => chalk_ir::UintTy::U16,
1448+
UintTy::U32 => chalk_ir::UintTy::U32,
1449+
UintTy::U64 => chalk_ir::UintTy::U64,
1450+
UintTy::U128 => chalk_ir::UintTy::U128,
1451+
UintTy::Usize => chalk_ir::UintTy::Usize,
1452+
}),
1453+
ScalarType::Float(float) => chalk_ir::Scalar::Float(match float {
1454+
FloatTy::F32 => chalk_ir::FloatTy::F32,
1455+
FloatTy::F64 => chalk_ir::FloatTy::F64,
1456+
}),
1457+
ScalarType::Bool => chalk_ir::Scalar::Bool,
1458+
ScalarType::Char => chalk_ir::Scalar::Char,
1459+
}
1460+
}

chalk-parse/src/ast.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,47 @@ pub enum Ty {
175175
lifetime_names: Vec<Identifier>,
176176
ty: Box<Ty>,
177177
},
178+
Tuple {
179+
arity: usize,
180+
},
181+
Scalar {
182+
ty: ScalarType,
183+
},
184+
}
185+
186+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
187+
pub enum IntTy {
188+
Isize,
189+
I8,
190+
I16,
191+
I32,
192+
I64,
193+
I128,
194+
}
195+
196+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
197+
pub enum UintTy {
198+
Usize,
199+
U8,
200+
U16,
201+
U32,
202+
U64,
203+
U128,
204+
}
205+
206+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
207+
pub enum FloatTy {
208+
F32,
209+
F64,
210+
}
211+
212+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
213+
pub enum ScalarType {
214+
Bool,
215+
Char,
216+
Int(IntTy),
217+
Uint(UintTy),
218+
Float(FloatTy),
178219
}
179220

180221
#[derive(Copy, Clone, PartialEq, Eq, Debug)]

chalk-parse/src/parser.lalrpop

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ pub Ty: Ty = {
178178
};
179179

180180
TyWithoutFor: Ty = {
181+
<ScalarType> => Ty::Scalar { ty: <> },
181182
<n:Id> => Ty::Id { name: n},
182183
"fn" "(" <t:Ty> ")" => Ty::ForAll {
183184
lifetime_names: vec![],
@@ -188,7 +189,33 @@ TyWithoutFor: Ty = {
188189
},
189190
<n:Id> "<" <a:Comma<Parameter>> ">" => Ty::Apply { name: n, args: a },
190191
<a:AliasTy> => Ty::Alias { alias: a },
191-
"(" <Ty> ")",
192+
"(" <t:TupleOrParensInner> ")" => t,
193+
};
194+
195+
ScalarType: ScalarType = {
196+
"u8" => ScalarType::Uint(UintTy::U8),
197+
"u16" => ScalarType::Uint(UintTy::U16),
198+
"u32" => ScalarType::Uint(UintTy::U32),
199+
"u64" => ScalarType::Uint(UintTy::U64),
200+
"u128" => ScalarType::Uint(UintTy::U128),
201+
"usize" => ScalarType::Uint(UintTy::Usize),
202+
"i8" => ScalarType::Int(IntTy::I8),
203+
"i16" => ScalarType::Int(IntTy::I16),
204+
"i32" => ScalarType::Int(IntTy::I32),
205+
"i64" => ScalarType::Int(IntTy::I64),
206+
"i128" => ScalarType::Int(IntTy::I128),
207+
"isize" => ScalarType::Int(IntTy::Isize),
208+
"f32" => ScalarType::Float(FloatTy::F32),
209+
"f64" => ScalarType::Float(FloatTy::F64),
210+
"bool" => ScalarType::Bool,
211+
"char" => ScalarType::Char,
212+
};
213+
214+
TupleOrParensInner: Ty = {
215+
<l:Comma2<Ty>> => Ty::Tuple { arity: l.len() },
216+
<Ty> "," => Ty::Tuple { arity: 1 },
217+
<Ty>,
218+
() => Ty::Tuple { arity: 0 },
192219
};
193220

194221
Lifetime: Lifetime = {
@@ -343,11 +370,26 @@ Separator1<S, T>: Vec<T> = {
343370
}
344371
};
345372

373+
Separator2<S, T>: Vec<T> = {
374+
<t1:T> S <t2:T> => vec![t1, t2],
375+
<t1:T> S <t2:T> S <v:Separator<S, T>> => {
376+
let mut v = v;
377+
v.push(t1);
378+
v.push(t2);
379+
v
380+
}
381+
};
382+
346383
#[inline]
347384
Comma<T>: Vec<T> = {
348385
<Separator<",", T>>
349386
};
350387

388+
#[inline]
389+
Comma2<T>: Vec<T> = {
390+
<Separator2<",", T>>
391+
};
392+
351393
#[inline]
352394
SemiColon<T>: Vec<T> = {
353395
<Separator<";", T>>

chalk-solve/src/clauses.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,8 @@ fn match_type_name<I: Interner>(builder: &mut ClauseBuilder<'_, I>, name: TypeNa
381381
.db
382382
.associated_ty_data(type_id)
383383
.to_program_clauses(builder),
384-
TypeName::Scalar(_) => todo!("Scalar match type name"),
385-
TypeName::Tuple(_) => todo!("Tuple match type name"),
384+
TypeName::Scalar(_) => (),
385+
TypeName::Tuple(_) => (),
386386
}
387387
}
388388

tests/lowering/mod.rs

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@ fn negative_impl() {
7474
type Item;
7575
}
7676

77-
struct i32 { }
78-
7977
impl !Foo for i32 {
8078
type Item = i32;
8179
}
@@ -93,8 +91,6 @@ fn negative_impl() {
9391
type Item;
9492
}
9593

96-
struct i32 { }
97-
9894
impl<T> !Foo for T where T: Iterator<Item = i32> { }
9995
}
10096
}
@@ -229,9 +225,9 @@ fn check_parameter_kinds() {
229225
lowering_error! {
230226
program {
231227
struct Foo<'a> { }
232-
struct i32 { }
228+
struct Myi32 { }
233229
trait Bar { }
234-
impl Bar for Foo<i32> { }
230+
impl Bar for Foo<Myi32> { }
235231
}
236232
error_msg {
237233
"incorrect parameter kind for `Foo`: expected lifetime, found type"
@@ -425,3 +421,58 @@ fn fundamental_multiple_type_parameters() {
425421
}
426422
}
427423
}
424+
425+
#[test]
426+
fn tuples() {
427+
lowering_success! {
428+
program {
429+
trait Foo { }
430+
431+
// `()` is an empty tuple
432+
impl Foo for () { }
433+
// `(i32,)` is a tuple
434+
impl Foo for (i32,) { }
435+
// `(i32)` is `i32` is a scalar
436+
impl Foo for (i32) { }
437+
impl Foo for (i32, u32) { }
438+
impl Foo for (i32, u32, f32) { }
439+
}
440+
}
441+
}
442+
443+
#[test]
444+
fn scalars() {
445+
lowering_success! {
446+
program {
447+
trait Foo { }
448+
449+
impl Foo for i8 { }
450+
impl Foo for i16 { }
451+
impl Foo for i32 { }
452+
impl Foo for i64 { }
453+
impl Foo for i128 { }
454+
impl Foo for isize { }
455+
impl Foo for u8 { }
456+
impl Foo for u16 { }
457+
impl Foo for u32 { }
458+
impl Foo for u64 { }
459+
impl Foo for u128 { }
460+
impl Foo for usize { }
461+
impl Foo for f32 { }
462+
impl Foo for f64 { }
463+
impl Foo for bool { }
464+
impl Foo for char { }
465+
}
466+
}
467+
468+
lowering_error! {
469+
program {
470+
struct i32 { }
471+
}
472+
473+
// TODO: improve this error message
474+
error_msg {
475+
"parse error: UnrecognizedToken { token: (8, Token(45, \"i32\"), 11), expected: [\"r#\\\"([A-Za-z]|_)([A-Za-z0-9]|_)*\\\"#\"] }"
476+
}
477+
}
478+
}

tests/test/auto_traits.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fn auto_semantics() {
88
program {
99
#[auto] trait Send { }
1010

11-
struct i32 { }
11+
struct TypeA { }
1212

1313
struct Ptr<T> { }
1414
impl<T> Send for Ptr<T> where T: Send { }
@@ -37,7 +37,7 @@ fn auto_semantics() {
3737
}
3838

3939
goal {
40-
List<i32>: Send
40+
List<TypeA>: Send
4141
} yields {
4242
"Unique"
4343
}
@@ -58,7 +58,7 @@ fn auto_trait_without_impls() {
5858
program {
5959
#[auto] trait Send { }
6060

61-
struct i32 { }
61+
struct TypeA { }
6262

6363
struct Useless<T> { }
6464

@@ -68,7 +68,7 @@ fn auto_trait_without_impls() {
6868
}
6969

7070
goal {
71-
i32: Send
71+
TypeA: Send
7272
} yields {
7373
"Unique"
7474
}
@@ -100,34 +100,34 @@ fn auto_trait_with_impls() {
100100
program {
101101
#[auto] trait Send { }
102102

103-
struct i32 { }
104-
struct f32 { }
103+
struct TypeA { }
104+
struct TypeB { }
105105
struct Vec<T> { }
106106

107107
impl<T> Send for Vec<T> where T: Send { }
108-
impl !Send for i32 { }
108+
impl !Send for TypeA { }
109109
}
110110

111111
goal {
112-
i32: Send
112+
TypeA: Send
113113
} yields {
114114
"No possible solution"
115115
}
116116

117117
goal {
118-
f32: Send
118+
TypeB: Send
119119
} yields {
120120
"Unique"
121121
}
122122

123123
goal {
124-
Vec<i32>: Send
124+
Vec<TypeA>: Send
125125
} yields {
126126
"No possible solution"
127127
}
128128

129129
goal {
130-
Vec<f32>: Send
130+
Vec<TypeB>: Send
131131
} yields {
132132
"Unique"
133133
}

0 commit comments

Comments
 (0)