Skip to content

Commit 2c94b0e

Browse files
authored
Merge pull request #394 from MarkMcCaskey/feature/add-scalar-to-typename
Add scalars to `TypeName`
2 parents 2c072cc + 8d09a2d commit 2c94b0e

23 files changed

+591
-203
lines changed

chalk-integration/src/lowering.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,6 +1188,20 @@ impl LowerTy for Ty {
11881188
};
11891189
Ok(chalk_ir::TyData::Function(function).intern(interner))
11901190
}
1191+
Ty::Tuple { ref types } => Ok(chalk_ir::TyData::Apply(chalk_ir::ApplicationTy {
1192+
name: chalk_ir::TypeName::Tuple(types.len()),
1193+
substitution: chalk_ir::Substitution::from_fallible(
1194+
interner,
1195+
types.iter().map(|t| Ok(t.lower(env)?)),
1196+
)?,
1197+
})
1198+
.intern(interner)),
1199+
1200+
Ty::Scalar { ty } => Ok(chalk_ir::TyData::Apply(chalk_ir::ApplicationTy {
1201+
name: chalk_ir::TypeName::Scalar(ast_scalar_to_chalk_scalar(ty)),
1202+
substitution: chalk_ir::Substitution::empty(interner),
1203+
})
1204+
.intern(interner)),
11911205
}
11921206
}
11931207
}
@@ -1542,3 +1556,30 @@ impl Kinded for chalk_ir::Parameter<ChalkIr> {
15421556
self.data(interner).kind()
15431557
}
15441558
}
1559+
1560+
fn ast_scalar_to_chalk_scalar(scalar: ScalarType) -> chalk_ir::Scalar {
1561+
match scalar {
1562+
ScalarType::Int(int) => chalk_ir::Scalar::Int(match int {
1563+
IntTy::I8 => chalk_ir::IntTy::I8,
1564+
IntTy::I16 => chalk_ir::IntTy::I16,
1565+
IntTy::I32 => chalk_ir::IntTy::I32,
1566+
IntTy::I64 => chalk_ir::IntTy::I64,
1567+
IntTy::I128 => chalk_ir::IntTy::I128,
1568+
IntTy::Isize => chalk_ir::IntTy::Isize,
1569+
}),
1570+
ScalarType::Uint(uint) => chalk_ir::Scalar::Uint(match uint {
1571+
UintTy::U8 => chalk_ir::UintTy::U8,
1572+
UintTy::U16 => chalk_ir::UintTy::U16,
1573+
UintTy::U32 => chalk_ir::UintTy::U32,
1574+
UintTy::U64 => chalk_ir::UintTy::U64,
1575+
UintTy::U128 => chalk_ir::UintTy::U128,
1576+
UintTy::Usize => chalk_ir::UintTy::Usize,
1577+
}),
1578+
ScalarType::Float(float) => chalk_ir::Scalar::Float(match float {
1579+
FloatTy::F32 => chalk_ir::FloatTy::F32,
1580+
FloatTy::F64 => chalk_ir::FloatTy::F64,
1581+
}),
1582+
ScalarType::Bool => chalk_ir::Scalar::Bool,
1583+
ScalarType::Char => chalk_ir::Scalar::Char,
1584+
}
1585+
}

