For a second I thought this was gonna be about adding higher kinded types to Rust by another name
. Since "kind" is commonly described as "the type of a type".
For a second I thought this was gonna be about adding higher kinded types to Rust by another name . Since "kind" is commonly described as "the type of a type".
a kind is the type of a type constructor or, less commonly, the type of a higher-order type operator.
Having read some documentation about Swift metatypes, I'm not seeing anything remotely like the code in your response, which looks like "the type argument to downcast is a runtime value".
What I've seen is more like:
fn cast<T>(any: Box<dyn Any>, _: T::type) {
if let Ok(x) = any.downcast::<T>() {
// do something
}
}
How will this interact with a type being generic over lifetimes?
For example, what should the following program print?
fn ref_to_type<'a>(r: &'a mut i32) -> Type {
r.type
}
fn main() {
let a = 5;
let t1 = ref_to_type(&mut a);
let t2 = ref_to_type(&mut a);
println!("{}", t1 == t2);
}
Implications of each result
If the result is true, then this new Type type won't be able to be used to downcast anything with references.
Alternatively, if the result is false, we can use it to downcast, but then we have the trouble of keeping track of unique lifetimes and chasing them all through codegen (this is the same reason specialisation with lifetimes is very hard to get right)
[edit: removed extra spaces and code mistakes that came free with my phone's keyboard]
You're very casually proposing Rust to have some form of dependent types (making runtime values determine the type of something), without specifying any of the semantics of what that means.This isn't something you can just add to Rust without considering the semantics implications.
For example, you've proposed this to be valid code:
fn cast(any: Box<dyn Any>, T: Type) /* apparently this is supposed to return something */ {
if let Ok(downcasted_x) = any.downcast::<T>() {
// do something
}
}
fn main(){
let ts: Vec<Type> = Vec::new();
let bs: Vec<Box<dyn Any>> = Vec::new();
for (type_, boxed) in ts.zip(bs) {
let x = cast(boxed, type_);
}
}
My interpretation of this is that T is a runtime value that determines the static type argument to the downcast method.
So I have some questions:
What's the type of downcasted_x? As in, the type you can write in let _: here = downcasted_x; such that the code compiles.
Can you use T as the type of a local variable or the return type of the function?
What methods can be called on downcasted_x?
Assuming that Type runtime variables can be used as the static type of a variable, is this a compile-time type error?
fn types(foo: Type, bar: Type, baz: foo) -> bar {
baz
}
since the above code is the runtime-type equivalent of this generic function:
fn types<foo, bar>(baz: foo) -> bar {
baz
}
which errors at definition time (which means that it errors even without any callers) because foo isn't proven to be the same type as bar for all possible invocations.
I'm leaving other questions for later, this is just the basics to understand as a user of the language what you're proposing even is.