Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions src/ir/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,12 +282,9 @@ mod statement {

#[derive(Clone, Debug)]
pub enum DeclarationTy {
#[cfg_attr(
not(test),
expect(
dead_code,
reason = "will be used when variable declarations can be explicitly typed."
)
#[expect(
dead_code,
reason = "will be used when variable declarations can be explicitly typed."
)]
Type(TypeId),
Inferred(ExpressionId),
Expand Down
41 changes: 28 additions & 13 deletions src/ir/thir.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
use crate::{
prelude::*,
ty::{TypeVarId, TypeVars},
};
use crate::prelude::*;

use hir::*;

#[derive(Clone, Debug)]
pub struct Thir<'hir> {
pub hir: &'hir Hir,
pub types: HashMap<TypeVarId, TypeId>,
pub type_vars: TypeVars,
pub identifier_tys: BTreeMap<IdentifierBindingId, TypeId>,
pub expression_tys: IndexedVec<ExpressionId, TypeId>,
}

impl Deref for Thir<'_> {
Expand All @@ -21,16 +17,35 @@ impl Deref for Thir<'_> {
}

impl<'hir> Thir<'hir> {
pub fn new(hir: &'hir Hir, types: HashMap<TypeVarId, TypeId>, type_vars: TypeVars) -> Self {
pub fn new(
hir: &'hir Hir,
identifiers_tys: BTreeMap<IdentifierBindingId, TypeId>,
expressions_tys: IndexedVec<ExpressionId, TypeId>,
) -> Self {
Self {
hir,
types,
type_vars,
identifier_tys: identifiers_tys,
expression_tys: expressions_tys,
}
}

pub fn type_of(&self, id: impl Into<TypeVar>) -> TypeId {
let var = self.type_vars.get(id.into());
self.types[&var]
pub fn type_of(&self, id: impl ThirIndex) -> TypeId {
id.type_of(self)
}
}

pub trait ThirIndex: Copy {
fn type_of(self, thir: &Thir<'_>) -> TypeId;
}

impl ThirIndex for IdentifierBindingId {
fn type_of(self, thir: &Thir<'_>) -> TypeId {
thir.identifier_tys[&self]
}
}

impl ThirIndex for ExpressionId {
fn type_of(self, thir: &Thir<'_>) -> TypeId {
thir.expression_tys[self]
}
}
17 changes: 16 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ mod test {
}

#[test]
#[should_panic(expected = "Type")]
#[should_panic(expected = "function signature must match trait definition")]
fn trait_impl_mismatch() {
run(r#"trait MyTrait {
fn some_method() -> Self;
Expand All @@ -458,6 +458,21 @@ mod test {
}"#);
}

#[test]
#[should_panic(expected = "trait implementation missing method")]
fn trait_impl_missing_fn() {
run(r#"trait MyTrait {
fn some_method() -> Self;
}

impl MyTrait for u8 {
}

fn main() -> u8 {
<u8 as MyTrait>::some_method()
}"#);
}

#[test]
#[should_panic(expected = "type must implement trait")]
fn trait_not_implemented() {
Expand Down
20 changes: 12 additions & 8 deletions src/passes/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,10 @@ impl<'ctx, 'mir, 'ink> Codegen<'ctx, 'mir, 'ink> {
_ => {
let (function_ptr, function_ty) =
self.resolve_operand(&builder, function_id, *function);
let Type::Function {
let Type::Composite(CompositeType::Function {
parameters,
return_ty,
} = &self.ctx.types[function_ty]
}) = &self.ctx.types[function_ty]
else {
panic!();
};
Expand Down Expand Up @@ -337,15 +337,15 @@ impl<'ctx, 'mir, 'ink> Codegen<'ctx, 'mir, 'ink> {

for projection in &place.projection {
(ptr, ty) = match (projection, &self.ctx.types[ty]) {
(Projection::Deref, Type::Ref(inner_ty)) => (
(Projection::Deref, Type::Composite(CompositeType::Ref(inner_ty))) => (
builder
.build_load(self.basic_ty(ty), ptr, "deref")
.unwrap()
.into_pointer_value(),
*inner_ty,
),
(Projection::Deref, ty) => panic!("cannot dereference {ty:?}"),
(Projection::Field(field), Type::Tuple(fields)) => {
(Projection::Field(field), Type::Composite(CompositeType::Tuple(fields))) => {
let offset = self.ctx.types.offset_of(ty, *field).unwrap();
let offset = self.ink.i64_type().const_int(offset as u64, false);

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

match &self.ctx.types[return_ty] {
Type::Tuple(tuple_items) if tuple_items.is_empty() => {
Type::Composite(CompositeType::Tuple(tuple_items)) if tuple_items.is_empty() => {
self.ink.void_type().fn_type(&parameters, false)
}
_ => self.basic_ty(return_ty).fn_type(&parameters, false),
Expand All @@ -730,10 +730,14 @@ impl<'ctx, 'mir, 'ink> Codegen<'ctx, 'mir, 'ink> {
Type::I8 => self.ink.i8_type().into(),
Type::U8 => self.ink.i8_type().into(),
Type::Boolean => self.ink.bool_type().into(),
Type::Ref(_) => self.ink.ptr_type(AddressSpace::default()).into(),
Type::Never => unreachable!(),
Type::Function { .. } => self.ink.ptr_type(AddressSpace::default()).into(),
Type::Tuple(_) => self
Type::Composite(CompositeType::Ref(_)) => {
self.ink.ptr_type(AddressSpace::default()).into()
}
Type::Composite(CompositeType::Function { .. }) => {
self.ink.ptr_type(AddressSpace::default()).into()
}
Type::Composite(CompositeType::Tuple(_)) => self
.ink
.i8_type()
.array_type(self.ctx.types.size_of(ty) as u32)
Expand Down
6 changes: 3 additions & 3 deletions src/passes/hir_gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub struct HirGen<'ctx, 'ast> {
/// AST that will be processed.
ast: &'ast ast::Ast,
/// HIR that is being generated.
hir: Hir,
pub hir: Hir,
}

impl<'ctx, 'ast> Pass<'ctx, 'ast> for HirGen<'ctx, 'ast> {
Expand Down Expand Up @@ -327,7 +327,7 @@ impl<'ctx, 'ast> HirGen<'ctx, 'ast> {
}

/// Lower an expression within the provided scope.
fn lower_expression(
pub fn lower_expression(
&mut self,
ctx: &FunctionCtx,
expression: &ast::Expression,
Expand Down Expand Up @@ -511,7 +511,7 @@ impl<'ctx, 'ast> HirGen<'ctx, 'ast> {

/// Context required when processing a function.
#[derive(Clone, Debug)]
enum FunctionCtx {
pub enum FunctionCtx {
/// An item function (top-level function).
Item,
/// A method within an `impl` block.
Expand Down
Loading