top and bottom types

This commit is contained in:
Janis 2025-07-14 18:09:23 +02:00
parent bbaa9cb671
commit adfc2c27f8
4 changed files with 46 additions and 7 deletions

View file

@ -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<u8> 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,

View file

@ -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 {

View file

@ -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!()

View file

@ -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)]