chalk-ir/src/debug.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ impl<I: Interner> Debug for TypeName<I> {
141141
match self {
142142
TypeName::Struct(id) => write!(fmt, "{:?}", id),
143143
TypeName::AssociatedType(assoc_ty) => write!(fmt, "{:?}", assoc_ty),
144+
TypeName::Scalar(scalar) => write!(fmt, "{:?}", scalar),
145+
TypeName::Tuple(arity) => write!(fmt, "{:?}", arity),
144146
TypeName::OpaqueType(opaque_ty) => write!(fmt, "!{:?}", opaque_ty),
145147
TypeName::Error => write!(fmt, "{{error}}"),
146148
}

chalk-ir/src/fold/boring_impls.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,10 @@ copy_fold!(DebruijnIndex);
243243
copy_fold!(chalk_engine::TableIndex);
244244
copy_fold!(chalk_engine::TimeStamp);
245245
copy_fold!(());
246+
copy_fold!(UintTy);
247+
copy_fold!(IntTy);
248+
copy_fold!(FloatTy);
249+
copy_fold!(Scalar);
246250
copy_fold!(ClausePriority);
247251

248252
#[macro_export]

chalk-ir/src/lib.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,41 @@ impl<G: HasInterner> HasInterner for InEnvironment<G> {
106106
type Interner = G::Interner;
107107
}
108108

109+
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
110+
pub enum IntTy {
111+
Isize,
112+
I8,
113+
I16,
114+
I32,
115+
I64,
116+
I128,
117+
}
118+
119+
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
120+
pub enum UintTy {
121+
Usize,
122+
U8,
123+
U16,
124+
U32,
125+
U64,
126+
U128,
127+
}
128+
129+
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
130+
pub enum FloatTy {
131+
F32,
132+
F64,
133+
}
134+
135+
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
136+
pub enum Scalar {
137+
Bool,
138+
Char,
139+
Int(IntTy),
140+
Uint(UintTy),
141+
Float(FloatTy),
142+
}
143+
109144
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Fold, Visit)]
110145
pub enum TypeName<I: Interner> {
111146
/// a type like `Vec<T>`
@@ -114,6 +149,12 @@ pub enum TypeName<I: Interner> {
114149
/// an associated type like `Iterator::Item`; see `AssociatedType` for details
115150
AssociatedType(AssocTypeId<I>),
116151

152+
/// a scalar type like `bool` or `u32`
153+
Scalar(Scalar),
154+
155+
/// a tuple of the given arity
156+
Tuple(usize),
157+
117158
/// a placeholder for opaque types like `impl Trait`
118159
OpaqueType(OpaqueTyId<I>),
119160

chalk-ir/src/visit/boring_impls.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
//! The more interesting impls of `Visit` remain in the `visit` module.
66
77
use crate::{
8-
AssocTypeId, ClausePriority, DebruijnIndex, Goals, ImplId, Interner, OpaqueTyId, Parameter,
9-
ParameterKind, PlaceholderIndex, ProgramClause, ProgramClauseData, ProgramClauses,
10-
QuantifiedWhereClauses, QuantifierKind, StructId, Substitution, SuperVisit, TraitId,
11-
UniverseIndex, Visit, VisitResult, Visitor,
8+
AssocTypeId, ClausePriority, DebruijnIndex, FloatTy, Goals, ImplId, IntTy, Interner,
9+
OpaqueTyId, Parameter, ParameterKind, PlaceholderIndex, ProgramClause, ProgramClauseData,
10+
ProgramClauses, QuantifiedWhereClauses, QuantifierKind, Scalar, StructId, Substitution,
11+
SuperVisit, TraitId, UintTy, UniverseIndex, Visit, VisitResult, Visitor,
1212
};
1313
use chalk_engine::{context::Context, ExClause, FlounderedSubgoal, Literal};
1414
use std::{marker::PhantomData, sync::Arc};
@@ -207,6 +207,10 @@ const_visit!(chalk_engine::TableIndex);
207207
const_visit!(chalk_engine::TimeStamp);
208208
const_visit!(ClausePriority);
209209
const_visit!(());
210+
const_visit!(Scalar);
211+
const_visit!(UintTy);
212+
const_visit!(IntTy);
213+
const_visit!(FloatTy);
210214

211215
#[macro_export]
212216
macro_rules! id_visit {

chalk-parse/src/ast.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,47 @@ pub enum Ty {
187187
lifetime_names: Vec<Identifier>,
188188
ty: Box<Ty>,
189189
},
190+
Tuple {
191+
types: Vec<Box<Ty>>,
192+
},
193+
Scalar {
194+
ty: ScalarType,
195+
},
196+
}
197+
198+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
199+
pub enum IntTy {
200+
Isize,
201+
I8,
202+
I16,
203+
I32,
204+
I64,
205+
I128,
206+
}
207+
208+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
209+
pub enum UintTy {
210+
Usize,
211+
U8,
212+
U16,
213+
U32,
214+
U64,
215+
U128,
216+
}
217+
218+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
219+
pub enum FloatTy {
220+
F32,
221+
F64,
222+
}
223+
224+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
225+
pub enum ScalarType {
226+
Bool,
227+
Char,
228+
Int(IntTy),
229+
Uint(UintTy),
230+
Float(FloatTy),
190231
}
191232

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

chalk-parse/src/parser.lalrpop

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ pub Ty: Ty = {
193193
};
194194

195195
TyWithoutFor: Ty = {
196+
<ScalarType> => Ty::Scalar { ty: <> },
196197
<n:Id> => Ty::Id { name: n},
197198
"fn" "(" <t:Ty> ")" => Ty::ForAll {
198199
lifetime_names: vec![],
@@ -203,7 +204,37 @@ TyWithoutFor: Ty = {
203204
},
204205
<n:Id> "<" <a:Comma<Parameter>> ">" => Ty::Apply { name: n, args: a },
205206
<p:ProjectionTy> => Ty::Projection { proj: p },
206-
"(" <Ty> ")",
207+
"(" <t:TupleOrParensInner> ")" => t,
208+
};
209+
210+
ScalarType: ScalarType = {
211+
"u8" => ScalarType::Uint(UintTy::U8),
212+
"u16" => ScalarType::Uint(UintTy::U16),
213+
"u32" => ScalarType::Uint(UintTy::U32),
214+
"u64" => ScalarType::Uint(UintTy::U64),
215+
"u128" => ScalarType::Uint(UintTy::U128),
216+
"usize" => ScalarType::Uint(UintTy::Usize),
217+
"i8" => ScalarType::Int(IntTy::I8),
218+
"i16" => ScalarType::Int(IntTy::I16),
219+
"i32" => ScalarType::Int(IntTy::I32),
220+
"i64" => ScalarType::Int(IntTy::I64),
221+
"i128" => ScalarType::Int(IntTy::I128),
222+
"isize" => ScalarType::Int(IntTy::Isize),
223+
"f32" => ScalarType::Float(FloatTy::F32),
224+
"f64" => ScalarType::Float(FloatTy::F64),
225+
"bool" => ScalarType::Bool,
226+
"char" => ScalarType::Char,
227+
};
228+
229+
TupleOrParensInner: Ty = {
230+
<Ty>,
231+
<first:Ty> "," <rest:Comma<Ty>> => {
232+
let mut types = Vec::with_capacity(rest.len() + 1);
233+
types.push(Box::new(first));
234+
types.extend(rest.into_iter().map(Box::new));
235+
Ty::Tuple { types }
236+
},
237+
() => Ty::Tuple { types: vec![] },
207238
};
208239

209240
Lifetime: Lifetime = {

chalk-solve/src/clauses.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ fn match_ty<I: Interner>(
416416
) -> Result<(), Floundered> {
417417
let interner = builder.interner();
418418
Ok(match ty.data(interner) {
419-
TyData::Apply(application_ty) => match_type_name(builder, application_ty.name),
419+
TyData::Apply(application_ty) => match_type_name(builder, interner, application_ty),
420420
TyData::Placeholder(_) => {
421421
builder.push_clause(WellFormed::Ty(ty.clone()), Some(FromEnv::Ty(ty.clone())));
422422
}
@@ -442,8 +442,12 @@ fn match_ty<I: Interner>(
442442
})
443443
}
444444

445-
fn match_type_name<I: Interner>(builder: &mut ClauseBuilder<'_, I>, name: TypeName<I>) {
446-
match name {
445+
fn match_type_name<I: Interner>(
446+
builder: &mut ClauseBuilder<'_, I>,
447+
interner: &I,
448+
application: &ApplicationTy<I>,
449+
) {
450+
match application.name {
447451
TypeName::Struct(struct_id) => match_struct(builder, struct_id),
448452
TypeName::OpaqueType(opaque_ty_id) => builder
449453
.db
@@ -454,6 +458,10 @@ fn match_type_name<I: Interner>(builder: &mut ClauseBuilder<'_, I>, name: TypeNa
454458
.db
455459
.associated_ty_data(type_id)
456460
.to_program_clauses(builder),
461+
TypeName::Scalar(_) => {
462+
builder.push_fact(WellFormed::Ty(application.clone().intern(interner)))
463+
}
464+
TypeName::Tuple(_) => (),
457465
}
458466
}
459467

chalk-solve/src/clauses/env_elaborator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl<'me, I: Interner> Visitor<'me, I> for EnvElaborator<'me, I> {
6161
let interner = self.db.interner();
6262
match ty.data(interner) {
6363
TyData::Apply(application_ty) => {
64-
match_type_name(&mut self.builder, application_ty.name)
64+
match_type_name(&mut self.builder, interner, application_ty)
6565
}
6666
TyData::Alias(alias_ty) => match_alias_ty(&mut self.builder, alias_ty),
6767
TyData::Placeholder(_) => {}

libstd.chalk

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,10 @@ trait Clone { }
1010
trait Copy where Self: Clone { }
1111
trait Sized { }
1212

13-
struct i32 { }
1413
impl Copy for i32 { }
1514
impl Clone for i32 { }
1615
impl Sized for i32 { }
1716

18-
struct u32 { }
1917
impl Copy for u32 { }
2018
impl Clone for u32 { }
2119
impl Sized for u32 { }

tests/lowering/mod.rs

Lines changed: 56 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,57 @@ 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+
error_msg {
474+
"parse error: UnrecognizedToken { token: (8, Token(49, \"i32\"), 11), expected: [\"r#\\\"([A-Za-z]|_)([A-Za-z0-9]|_)*\\\"#\"] }"
475+
}
476+
}
477+
}

0 commit comments

Comments
 (0)