Skip to content

Commit 31b30d4

Browse files
authored
feat: new type solver (#12)
2 parents b580396 + f81fef5 commit 31b30d4

15 files changed

Lines changed: 1673 additions & 2472 deletions

File tree

src/ir/hir.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -282,12 +282,9 @@ mod statement {
282282

283283
#[derive(Clone, Debug)]
284284
pub enum DeclarationTy {
285-
#[cfg_attr(
286-
not(test),
287-
expect(
288-
dead_code,
289-
reason = "will be used when variable declarations can be explicitly typed."
290-
)
285+
#[expect(
286+
dead_code,
287+
reason = "will be used when variable declarations can be explicitly typed."
291288
)]
292289
Type(TypeId),
293290
Inferred(ExpressionId),

src/ir/thir.rs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
use crate::{
2-
prelude::*,
3-
ty::{TypeVarId, TypeVars},
4-
};
1+
use crate::prelude::*;
52

63
use hir::*;
74

8-
#[derive(Clone, Debug)]
95
pub struct Thir<'hir> {
106
pub hir: &'hir Hir,
11-
pub types: HashMap<TypeVarId, TypeId>,
12-
pub type_vars: TypeVars,
7+
pub identifier_tys: BTreeMap<IdentifierBindingId, TypeId>,
8+
pub expression_tys: IndexedVec<ExpressionId, TypeId>,
139
}
1410

1511
impl Deref for Thir<'_> {
@@ -21,16 +17,35 @@ impl Deref for Thir<'_> {
2117
}
2218

