Skip to content

Commit 7a38a7d

Browse files
committed
v2: remove all remaining type fallbacks from Transformer.get_expr_type()
1 parent 32f2669 commit 7a38a7d

1 file changed

Lines changed: 0 additions & 229 deletions

File tree

‎vlib/v2/transformer/transformer.v‎

Lines changed: 0 additions & 229 deletions
Original file line numberDiff line numberDiff line change
@@ -11618,235 +11618,6 @@ fn (t &Transformer) get_expr_type(expr ast.Expr) ?types.Type {
1161811618
return typ
1161911619
}
1162011620
}
11621-
// Handle literal types by looking up their type in the scope
11622-
if expr is ast.StringLiteral || expr is ast.StringInterLiteral {
11623-
if mut scope := t.get_current_scope() {
11624-
if obj := scope.lookup_parent('string', 0) {
11625-
return obj.typ()
11626-
}
11627-
}
11628-
}
11629-
if expr is ast.BasicLiteral {
11630-
if expr.kind == .string {
11631-
if mut scope := t.get_current_scope() {
11632-
if obj := scope.lookup_parent('string', 0) {
11633-
return obj.typ()
11634-
}
11635-
}
11636-
}
11637-
}
11638-
// Handle pointer type expressions like &Type
11639-
if expr is ast.PrefixExpr && expr.op == token.Token.amp {
11640-
inner_type := t.get_expr_type(expr.expr) or { return none }
11641-
return types.Pointer{
11642-
base_type: inner_type
11643-
}
11644-
}
11645-
// Handle modifier expressions like mut Type
11646-
if expr is ast.ModifierExpr {
11647-
return t.get_expr_type(expr.expr)
11648-
}
11649-
if expr is ast.Ident {
11650-
// Look up variable type from scope
11651-
if var_type := t.lookup_var_type(expr.name) {
11652-
return var_type
11653-
}
11654-
// Fall back to current scope lookup
11655-
if mut scope := t.get_current_scope() {
11656-
if obj := scope.lookup_parent(expr.name, 0) {
11657-
return obj.typ()
11658-
}
11659-
}
11660-
// Fallback to the checker's position-based cache when scope lookup fails.
11661-
// This is needed for locals that live only in nested scopes (the transformer does
11662-
// not have those checker scopes), and for synthesized scopes during lowering.
11663-
if pos.is_valid() {
11664-
if typ := t.env.get_expr_type(pos.id) {
11665-
return typ
11666-
}
11667-
}
11668-
return none
11669-
}
11670-
if expr is ast.IndexExpr {
11671-
// For slicing (a[i..j]), the result type is the same as the source
11672-
if expr.expr is ast.RangeExpr {
11673-
return t.get_expr_type(expr.lhs)
11674-
}
11675-
// For array/map indexing (a[i] or m[k]), get the element/value type
11676-
lhs_type := t.get_expr_type(expr.lhs) or { return none }
11677-
if lhs_type is types.Array {
11678-
return lhs_type.elem_type
11679-
}
11680-
if lhs_type is types.ArrayFixed {
11681-
return lhs_type.elem_type
11682-
}
11683-
if lhs_type is types.Map {
11684-
return lhs_type.value_type
11685-
}
11686-
}
11687-
// Handle array type expressions (for receiver types like []Expr)
11688-
if expr is ast.Type {
11689-
if expr is ast.ArrayType {
11690-
elem_type := t.get_expr_type(expr.elem_type) or { return none }
11691-
return types.Array{
11692-
elem_type: elem_type
11693-
}
11694-
}
11695-
if expr is ast.ArrayFixedType {
11696-
elem_type := t.get_expr_type(expr.elem_type) or { return none }
11697-
mut len := 0
11698-
if expr.len is ast.BasicLiteral && expr.len.kind == .number {
11699-
len = expr.len.value.int()
11700-
}
11701-
return types.ArrayFixed{
11702-
len: len
11703-
elem_type: elem_type
11704-
}
11705-
}
11706-
}
11707-
// Handle cast expressions - type is the target type
11708-
if expr is ast.CastExpr {
11709-
return t.get_expr_type(expr.typ)
11710-
}
11711-
// Handle function calls - look up return type
11712-
if expr is ast.CallExpr {
11713-
mut fn_name := ''
11714-
mut mod_name := ''
11715-
if expr.lhs is ast.Ident {
11716-
fn_name = expr.lhs.name
11717-
} else if expr.lhs is ast.SelectorExpr {
11718-
sel := expr.lhs as ast.SelectorExpr
11719-
// Check for module.function call
11720-
if sel.lhs is ast.Ident {
11721-
mod_name = (sel.lhs as ast.Ident).name
11722-
fn_name = sel.rhs.name
11723-
}
11724-
}
11725-
if fn_name != '' {
11726-
// Look up function return type from environment
11727-
if mod_name != '' {
11728-
if fn_type := t.env.lookup_fn(mod_name, fn_name) {
11729-
if ret_type := fn_type.get_return_type() {
11730-
return ret_type
11731-
}
11732-
}
11733-
} else if t.cur_module != '' {
11734-
// Try current module first
11735-
if fn_type := t.env.lookup_fn(t.cur_module, fn_name) {
11736-
if ret_type := fn_type.get_return_type() {
11737-
return ret_type
11738-
}
11739-
}
11740-
}
11741-
// Try builtin
11742-
if fn_type := t.env.lookup_fn('builtin', fn_name) {
11743-
if ret_type := fn_type.get_return_type() {
11744-
return ret_type
11745-
}
11746-
}
11747-
}
11748-
}
11749-
// Handle single-arg function calls or type casts (CallOrCastExpr)
11750-
if expr is ast.CallOrCastExpr {
11751-
mut fn_name := ''
11752-
mut mod_name := ''
11753-
if expr.lhs is ast.Ident {
11754-
fn_name = expr.lhs.name
11755-
} else if expr.lhs is ast.SelectorExpr {
11756-
sel := expr.lhs as ast.SelectorExpr
11757-
if sel.lhs is ast.Ident {
11758-
mod_name = (sel.lhs as ast.Ident).name
11759-
fn_name = sel.rhs.name
11760-
}
11761-
}
11762-
if fn_name != '' {
11763-
// If name starts with uppercase, it might be a type cast (e.g., ast.Expr(value))
11764-
if fn_name.len > 0 && fn_name[0] >= `A` && fn_name[0] <= `Z` {
11765-
// Try looking up as a type first
11766-
if typ := t.get_expr_type(expr.lhs) {
11767-
return typ
11768-
}
11769-
}
11770-
if mod_name != '' {
11771-
if fn_type := t.env.lookup_fn(mod_name, fn_name) {
11772-
if ret_type := fn_type.get_return_type() {
11773-
return ret_type
11774-
}
11775-
}
11776-
} else if t.cur_module != '' {
11777-
if fn_type := t.env.lookup_fn(t.cur_module, fn_name) {
11778-
if ret_type := fn_type.get_return_type() {
11779-
return ret_type
11780-
}
11781-
}
11782-
}
11783-
// Try builtin module for transformed calls like int__str(x),
11784-
// which are represented as CallOrCastExpr with one argument.
11785-
if fn_type := t.env.lookup_fn('builtin', fn_name) {
11786-
if ret_type := fn_type.get_return_type() {
11787-
return ret_type
11788-
}
11789-
}
11790-
}
11791-
}
11792-
// Handle MapInitExpr (for literal maps like {'a': 1, 'b': 2})
11793-
if expr is ast.MapInitExpr {
11794-
// Helper to get string type from scope
11795-
mut string_type := types.Type(types.Primitive{
11796-
size: 64
11797-
props: .integer
11798-
})
11799-
if mut scope := t.get_current_scope() {
11800-
if obj := scope.lookup_parent('string', 0) {
11801-
string_type = obj.typ()
11802-
}
11803-
}
11804-
int_type := types.Type(types.Primitive{
11805-
size: 64
11806-
props: .integer
11807-
})
11808-
11809-
// Check if map has explicit type
11810-
match expr.typ {
11811-
ast.Type {
11812-
if expr.typ is ast.MapType {
11813-
mt := expr.typ as ast.MapType
11814-
key_type := t.get_expr_type(mt.key_type) or { string_type }
11815-
value_type := t.get_expr_type(mt.value_type) or { int_type }
11816-
return types.Map{
11817-
key_type: key_type
11818-
value_type: value_type
11819-
}
11820-
}
11821-
}
11822-
else {}
11823-
}
11824-
// Infer from first key/value (for literal maps like {'a': 1})
11825-
if expr.keys.len > 0 {
11826-
first_key := expr.keys[0]
11827-
first_val := expr.vals[0]
11828-
mut key_type := int_type
11829-
mut val_type := int_type
11830-
if first_key is ast.StringLiteral {
11831-
key_type = string_type
11832-
} else if first_key is ast.BasicLiteral {
11833-
if first_key.kind == .string {
11834-
key_type = string_type
11835-
}
11836-
}
11837-
if first_val is ast.StringLiteral {
11838-
val_type = string_type
11839-
} else if first_val is ast.BasicLiteral {
11840-
if first_val.kind == .string {
11841-
val_type = string_type
11842-
}
11843-
}
11844-
return types.Map{
11845-
key_type: key_type
11846-
value_type: val_type
11847-
}
11848-
}
11849-
}
1185011621
return none
1185111622
}
1185211623

0 commit comments

Comments
 (0)