Struct inheritance
Changes:
- Struct can be abstract
- Struct can be inherited from another struct
- New error causes
- class C can't inherit struct S
- struct S can't inherit class C
The main purpose is to get access to more native structs:
public abstract native struct ISerializable {}
public abstract native struct CResource extends ISerializable {}
public native struct inkHudEntriesResource extends CResource {
public native let entries: array<inkHudWidgetSpawnEntry>;
}
A controversial moment with abstract structs is instantiation. The Construct op doesn't check for abstract flag, so effectively anything can be constructed. It's easy to check the flag for new, but I don't see how declarations let a: A could be handled. Maybe it's better to just disallow abstract modifier for scripted structs, but allow for imports?
I think declarations could be checked, the line here is responsible for checking declarations without an initializer: https://github.com/jac3km4/redscript/blob/master/compiler/src/typechecker.rs#L111 it could look like this:
(Some(type_name), None) => {
let resolved = scope.resolve_type(type_name, self.pool).with_span(*span)?;
if let TypeId::Struct(idx) = resolved {
if self.pool.class(idx)?.flags.is_abstract() {
self.report(Cause::InstantiatingAbstract(type_name.pretty()).with_span(*span))?;
}
}
(None, resolved)
}
I've thought about this, and there's still a problem of fields that have an abstract type but exist on a non-abstract type, they'd need to be handled too and that would be a bit more difficult to do, because information about abstract-ness of types is only checked when fields are processed. I can think of a way to do it, but it'll complicate things
I guess the simplest thing to do would be to disallow having abstract structs as fields at all
True, I think it makes sense to disallow them as fields.
There's another problem with the ISerializable type though. This is a struct, but it must be a ref<>. Although refs support ISerializable, the New opcode only works for IScriptable. It can be accessed, but can't be created and assigned.