top and bottom types
This commit is contained in:
parent
bbaa9cb671
commit
adfc2c27f8
|
@ -22,6 +22,12 @@ pub enum SimpleType {
|
||||||
USize,
|
USize,
|
||||||
ISize,
|
ISize,
|
||||||
ComptimeInt,
|
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 {
|
impl From<u8> for SimpleType {
|
||||||
|
@ -52,6 +58,8 @@ impl Display for SimpleType {
|
||||||
SimpleType::USize => "usize",
|
SimpleType::USize => "usize",
|
||||||
SimpleType::ISize => "isize",
|
SimpleType::ISize => "isize",
|
||||||
SimpleType::ComptimeInt => "comptime_int",
|
SimpleType::ComptimeInt => "comptime_int",
|
||||||
|
SimpleType::Top => "⊤",
|
||||||
|
SimpleType::Bottom => "⊥",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -527,6 +535,8 @@ macro_rules! static_keys {
|
||||||
}
|
}
|
||||||
|
|
||||||
static_keys!(
|
static_keys!(
|
||||||
|
TOP => Key::SimpleType {ty: SimpleType::Top,},
|
||||||
|
BOTTOM => Key::SimpleType {ty: SimpleType::Bottom,},
|
||||||
BOOL => Key::SimpleType {ty: SimpleType::Bool,},
|
BOOL => Key::SimpleType {ty: SimpleType::Bool,},
|
||||||
F32 => Key::SimpleType {ty: SimpleType::F32,},
|
F32 => Key::SimpleType {ty: SimpleType::F32,},
|
||||||
F64 => Key::SimpleType {ty: SimpleType::F64,},
|
F64 => Key::SimpleType {ty: SimpleType::F64,},
|
||||||
|
@ -632,6 +642,18 @@ impl InternPool {
|
||||||
pub fn get_i64_type(&self) -> Index {
|
pub fn get_i64_type(&self) -> Index {
|
||||||
self.get_assume_present(&Key::SIntType { bit_width: 64 })
|
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)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
@ -740,8 +762,8 @@ impl InternPool {
|
||||||
todo!("void can't be turned into a mir type")
|
todo!("void can't be turned into a mir type")
|
||||||
}
|
}
|
||||||
SimpleType::ISize | SimpleType::USize => Type::QWord,
|
SimpleType::ISize | SimpleType::USize => Type::QWord,
|
||||||
SimpleType::ComptimeInt => {
|
SimpleType::Top | SimpleType::Bottom | SimpleType::ComptimeInt => {
|
||||||
panic!("comptime int can't be turned into a mir type")
|
panic!("{ty} can't be turned into a mir type")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Key::ArrayType { .. } => {
|
Key::ArrayType { .. } => {
|
||||||
|
@ -816,6 +838,9 @@ impl InternPool {
|
||||||
},
|
},
|
||||||
SimpleType::USize => ptr_size,
|
SimpleType::USize => ptr_size,
|
||||||
SimpleType::ISize => 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"),
|
SimpleType::ComptimeInt => panic!("comptime int is unsized"),
|
||||||
},
|
},
|
||||||
Key::PointerType { .. } => ptr_size,
|
Key::PointerType { .. } => ptr_size,
|
||||||
|
@ -953,6 +978,9 @@ impl InternPool {
|
||||||
SimpleType::USize => Type::Integer(IntegralType::new(false, pointer_bits)),
|
SimpleType::USize => Type::Integer(IntegralType::new(false, pointer_bits)),
|
||||||
SimpleType::ISize => Type::Integer(IntegralType::new(true, pointer_bits)),
|
SimpleType::ISize => Type::Integer(IntegralType::new(true, pointer_bits)),
|
||||||
SimpleType::ComptimeInt => Type::comptime_number(),
|
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 {
|
Key::PointerType { pointee, flags } => Type::Pointer {
|
||||||
constness: flags.is_const,
|
constness: flags.is_const,
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
|
#![allow(unused_variables)]
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast2::{
|
ast2::{
|
||||||
intern::{self, AMD64_POINTER_TYPE_INFO},
|
|
||||||
Index,
|
Index,
|
||||||
|
intern::{self, AMD64_POINTER_TYPE_INFO},
|
||||||
},
|
},
|
||||||
triples::{self, Inst, IR},
|
triples::{self, IR, Inst},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
@ -15,9 +16,9 @@ enum Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
Ast, Data, PlaceOrValue, Tag, TypeCache,
|
||||||
intern::InternPoolWrapper as InternPool,
|
intern::InternPoolWrapper as InternPool,
|
||||||
visitor::{AstExt, AstVisitorTrait},
|
visitor::{AstExt, AstVisitorTrait},
|
||||||
Ast, Data, PlaceOrValue, Tag, TypeCache,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IrBuilder {
|
struct IrBuilder {
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::{
|
||||||
fmt::{Debug, Display},
|
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 num_bigint::BigInt;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -2251,6 +2251,9 @@ where
|
||||||
};
|
};
|
||||||
ComptimeNumber::Integral(ComptimeInt::Comptime(bigint))
|
ComptimeNumber::Integral(ComptimeInt::Comptime(bigint))
|
||||||
}
|
}
|
||||||
|
intern::SimpleType::Top | intern::SimpleType::Bottom => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
|
|
|
@ -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 crate::variant;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
Ast, Data, Index, Tag,
|
||||||
intern::{self},
|
intern::{self},
|
||||||
tag::{AstNode, AstNodeExt},
|
tag::{AstNode, AstNodeExt},
|
||||||
visitor::{AstExt, AstVisitorTrait},
|
visitor::{AstExt, AstVisitorTrait},
|
||||||
Ast, Data, Index, Tag,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
|
Loading…
Reference in a new issue