E81071: a closeable made but never named in the arguments of 'super(...)' or 'this(...)' can never be closed - nothing can surround a construction call; make the value in a function and pass the result ('super(freshDescription())'), or take the closeable as a constructor parameter
What went wrong
A closeable value is made, and never named, inside the ARGUMENTS of an explicit 'super(...)' or 'this(...)' - for example 'super(describe(Res()))', where 'Res' has an 'operator close'.
Everywhere else an unnamed closeable is owned by the evaluation that made it and closed, protected, as soon as that evaluation finishes. That close needs a protected region around the statement. A construction call must be the first statement of a constructor (E05050), so nothing - not even a 'try' - can surround it, and the JVM rejects a protected region that covers it. Closing the value before the call would hand the super constructor a closed value; closing it after would leak it whenever the super constructor fails. So the value has no owner that can close it.
Only these two call sites are affected. An unnamed closeable in any later statement of the constructor is closed by that statement as usual.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 1520 (When does EK9 close a closeable value, and where may I keep one?)
How to fix it
Make the value in a function and pass the function's result ('super(freshDescription())'): the function's own statement owns the closeable and closes it before the construction call (good.ek9 in the [EXAMPLE] section below).
Or, when the caller should decide how long the resource lives, take it as a constructor parameter: the caller acquires it in a 'try' and lends it.
Common causes
- Computing a constructor argument inline from a resource: reading a file, a connection or a handle to produce the text the super type needs.
- Moving a statement that made a closeable into the 'super(...)' call while removing a local variable.
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E81071: a closeable made but never named in the arguments of 'super(...)' or 'this(...)' can never be closed - nothing can surround a construction call; make the value in a function and pass the result ('super(freshDescription())'), or take the closeable as a constructor parameter
#!ek9 defines module error.e81071.bad defines class Res name as String? default private Res() Res() -> label as String name: label read() as pure <- rtn as String: `read ${name}` default operator ? operator close as pure stdout <- Stdout() stdout.println(`closed ${name}`) Base as open text as String? default private Base() Base() -> text as String this.text: text default operator ? Child extends Base Child() super(describe(Res("journal"))) defines function describe() -> res as Res <- rtn as String: res.read()
Fixed: Make the value in a function and pass the result - the function's statement closes it
#!ek9 defines module error.e81071.good defines class Res name as String? default private Res() Res() -> label as String name: label read() as pure <- rtn as String: `read ${name}` default operator ? operator close as pure stdout <- Stdout() stdout.println(`closed ${name}`) Base as open text as String? default private Base() Base() -> text as String this.text: text default operator ? Child extends Base Child() super(freshDescription()) defines function describe() -> res as Res <- rtn as String: res.read() freshDescription() <- rtn as String: describe(Res("journal"))