diff --git a/src/ast2/intern.rs b/src/ast2/intern.rs index 1c8d27e..09df5f6 100644 --- a/src/ast2/intern.rs +++ b/src/ast2/intern.rs @@ -22,6 +22,12 @@ pub enum SimpleType { USize, ISize, ComptimeInt, + /// Top type: this is the supertype of all types, and any value can coerce into it. + /// Although Rust's `()` is not a top type, it can be thought of as a top type in some contexts. + Top, + /// Bottom type: this is the subtype of all types, and it can coerce into a value of any type. + /// Akin to Rust's `!`. + Bottom, } impl From for SimpleType { @@ -52,6 +58,8 @@ impl Display for SimpleType { SimpleType::USize => "usize", SimpleType::ISize => "isize", SimpleType::ComptimeInt => "comptime_int", + SimpleType::Top => "⊤", + SimpleType::Bottom => "⊥", } ) } @@ -527,6 +535,8 @@ macro_rules! static_keys { } static_keys!( + TOP => Key::SimpleType {ty: SimpleType::Top,}, + BOTTOM => Key::SimpleType {ty: SimpleType::Bottom,}, BOOL => Key::SimpleType {ty: SimpleType::Bool,}, F32 => Key::SimpleType {ty: SimpleType::F32,}, F64 => Key::SimpleType {ty: SimpleType::F64,}, @@ -632,6 +642,18 @@ impl InternPool { pub fn get_i64_type(&self) -> Index { self.get_assume_present(&Key::SIntType { bit_width: 64 }) } + + pub fn get_top_type(&self) -> Index { + self.get_assume_present(&Key::SimpleType { + ty: SimpleType::Top, + }) + } + + pub fn get_bottom_type(&self) -> Index { + self.get_assume_present(&Key::SimpleType { + ty: SimpleType::Bottom, + }) + } } #[derive(Debug, Clone, Copy)] @@ -740,8 +762,8 @@ impl InternPool { todo!("void can't be turned into a mir type") } SimpleType::ISize | SimpleType::USize => Type::QWord, - SimpleType::ComptimeInt => { - panic!("comptime int can't be turned into a mir type") + SimpleType::Top | SimpleType::Bottom | SimpleType::ComptimeInt => { + panic!("{ty} can't be turned into a mir type") } }, Key::ArrayType { .. } => { @@ -816,6 +838,9 @@ impl InternPool { }, SimpleType::USize => ptr_size, SimpleType::ISize => ptr_size, + SimpleType::Top | SimpleType::Bottom => { + panic!("top and bottom types are not sized") + } SimpleType::ComptimeInt => panic!("comptime int is unsized"), }, Key::PointerType { .. } => ptr_size, @@ -953,6 +978,9 @@ impl InternPool { SimpleType::USize => Type::Integer(IntegralType::new(false, pointer_bits)), SimpleType::ISize => Type::Integer(IntegralType::new(true, pointer_bits)), SimpleType::ComptimeInt => Type::comptime_number(), + SimpleType::Top | SimpleType::Bottom => { + panic!("top and bottom types cannot be converted to ast1 types") + } }, Key::PointerType { pointee, flags } => Type::Pointer { constness: flags.is_const, diff --git a/src/ast2/ir.rs b/src/ast2/ir.rs index b92efff..aef9354 100644 --- a/src/ast2/ir.rs +++ b/src/ast2/ir.rs @@ -1,11 +1,12 @@ +#![allow(unused_variables)] use std::collections::HashMap; use crate::{ ast2::{ - intern::{self, AMD64_POINTER_TYPE_INFO}, Index, + intern::{self, AMD64_POINTER_TYPE_INFO}, }, - triples::{self, Inst, IR}, + triples::{self, IR, Inst}, }; #[derive(Debug, thiserror::Error)] @@ -15,9 +16,9 @@ enum Error { } use super::{ + Ast, Data, PlaceOrValue, Tag, TypeCache, intern::InternPoolWrapper as InternPool, visitor::{AstExt, AstVisitorTrait}, - Ast, Data, PlaceOrValue, Tag, TypeCache, }; struct IrBuilder { diff --git a/src/ast2/mod.rs b/src/ast2/mod.rs index dde901a..14597b6 100644 --- a/src/ast2/mod.rs +++ b/src/ast2/mod.rs @@ -5,7 +5,7 @@ use std::{ fmt::{Debug, Display}, }; -use intern::{InternPoolWrapper as InternPool, PointerFlags, StructFlags, AMD64_POINTER_TYPE_INFO}; +use intern::{AMD64_POINTER_TYPE_INFO, InternPoolWrapper as InternPool, PointerFlags, StructFlags}; use num_bigint::BigInt; use crate::{ @@ -2251,6 +2251,9 @@ where }; ComptimeNumber::Integral(ComptimeInt::Comptime(bigint)) } + intern::SimpleType::Top | intern::SimpleType::Bottom => { + unreachable!() + } }, _ => { unreachable!() diff --git a/src/ast2/typecheck.rs b/src/ast2/typecheck.rs index fef8123..da52c77 100644 --- a/src/ast2/typecheck.rs +++ b/src/ast2/typecheck.rs @@ -1,10 +1,17 @@ +//! Type checking for the AST. +//! This module implements a bi-unification type-checking algorithm to infer +//! types for each node in the AST. + +// Visitor pattern has lots of unused arguments +#![allow(unused_variables)] + use crate::variant; use super::{ + Ast, Data, Index, Tag, intern::{self}, tag::{AstNode, AstNodeExt}, visitor::{AstExt, AstVisitorTrait}, - Ast, Data, Index, Tag, }; #[derive(Debug, Clone, Copy, PartialEq, Eq)]