redscript icon indicating copy to clipboard operation
redscript copied to clipboard

Struct inheritance

Open psiberx opened this issue 3 years ago • 5 comments

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>;
}

psiberx avatar Aug 08 '22 17:08 psiberx

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?

psiberx avatar Aug 08 '22 18:08 psiberx

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)
}

jac3km4 avatar Aug 08 '22 21:08 jac3km4

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

jac3km4 avatar Aug 08 '22 21:08 jac3km4

I guess the simplest thing to do would be to disallow having abstract structs as fields at all

jac3km4 avatar Aug 08 '22 21:08 jac3km4

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.

psiberx avatar Aug 24 '22 16:08 psiberx