E07440: return types are incompatible (covariance required)
What went wrong
An overriding method returns a type that's incompatible with the base method's return type. The return type must be the same as, or a subtype of, the return type of EVERY parent that declares the method - the super class and each trait. When two parents promise types no single type satisfies (Integer and String), no override can honour both.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 699 (What are the return type and parameter type rules for met...)
How to fix it
- Use same return type as base
- Or use covariant (subtype) return
Common causes
- Different return type than parent
- Non-covariant return
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E07440: return types are incompatible (covariance required)
#!ek9 defines module error.e07440.bad <?- Just use these for valid covariance checks. -?> defines record R1 as open someField <- "Field1" default operator ? R2 extends R1 anotherField <- "Field2" default operator ? <?- Something that is unrelated to R1 or R2. To be used later in tests. -?> R3 unrelatedField <- "Field3" default operator ? defines class C1 as open someMethod1() -> text as String <- rtn as Float: 1.0 someMethod2() -> text as String <- rtn as R1: R1() someMethod3() -> text as String <- rtn as R1: R1() //Something that has no return mainValue to be used in covariance checks later someMethod4() -> text as String require text? <?- Extend an override the C1 someMethod1 method but alter the return type so that it incompatible with the class C1 -?> C2 extends C1 override someMethod1() -> text as String <- rtn as String: "Test" <?- just a normal override no covariance issues or use. -?> override someMethod2() -> text as String <- rtn as R1: R1() <?- Again override and should be OK because this is valid as it is a 'R1'. But this does not test covariance! -?> override someMethod3() -> text as String <- rtn as R1: R2() <?- A valid override of a method -?> override someMethod4() -> text as String require text? <?- Now even though an Integer can be coerced to a Float - it is not 'covariant'. -?> C3 extends C1 override someMethod1() -> text as String <- rtn as Integer: 1 <?- Again override and should be OK because this is valid covariance. Note that we have altered the return type. -?> override someMethod2() -> text as String <- rtn as R2: R2() <?- But R3 is not a 'R1' and therefore this is not valid covariance. -?> override someMethod3() -> text as String <- rtn as R3: R3() <?- Cannot start adding return types when super is not returning anything. -?> override someMethod4() -> text as String <- rtn as R3: R3() require text? C4 extends C1 <?- Normal valid override -?> override someMethod1() -> text as String <- rtn as Float: 1.0 <?- Must return a covariant compatible type. -?> override someMethod2() -> text as String require text? <?- But Integer '9' is not a 'R1' and therefore this is not valid covariance. -?> override someMethod3() -> text as String <- rtn <- 9 <?- Another valid override -?> override someMethod4() -> text as String require text?
Fixed: Return the super's type, or a sub-type of it
#!ek9 defines module error.e07440.good defines record Shape as open name <- "shape" default operator ? Square extends Shape side <- 2 default operator ? defines class Factory as open make() <- rtn as Shape: Shape() //Covariant: a Square IS a Shape SquareFactory extends Factory override make() <- rtn as Square: Square()
Questions and answers
These Q&A entries show E07440 and its fix: