Design: how do generic container instantiations resolve to a concrete Ty #69
Labels
No labels
bug
design
epic
risk
user-story
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
jacksonopp/twill#69
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Surfaced while implementing #56/#57 (array/map literal checking) — both issues cite #6 as the blocking dependency for their result type ("no TyKind variant exists yet for a generic container instantiation... needs that settled first"), but #6 is closed and never actually covered this. #6 was narrower: treating T: type as an ordinary parameter and List(T)-shaped calls as ordinary function calls type-checking against the abstract T (landed in #53). It didn't resolve how a generic container instantiation resolves to a concrete Ty when used in type-annotation position — resolve_type_expr's TypeExpr::Generic { .. } => None arm (crates/twill-check/src/ty.rs) still leaves this completely unhandled today.
This issue is that actual open question. Two real directions, not just "add an enum variant":
Currently #56/#57 land with a placeholder result type (e.g. the array literal's own element type, or None for maps) rather than a real List(T)/Array(T, N)/Map(K, V) Ty, specifically because of this open question. #56/#57's own descriptions should get their "Dependency" note repointed here instead of #6.
Landed with a narrower scope than originally written up:
List(T)-shaped generic-call resolution is done end to end: a newfn_declsalsa query looks up a callee's declaration by name within a givenSourceFile, andevaluate_generic_callcomptime-evaluates the body under substitutedT: typebindings to produce a realTy(reusingcheck_struct/check_exprrather than adding a dedicated containerTyKind— the 'general comptime evaluation' direction from the original writeup, not the special-cased-variants one).TypeExpr::Pointer->TyKind::Pointer) landed as a prerequisite, sinceList's own body (items: *T) needed it.check_array_literal/check_map_literal's bare/typed cases too, so[1, 2, 3],[]Int[1, 2, 3], and bothMapliteral forms now resolve to realList(T)/Map(K, V)shapes instead of the old placeholder result types.Array'sComptime(Int)size and the generalComptime(_)-value-param machinery got split to #71 -- corrected from the original writeup along the way:Map(K, V)'s params are both plaintype-kinded, so it needed noComptimesupport and already works via the same mechanism asListonce aMapdecl exists somewhere to find. OnlyArrayis actually blocked on #71.List/Array/Mapbecome available without a user declaring them inline in every file (a builtin/prelude, not a general importable std library) got split to #72 -- every test here declaresList/Mapinline in the checked source, sincefn_declonly searches the given file.