-
Notifications
You must be signed in to change notification settings - Fork 239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sub-Types (Type Safety v1.1) #8
Comments
|
Also, it seems like signed types should be explicit, though LLVM doesn't make this distinction. |
It's worth noting StructTypes (and probably StructValues) have two interesting properties:
|
After looking at #32, it seems that Those two methods could be implemented for only the latter Builder Function subtype. |
I know gtk-rs encountered a similar problem when emulating inheritance in Rust. They came up with an IsA trait which lets you use a child class as its parent. So you might write a function that takes anything which |
Inkwell use to have something like that, however the issue was primarily that the trait would require you to assume the global context which may not always be desired and wasn't super intuitive (why does |
We're going to want |
WARNING: Brain dump ahead!
Today,
build_int_add
looks approximately likebuild_int_add(&self, left: &IntValue, right: &IntValue) -> IntValue
. This is great, because it'll stop you from trying to add aFloatValue
and anIntValue
, for instance which would not work in LLVM. But I wonder if we can take type checking a step further! What happens when left is au8
and right is au16
? Needs to be verified, but I believe this is also a LLVM error because it doesn't make much sense. How would adding two values of different sizes work (without casting)?Therefore, I wonder if we can add sub-type annotations using generics (here-on known as sub-types). For example,
IntType<u32>
andIntValue<u32>
so that you could express something like:build_int_add<T>(&self, left: &IntValue<T>, right: &IntValue<T>) -> IntValue<T>
which would ensure only the same sub-types are added together when needed. So,IntValue<u8>
andIntValue<u8>
would be able to be added together but it'd preventIntValue<u8>
andIntValue<u16>
from being added together, requiring a cast first. And, in case you do want different sub-types to be valid input you would just specify separate type variables:do_foo<L, R>(&self, left: &IntType<L>, right: &IntType<R>)
In terms of implementation details, the sub-type should basically just be a marker and not take up any additional space (as PhantomData if needed) (type parameters are cool!)
Outstanding questions:
How would custom & 80 bit width types be handled given that they don't map to rust types (yet?)? It may be permissible to disallow custom & 80 bit types since they are far less common. Or just find some workaround.i128 is stable; we can use custom type for the f128 and f80, etc I think.LLVM has a pointer-width typeusize
should probably be a valid sub-type for ints, but I wonder if there's any issue with it's variable width nature? LLVM should allow us to map it to the pointer size at runtimeString
type:StructType<(PointerType<IntType<u8>>, IntType<usize>, IntType<usize>)>
Will the compiler be able to hide most of this from the user so that they don't have to specify annotations themselves?Could thenum
crate's traits help with float and int sub-types?Should signed types be explicit(IEIntType<i8>
) or just an irrelevant fact about anIntType<u8>
? I'm guessing LLVM doesn't let you mix signed and unsigned addition without casting first, so I'm leaning towards keeping them explicit.The text was updated successfully, but these errors were encountered: