Where is type inference not supported in generic type and function bodies?
← Generics · Ref: Q646
Inside a generic type or function body, EK9 does not support type inference for local variables at all (E06070). Every local declared with '<-' needs an explicit type, even when the value does not depend on T (for example 'counter as Integer: 0', not 'counter <- 0').
INFERENCE LIMITATION
Inside a generic definition the compiler rejects every '<-' declaration, whether or not the type involves T. Declare locals with an explicit type: 'counter as Integer: 0', 'copy as T: T(item)'.
EXPLICIT RETURN TYPES
Generic functions must declare return types explicitly:
defines function transform() of type (S, T) as open -> source as S <- target as T: source? <- T() else T()
FIELD DECLARATIONS
Fields in generic classes must use the type parameter explicitly:
Container of type T item as T: T()
WHEN INFERENCE WORKS
Type inference works at the CALL SITE, not inside the generic body:
intContainer <- Container(42) // inference works here
But inside Container's methods, T must be used explicitly.
See Q642 for constructor inference at call site. See Q648 for function constraints. See Q194 for generic class basics.
Example
defines module qa.genericsdeep.inferencelimits defines function <?- Correct: explicit types used throughout the generic body. Return type explicitly declared as T. -?> identity() of type T as open -> item as T <- rtn as T: T(item) <?- Correct: multi-param generic with explicit return type. Both S and T used with explicit type annotations. -?> converter() of type (S, T) as open -> source as S <- target as T? require source? target: T() defines class <?- Correct: all fields and method return types use T explicitly. No reliance on type inference inside the generic body. -?> Stack of type T items as List of T? Stack() items :=? List() of T Stack() -> initial as T items: List() of T items += initial push() -> item as T if not items? items: List() of T items += item count() as pure <- rtn as Integer: 0 if items? rtn: length items default operator ? defines program InferenceLimitsDemo() stdout <- Stdout() // === INFERENCE AT CALL SITE (works) === result <- identity(42) stdout.println(`Identity: ${result}`) // === EXPLICIT TYPE AT CALL SITE === stack <- Stack("first") stack.push("second") stack.push("third") stdout.println(`Stack count: ${stack.count()}`)
Common mistakes
E50060 — Integer has no toString() method in EK9. Use the $ prefix operator or string interpolation. See ek9 -h E50060 for details.
Incorrect:
stdout.println(stack.count().toString())
Correct:
stdout.println(`Stack count: ${stack.count()}`)
Other ways to ask this
- What is E06070 type inference not supported in generic context?
- When must I use explicit types inside generic definitions?
- Why cannot I use type inference inside a generic class body?
Coming from another language?
Java: type inference works inside generics (var keyword, diamond). C++: auto deduction inside templates. Rust: type inference inside generic functions with compiler assistance. Go: type inference limited inside generics too. Kotlin: type inference works inside generic bodies. EK9: no '<-' inference inside generic bodies (E06070), every local needs an explicit type.
Keywords: explicit, inference, function, parameter, limitation, body, generic, type, context, E06070, type-parameter