2319
impl<'hir> Thir<'hir> {
24-
pub fn new(hir: &'hir Hir, types: HashMap<TypeVarId, TypeId>, type_vars: TypeVars) -> Self {
20+
pub fn new(
21+
hir: &'hir Hir,
22+
identifiers_tys: BTreeMap<IdentifierBindingId, TypeId>,
23+
expressions_tys: IndexedVec<ExpressionId, TypeId>,
24+
) -> Self {
2525
Self {
2626
hir,
27-
types,
28-
type_vars,
27+
identifier_tys: identifiers_tys,
28+
expression_tys: expressions_tys,
2929
}
3030
}
3131

32-
pub fn type_of(&self, id: impl Into<TypeVar>) -> TypeId {
33-
let var = self.type_vars.get(id.into());
34-
self.types[&var]
32+
pub fn type_of(&self, id: impl ThirIndex) -> TypeId {
33+
id.type_of(self)
34+
}
35+
}
36+
37+
pub trait ThirIndex: Copy {
38+
fn type_of(self, thir: &Thir<'_>) -> TypeId;
39+
}
40+
41+
impl ThirIndex for IdentifierBindingId {
42+
fn type_of(self, thir: &Thir<'_>) -> TypeId {
43+
thir.identifier_tys[&self]
44+
}
45+
}
46+
47+
impl ThirIndex for ExpressionId {
48+
fn type_of(self, thir: &Thir<'_>) -> TypeId {
49+
thir.expression_tys[self]
3550
}
3651
}

src/main.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ mod test {
441441
}
442442

443443
#[test]
444-
#[should_panic(expected = "Type")]
444+
#[should_panic(expected = "function signature must match trait definition")]
445445
fn trait_impl_mismatch() {
446446
run(r#"trait MyTrait {
447447
fn some_method() -> Self;
@@ -458,6 +458,21 @@ mod test {
458458
}"#);
459459
}
460460

461+
#[test]
462+
#[should_panic(expected = "trait implementation missing method")]
463+
fn trait_impl_missing_fn() {
464+
run(r#"trait MyTrait {
465+
fn some_method() -> Self;
466+
}
467+
468+
impl MyTrait for u8 {
469+
}
470+
471+
fn main() -> u8 {
472+
<u8 as MyTrait>::some_method()
473+
}"#);
474+
}
475+
461476
#[test]
462477
#[should_panic(expected = "type must implement trait")]
463478
fn trait_not_implemented() {

src/passes/codegen.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -230,10 +230,10 @@ impl<'ctx, 'mir, 'ink> Codegen<'ctx, 'mir, 'ink> {
230230
_ => {
231231
let (function_ptr, function_ty) =
232232
self.resolve_operand(&builder, function_id, *function);
233-
let Type::Function {
233+
let Type::Composite(CompositeType::Function {
234234
parameters,
235235
return_ty,
236-
} = &self.ctx.types[function_ty]
236+
}) = &self.ctx.types[function_ty]
237237
else {
238238
panic!();
239239
};
@@ -337,15 +337,15 @@ impl<'ctx, 'mir, 'ink> Codegen<'ctx, 'mir, 'ink> {
337337

338338
for projection in &place.projection {
339339
(ptr, ty) = match (projection, &self.ctx.types[ty]) {
340-
(Projection::Deref, Type::Ref(inner_ty)) => (
340+
(Projection::Deref, Type::Composite(CompositeType::Ref(inner_ty))) => (
341341
builder
342342
.build_load(self.basic_ty(ty), ptr, "deref")
343343
.unwrap()
344344
.into_pointer_value(),
345345
*inner_ty,
346346
),
347347
(Projection::Deref, ty) => panic!("cannot dereference {ty:?}"),
348-
(Projection::Field(field), Type::Tuple(fields)) => {
348+
(Projection::Field(field), Type::Composite(CompositeType::Tuple(fields))) => {
349349
let offset = self.ctx.types.offset_of(ty, *field).unwrap();
350350
let offset = self.ink.i64_type().const_int(offset as u64, false);
351351

@@ -717,7 +717,7 @@ impl<'ctx, 'mir, 'ink> Codegen<'ctx, 'mir, 'ink> {
717717
.collect::<Vec<_>>();
718718

719719
match &self.ctx.types[return_ty] {
720-
Type::Tuple(tuple_items) if tuple_items.is_empty() => {
720+
Type::Composite(CompositeType::Tuple(tuple_items)) if tuple_items.is_empty() => {
721721
self.ink.void_type().fn_type(&parameters, false)
722722
}
723723
_ => self.basic_ty(return_ty).fn_type(&parameters, false),
@@ -730,10 +730,14 @@ impl<'ctx, 'mir, 'ink> Codegen<'ctx, 'mir, 'ink> {
730730
Type::I8 => self.ink.i8_type().into(),
731731
Type::U8 => self.ink.i8_type().into(),
732732
Type::Boolean => self.ink.bool_type().into(),
733-
Type::Ref(_) => self.ink.ptr_type(AddressSpace::default()).into(),
734733
Type::Never => unreachable!(),
735-
Type::Function { .. } => self.ink.ptr_type(AddressSpace::default()).into(),
736-
Type::Tuple(_) => self
734+
Type::Composite(CompositeType::Ref(_)) => {
735+
self.ink.ptr_type(AddressSpace::default()).into()
736+
}
737+
Type::Composite(CompositeType::Function { .. }) => {
738+
self.ink.ptr_type(AddressSpace::default()).into()
739+
}
740+
Type::Composite(CompositeType::Tuple(_)) => self
737741
.ink
738742
.i8_type()
739743
.array_type(self.ctx.types.size_of(ty) as u32)

src/passes/hir_gen/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub struct HirGen<'ctx, 'ast> {
1717
/// AST that will be processed.
1818
ast: &'ast ast::Ast,
1919
/// HIR that is being generated.
20-
hir: Hir,
20+
pub hir: Hir,
2121
}
2222

2323
impl<'ctx, 'ast> Pass<'ctx, 'ast> for HirGen<'ctx, 'ast> {
@@ -327,7 +327,7 @@ impl<'ctx, 'ast> HirGen<'ctx, 'ast> {
327327
}
328328

329329
/// Lower an expression within the provided scope.
330-
fn lower_expression(
330+
pub fn lower_expression(
331331
&mut self,
332332
ctx: &FunctionCtx,
333333
expression: &ast::Expression,
@@ -511,7 +511,7 @@ impl<'ctx, 'ast> HirGen<'ctx, 'ast> {
511511

512512
/// Context required when processing a function.
513513
#[derive(Clone, Debug)]
514-
enum FunctionCtx {
514+
pub enum FunctionCtx {
515515
/// An item function (top-level function).
516516
Item,
517517
/// A method within an `impl` block.

0 commit comments

Comments
 (0)