v / vlib / v2 / ssa / build_as_cast_from_flat_test.v
100 lines · 92 sloc · 2.74 KB · 07d7d0a475915ac672c8ed1ed3128131e29be755
Raw
1// Copyright (c) 2026 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4// vtest build: macos
5//
6// Bit-equality pin for the cursor-native rewrite of `build_as_cast_from_flat`.
7// The previous helper decoded both AsCastExpr edges via `decode_expr` and
8// dispatched to legacy `build_as_cast`; the cursor-native rewrite mirrors
9// `build_as_cast` directly: `build_expr_from_flat(expr_c)` produces the value,
10// `ast_type_to_ssa_from_flat(typ_c)` resolves the target type, and
11// `get_checked_expr_type_from_flat(expr_c)` retrieves the checked source type
12// (only consulted for the sumtype-source branch). This pin uses a same-type
13// passthrough cast so legacy + flat both take the `values[val].typ ==
14// target_type` short-circuit and emit identical IR.
15module ssa
16
17import v2.ast
18import v2.types
19
20fn ac_ident(name string) ast.Expr {
21 return ast.Expr(ast.Ident{
22 name: name
23 })
24}
25
26fn ac_num(value string) ast.Expr {
27 return ast.Expr(ast.BasicLiteral{
28 kind: .number
29 value: value
30 })
31}
32
33fn make_as_cast_fixture() []ast.File {
34 mut stmts := [
35 ast.Stmt(ast.ModuleStmt{
36 name: 'main'
37 }),
38 ]
39 // fn passthrough() i64 { x := i64(7) return x as i64 }
40 stmts << ast.Stmt(ast.FnDecl{
41 name: 'passthrough'
42 typ: ast.FnType{
43 return_type: ac_ident('i64')
44 }
45 stmts: [
46 ast.Stmt(ast.AssignStmt{
47 op: .decl_assign
48 lhs: [ac_ident('x')]
49 rhs: [ast.Expr(ast.CastExpr{
50 typ: ac_ident('i64')
51 expr: ac_num('7')
52 })]
53 }),
54 ast.Stmt(ast.ReturnStmt{
55 exprs: [
56 ast.Expr(ast.AsCastExpr{
57 expr: ac_ident('x')
58 typ: ac_ident('i64')
59 }),
60 ]
61 }),
62 ]
63 })
64 return [
65 ast.File{
66 name: 'main.v'
67 mod: 'main'
68 stmts: stmts
69 },
70 ]
71}
72
73fn build_via_legacy_as_cast(files []ast.File, env &types.Environment, name string) &Module {
74 mut mod := Module.new(name)
75 mut b := Builder.new_with_env(mod, env)
76 b.register_fn_signatures(files[0])
77 b.build_fn_bodies(files[0])
78 return mod
79}
80
81fn build_via_flat_as_cast(files []ast.File, env &types.Environment, name string) &Module {
82 flat := ast.flatten_files(files)
83 mut mod := Module.new(name)
84 mut b := Builder.new_with_env(mod, env)
85 b.register_fn_signatures_from_flat(flat.file_cursor(0))
86 b.build_fn_bodies_from_flat(flat.file_cursor(0))
87 return mod
88}
89
90fn test_build_as_cast_from_flat_matches_legacy() {
91 files := make_as_cast_fixture()
92 env := types.Environment.new()
93 mod_legacy := build_via_legacy_as_cast(files, env, 'as_cast_legacy')
94 mod_flat := build_via_flat_as_cast(files, env, 'as_cast_flat')
95
96 assert mod_legacy.funcs.len == mod_flat.funcs.len
97 assert mod_legacy.blocks.len == mod_flat.blocks.len
98 assert mod_legacy.instrs.len == mod_flat.instrs.len
99 assert mod_legacy.values.len == mod_flat.values.len
100}
101