parser: warn about old use of `typeof` (#7923)

pull/7952/head
Nick Treleaven 2021-01-07 19:32:02 +00:00 committed by GitHub
parent a2add15558
commit cbefe6c32f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 93 additions and 92 deletions

View File

@ -9,14 +9,14 @@ fn test_clone() {
xx := byte(35) xx := byte(35)
assert xx.str() == '35' assert xx.str() == '35'
assert xx.ascii_str() == '#' assert xx.ascii_str() == '#'
println(typeof(`A`)) println(typeof(`A`).name)
assert typeof(`A`) == 'rune' assert typeof(`A`).name == 'rune'
x := rune(`A`) x := rune(`A`)
assert x.str() == 'A' assert x.str() == 'A'
assert typeof(x) == 'rune' assert typeof(x).name == 'rune'
// //
y := `Z` y := `Z`
assert typeof(y) == 'rune' assert typeof(y).name == 'rune'
assert y.str() == 'Z' assert y.str() == 'Z'
// assert b[1].str() == '1' TODO // assert b[1].str() == '1' TODO
} }

View File

@ -5,34 +5,34 @@ fn test_float_decl() {
x2 := -2e16 x2 := -2e16
x3 := 1e-15 x3 := 1e-15
x4 := -9e-4 x4 := -9e-4
assert typeof(x1) == 'f64' assert typeof(x1).name == 'f64'
assert typeof(x2) == 'f64' assert typeof(x2).name == 'f64'
assert typeof(x3) == 'f64' assert typeof(x3).name == 'f64'
assert typeof(x4) == 'f64' assert typeof(x4).name == 'f64'
x5 := 4e108 x5 := 4e108
x6 := -7e99 x6 := -7e99
x7 := 3e-205 x7 := 3e-205
x8 := -6e-147 x8 := -6e-147
assert typeof(x5) == 'f64' assert typeof(x5).name == 'f64'
assert typeof(x6) == 'f64' assert typeof(x6).name == 'f64'
assert typeof(x7) == 'f64' assert typeof(x7).name == 'f64'
assert typeof(x8) == 'f64' assert typeof(x8).name == 'f64'
x9 := 312874834.77 x9 := 312874834.77
x10 := -22399994.06 x10 := -22399994.06
x11 := 0.0000000019 x11 := 0.0000000019
x12 := -0.00000000008 x12 := -0.00000000008
assert typeof(x9) == 'f64' assert typeof(x9).name == 'f64'
assert typeof(x10) == 'f64' assert typeof(x10).name == 'f64'
assert typeof(x11) == 'f64' assert typeof(x11).name == 'f64'
assert typeof(x12) == 'f64' assert typeof(x12).name == 'f64'
x13 := 34234234809890890898903213154353453453253253243432413232228908902183918392183902432432438980380123021983901392183921389083913890389089031.0 x13 := 34234234809890890898903213154353453453253253243432413232228908902183918392183902432432438980380123021983901392183921389083913890389089031.0
x14 := -39999999999999999999222212128182813294989082302832183928343325325233253242312331324392839238239829389038097438248932789371837218372837293.8 x14 := -39999999999999999999222212128182813294989082302832183928343325325233253242312331324392839238239829389038097438248932789371837218372837293.8
x15 := 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002 x15 := 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002
x16 := -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004 x16 := -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004
assert typeof(x13) == 'f64' assert typeof(x13).name == 'f64'
assert typeof(x14) == 'f64' assert typeof(x14).name == 'f64'
assert typeof(x15) == 'f64' assert typeof(x15).name == 'f64'
assert typeof(x16) == 'f64' assert typeof(x16).name == 'f64'
} }
fn test_f32_equal_operator() { fn test_f32_equal_operator() {

View File

@ -177,13 +177,13 @@ fn test_int_decl() {
x3 := -88955 x3 := -88955
x4 := 2000000000 x4 := 2000000000
x5 := -1999999999 x5 := -1999999999
assert typeof(x1) == 'int' assert typeof(x1).name == 'int'
assert typeof(x2) == 'int' assert typeof(x2).name == 'int'
assert typeof(x3) == 'int' assert typeof(x3).name == 'int'
assert typeof(x4) == 'int' assert typeof(x4).name == 'int'
assert typeof(x5) == 'int' assert typeof(x5).name == 'int'
x7 := u64(-321314588900011) x7 := u64(-321314588900011)
assert typeof(x7) == 'u64' assert typeof(x7).name == 'u64'
} }
fn test_int_to_hex() { fn test_int_to_hex() {

View File

@ -536,8 +536,8 @@ fn test_bytes_to_string() {
fn test_charptr() { fn test_charptr() {
foo := charptr('VLANG'.str) foo := charptr('VLANG'.str)
println(typeof(foo)) println(typeof(foo).name)
assert typeof(foo) == 'charptr' assert typeof(foo).name == 'charptr'
assert unsafe { foo.vstring() } == 'VLANG' assert unsafe { foo.vstring() } == 'VLANG'
assert unsafe { foo.vstring_with_len(3) } == 'VLA' assert unsafe { foo.vstring_with_len(3) } == 'VLA'
} }

View File

@ -1217,11 +1217,11 @@ pub fn (stmt Stmt) check_c_expr() ? {
if stmt.expr.is_expr() { if stmt.expr.is_expr() {
return return
} }
return error('unsupported statement (`${typeof(stmt.expr)}`)') return error('unsupported statement (`$stmt.expr.type_name()`)')
} }
else {} else {}
} }
return error('unsupported statement (`${typeof(stmt)}`)') return error('unsupported statement (`$stmt.type_name()`)')
} }
// CTempVar is used in cgen only, to hold nodes for temporary variables // CTempVar is used in cgen only, to hold nodes for temporary variables

View File

@ -288,7 +288,7 @@ pub fn (x Expr) str() string {
} }
else {} else {}
} }
return '[unhandled expr type ${typeof(x)}]' return '[unhandled expr type $x.type_name()]'
} }
pub fn (a CallArg) str() string { pub fn (a CallArg) str() string {
@ -352,7 +352,7 @@ pub fn (node Stmt) str() string {
return 'struct $node.name { $node.fields.len fields }' return 'struct $node.name { $node.fields.len fields }'
} }
else { else {
return '[unhandled stmt str type: ${typeof(node)} ]' return '[unhandled stmt str type: $node.type_name() ]'
} }
} }
} }

View File

@ -1086,11 +1086,11 @@ fn (mut c Checker) fail_if_immutable(expr ast.Expr) (string, token.Position) {
return '', pos return '', pos
} }
else { else {
c.error('unexpected expression `${typeof(expr)}`', expr.position()) c.error('unexpected expression `$expr.type_name()`', expr.position())
} }
} }
if explicit_lock_needed { if explicit_lock_needed {
c.error('`$to_lock` is `shared` and needs explicit lock for `${typeof(expr)}`', c.error('`$to_lock` is `shared` and needs explicit lock for `$expr.type_name()`',
pos) pos)
to_lock = '' to_lock = ''
} }
@ -1547,7 +1547,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
} else if fn_name == 'json.decode' && call_expr.args.len > 0 { } else if fn_name == 'json.decode' && call_expr.args.len > 0 {
expr := call_expr.args[0].expr expr := call_expr.args[0].expr
if expr !is ast.Type { if expr !is ast.Type {
typ := typeof(expr) typ := expr.type_name()
c.error('json.decode: first argument needs to be a type, got `$typ`', call_expr.pos) c.error('json.decode: first argument needs to be a type, got `$typ`', call_expr.pos)
return table.void_type return table.void_type
} }
@ -4428,7 +4428,7 @@ fn (mut c Checker) comp_if_branch(cond ast.Expr, pos token.Position) bool {
!different !different
} }
} else { } else {
c.error('invalid `\$if` condition: ${typeof(cond.left)}', cond.pos) c.error('invalid `\$if` condition: $cond.left.type_name()', cond.pos)
} }
} }
else { else {

View File

@ -3,5 +3,5 @@ vlib/v/checker/tests/comparing_typesymbol_to_a_type_should_not_compile.vv:12:12:
11 | // the next line should produce at least a warning, or even an error, without an explicit cast: 11 | // the next line should produce at least a warning, or even an error, without an explicit cast:
12 | z := isym == table.string_type 12 | z := isym == table.string_type
| ~~ | ~~
13 | println(typeof(isym)) 13 | println(typeof(isym).name)
14 | println(typeof(table.string_type)) 14 | println(typeof(table.string_type).name)

View File

@ -10,8 +10,8 @@ fn main() {
x := ityp == table.string_type x := ityp == table.string_type
// the next line should produce at least a warning, or even an error, without an explicit cast: // the next line should produce at least a warning, or even an error, without an explicit cast:
z := isym == table.string_type z := isym == table.string_type
println(typeof(isym)) println(typeof(isym).name)
println(typeof(table.string_type)) println(typeof(table.string_type).name)
println(x) println(x)
println(z) println(z)
} }

View File

@ -255,7 +255,7 @@ pub fn (mut f Fmt) stmt_str(node ast.Stmt) string {
pub fn (mut f Fmt) stmt(node ast.Stmt) { pub fn (mut f Fmt) stmt(node ast.Stmt) {
if f.is_debug { if f.is_debug {
eprintln('stmt: ${node.position():-42} | node: ${typeof(node):-20}') eprintln('stmt: ${node.position():-42} | node: ${node.type_name():-20}')
} }
match node { match node {
ast.AssignStmt { ast.AssignStmt {
@ -854,7 +854,7 @@ pub fn (mut f Fmt) prefix_expr_cast_expr(fexpr ast.Expr) {
pub fn (mut f Fmt) expr(node ast.Expr) { pub fn (mut f Fmt) expr(node ast.Expr) {
if f.is_debug { if f.is_debug {
eprintln('expr: ${node.position():-42} | node: ${typeof(node):-20} | $node.str()') eprintln('expr: ${node.position():-42} | node: ${node.type_name():-20} | $node.str()')
} }
match mut node { match mut node {
ast.CTempVar { ast.CTempVar {

View File

@ -823,7 +823,7 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) {
} }
if stmt_pos.pos == 0 { if stmt_pos.pos == 0 {
print('autofree: first stmt pos = 0. ') print('autofree: first stmt pos = 0. ')
println(typeof(stmt)) println(stmt.type_name())
return return
} }
} }
@ -1550,7 +1550,7 @@ fn (mut g Gen) gen_assert_single_expr(e ast.Expr, t table.Type) {
g.gen_expr_to_string(e, t) g.gen_expr_to_string(e, t)
} }
} }
g.write(' /* typeof: ' + typeof(e) + ' type: ' + t.str() + ' */ ') g.write(' /* typeof: ' + e.type_name() + ' type: ' + t.str() + ' */ ')
} }
fn (mut g Gen) write_fn_ptr_decl(func &table.FnType, ptr_name string) { fn (mut g Gen) write_fn_ptr_decl(func &table.FnType, ptr_name string) {
@ -5049,14 +5049,6 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type table.
g.write('}') g.write('}')
} }
fn (mut g Gen) type_of_call_expr(node ast.Expr) string {
match node {
ast.CallExpr { return g.typ(node.return_type) }
else { return typeof(node) }
}
return ''
}
// `a in [1,2,3]` => `a == 1 || a == 2 || a == 3` // `a in [1,2,3]` => `a == 1 || a == 2 || a == 3`
fn (mut g Gen) in_optimization(left ast.Expr, right ast.ArrayInit) { fn (mut g Gen) in_optimization(left ast.Expr, right ast.ArrayInit) {
is_str := right.elem_type == table.string_type is_str := right.elem_type == table.string_type

View File

@ -622,7 +622,7 @@ pub fn (mut g Gen) call_fn(node ast.CallExpr) {
g.mov_var_to_reg(fn_arg_registers[i], var_offset) g.mov_var_to_reg(fn_arg_registers[i], var_offset)
} }
else { else {
verror('unhandled call_fn (name=$name) node: ' + typeof(expr)) verror('unhandled call_fn (name=$name) node: ' + expr.type_name())
} }
} }
} }
@ -671,7 +671,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
} }
ast.StructDecl {} ast.StructDecl {}
else { else {
println('x64.stmt(): bad node: ' + typeof(node)) println('x64.stmt(): bad node: ' + node.type_name())
} }
} }
} }
@ -704,7 +704,7 @@ fn (mut g Gen) expr(node ast.Expr) {
ast.StringLiteral {} ast.StringLiteral {}
ast.StructInit {} ast.StructInit {}
else { else {
println(term.red('x64.expr(): unhandled node: ' + typeof(node))) println(term.red('x64.expr(): unhandled node: ' + node.type_name()))
} }
} }
} }
@ -775,7 +775,8 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) {
} }
} }
else { else {
g.error_with_pos('x64 assign_stmt unhandled expr: ' + typeof(right), right.position()) g.error_with_pos('x64 assign_stmt unhandled expr: ' + right.type_name(),
right.position())
} }
} }
// } // }

View File

@ -187,6 +187,10 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
p.check(.lpar) p.check(.lpar)
expr := p.expr(0) expr := p.expr(0)
p.check(.rpar) p.check(.rpar)
if p.tok.kind != .dot && p.tok.line_nr == p.prev_tok.line_nr {
p.warn_with_pos('use e.g. `typeof(expr).name` or `sum_type_instance.type_name()` instead',
spos)
}
node = ast.TypeOf{ node = ast.TypeOf{
expr: expr expr: expr
pos: spos.extend(p.tok.position()) pos: spos.extend(p.tok.position())

View File

@ -1,27 +1,27 @@
fn test_fixed_array_lit_init() { fn test_fixed_array_lit_init() {
a1 := ['1', '2', '3']!! a1 := ['1', '2', '3']!!
assert typeof(a1) == '[3]string' assert typeof(a1).name == '[3]string'
assert '$a1' == "['1', '2', '3']" assert '$a1' == "['1', '2', '3']"
a2 := ['a', 'b']!! a2 := ['a', 'b']!!
assert typeof(a2) == '[2]string' assert typeof(a2).name == '[2]string'
assert '$a2' == "['a', 'b']" assert '$a2' == "['a', 'b']"
c1 := [1, 2, 3]!! c1 := [1, 2, 3]!!
assert typeof(c1) == '[3]int' assert typeof(c1).name == '[3]int'
assert '$c1' == '[1, 2, 3]' assert '$c1' == '[1, 2, 3]'
c2 := [i16(1), 2, 3]!! c2 := [i16(1), 2, 3]!!
assert typeof(c2) == '[3]i16' assert typeof(c2).name == '[3]i16'
assert '$c2' == '[1, 2, 3]' assert '$c2' == '[1, 2, 3]'
mut c3 := [i64(1), 2, 3]!! mut c3 := [i64(1), 2, 3]!!
assert typeof(c3) == '[3]i64' assert typeof(c3).name == '[3]i64'
assert '$c3' == '[1, 2, 3]' assert '$c3' == '[1, 2, 3]'
mut c4 := [u64(1), 2, 3]!! mut c4 := [u64(1), 2, 3]!!
assert typeof(c4) == '[3]u64' assert typeof(c4).name == '[3]u64'
assert '$c4' == '[1, 2, 3]' assert '$c4' == '[1, 2, 3]'
mut d1 := [1.1, 2.2, 3.3]!! mut d1 := [1.1, 2.2, 3.3]!!
assert typeof(d1) == '[3]f64' assert typeof(d1).name == '[3]f64'
assert '$d1' == '[1.1, 2.2, 3.3]' assert '$d1' == '[1.1, 2.2, 3.3]'
mut d2 := [f32(1.1), 2.2, 3.3]!! mut d2 := [f32(1.1), 2.2, 3.3]!!
assert typeof(d2) == '[3]f32' assert typeof(d2).name == '[3]f32'
assert '$d2' == '[1.1, 2.2, 3.3]' assert '$d2' == '[1.1, 2.2, 3.3]'
} }

View File

@ -9,12 +9,12 @@ fn new_tensor<T>(data BuildData) Tensor {
fn test_generic_function_returning_type_starting_with_t() { fn test_generic_function_returning_type_starting_with_t() {
ft := new_tensor<f64>(x:123) ft := new_tensor<f64>(x:123)
println(ft) println(ft)
assert typeof(ft) == 'Tensor' assert typeof(ft).name == 'Tensor'
assert '$ft' == 'Tensor{\n x: 123\n}' assert '$ft' == 'Tensor{\n x: 123\n}'
// //
it := new_tensor<int>(x:456) it := new_tensor<int>(x:456)
println(it) println(it)
assert typeof(it) == 'Tensor' assert typeof(it).name == 'Tensor'
assert '$it' == 'Tensor{\n x: 456\n}' assert '$it' == 'Tensor{\n x: 456\n}'
} }

View File

@ -4,7 +4,7 @@ import genericmodule
fn test_generic_function_from_another_module() { fn test_generic_function_from_another_module() {
v1 := genericmodule.take<int>(true, 10, 20) v1 := genericmodule.take<int>(true, 10, 20)
assert typeof(v1) == 'int' assert typeof(v1).name == 'int'
assert v1 == 10 assert v1 == 10
v2 := genericmodule.take<int>(false, 10, 20) v2 := genericmodule.take<int>(false, 10, 20)
assert v2 == 20 assert v2 == 20
@ -12,7 +12,7 @@ fn test_generic_function_from_another_module() {
fn test_generic_type_inference_from_another_module() { fn test_generic_type_inference_from_another_module() {
v1 := genericmodule.take(true, 10, 20) v1 := genericmodule.take(true, 10, 20)
assert typeof(v1) == 'int' assert typeof(v1).name == 'int'
assert v1 == 10 assert v1 == 10
v2 := genericmodule.take(false, 10, 20) v2 := genericmodule.take(false, 10, 20)
assert v2 == 20 assert v2 == 20
@ -20,7 +20,7 @@ fn test_generic_type_inference_from_another_module() {
fn test_inference_with_strings() { fn test_inference_with_strings() {
v1 := genericmodule.take(true, 'abc', 'def') v1 := genericmodule.take(true, 'abc', 'def')
assert typeof(v1) == 'string' assert typeof(v1).name == 'string'
assert v1 == 'abc' assert v1 == 'abc'
v2 := genericmodule.take(false, 'abc', 'def') v2 := genericmodule.take(false, 'abc', 'def')
assert v2 == 'def' assert v2 == 'def'
@ -28,7 +28,7 @@ fn test_inference_with_strings() {
fn test_inference_with_f64() { fn test_inference_with_f64() {
v1 := genericmodule.take(true, f64(123), 345) v1 := genericmodule.take(true, f64(123), 345)
assert typeof(v1) == 'f64' assert typeof(v1).name == 'f64'
assert v1 == 123 assert v1 == 123
v2 := genericmodule.take(false, f64(123), 345) v2 := genericmodule.take(false, f64(123), 345)
assert v2 == 345 assert v2 == 345

View File

@ -260,10 +260,10 @@ fn test_generic_struct() {
assert b.permission.name == 'superuser' assert b.permission.name == 'superuser'
println('b.model.name: $b.model.name') println('b.model.name: $b.model.name')
println('b.permission.name: $b.permission.name') println('b.permission.name: $b.permission.name')
assert typeof(a.model) == 'User' assert typeof(a.model).name == 'User'
assert typeof(b.model) == 'Group' assert typeof(b.model).name == 'Group'
println('typeof(a.model): ' + typeof(a.model)) println('typeof(a.model): ' + typeof(a.model).name)
println('typeof(b.model): ' + typeof(b.model)) println('typeof(b.model): ' + typeof(b.model).name)
// mut x := new_repo<User>(DB{}) // mut x := new_repo<User>(DB{})
// x.model.name = 'joe2' // x.model.name = 'joe2'
// println(x.model.name) // println(x.model.name)

View File

@ -23,7 +23,7 @@ fn (c &Cat) speak(s string) {
} }
fn (c Cat) name_detailed(pet_name string) string { fn (c Cat) name_detailed(pet_name string) string {
return '$pet_name the ${typeof(c)}, breed:$c.breed' return '$pet_name the ${typeof(c).name}, breed:$c.breed'
} }
fn (mut c Cat) set_breed(new string) { fn (mut c Cat) set_breed(new string) {
@ -46,7 +46,7 @@ fn (d Dog) name() string {
} }
fn (d Dog) name_detailed(pet_name string) string { fn (d Dog) name_detailed(pet_name string) string {
return '$pet_name the ${typeof(d)}, breed:$d.breed' return '$pet_name the ${typeof(d).name}, breed:$d.breed'
} }
fn (mut d Dog) set_breed(new string) { fn (mut d Dog) set_breed(new string) {
@ -71,7 +71,7 @@ fn perform_speak(a Animal) {
println(a.breed) println(a.breed)
} }
println(a.name()) println(a.name())
println('Got animal of type: ${typeof(a)}') // TODO: get implementation type (if possible) println('Got animal of type: ${typeof(a).name}') // TODO: get implementation type (if possible)
assert a is Dog || a is Cat assert a is Dog || a is Cat
} }
@ -84,7 +84,7 @@ fn perform_speak_on_ptr(a &Animal) {
assert name == 'Dog' assert name == 'Dog'
} }
println(a.name()) println(a.name())
println('Got animal of type: ${typeof(a)}') // TODO: get implementation type (if possible) println('Got animal of type: ${typeof(a).name}') // TODO: get implementation type (if possible)
assert a is Dog || a is Cat assert a is Dog || a is Cat
} }

View File

@ -152,7 +152,7 @@ struct B1 {
fn f(s Sum) string { fn f(s Sum) string {
match s { match s {
A1 { return typeof(s) } A1 { return typeof(s).name }
B1 { return '' } B1 { return '' }
} }
return '' return ''
@ -167,7 +167,7 @@ fn test_sum_type_name() {
fn f_else(s Sum) string { fn f_else(s Sum) string {
match s { match s {
A1 { return typeof(s) } A1 { return typeof(s).name }
else { return '' } else { return '' }
} }
} }

View File

@ -165,7 +165,7 @@ fn test_as_cast() {
fn test_typeof() { fn test_typeof() {
x := Expr(IfExpr{}) x := Expr(IfExpr{})
assert typeof(x) == 'IfExpr' assert x.type_name() == 'IfExpr'
} }
type Food = Milk | Eggs type Food = Milk | Eggs
@ -409,7 +409,7 @@ fn (c CommonType) str() string {
match c { match c {
string { string {
d := c.int() d := c.int()
e := d _ := d
return c return c
} }
int { int {
@ -525,7 +525,7 @@ fn handle(e Expr) string {
assert is_literal assert is_literal
assert !(e !is IntegerLiteral) assert !(e !is IntegerLiteral)
if e is IntegerLiteral { if e is IntegerLiteral {
assert typeof(e.val) == 'string' assert typeof(e.val).name == 'string'
} }
match e { match e {
IntegerLiteral { IntegerLiteral {

View File

@ -1,6 +1,6 @@
// _likely_(expr) should be compilable, and it should return the expr // _likely_(expr) should be compilable, and it should return the expr
fn test_likely_type() { fn test_likely_type() {
assert typeof(_likely_(false)) == 'bool' assert typeof(_likely_(false)).name == 'bool'
assert _likely_(false) == false assert _likely_(false) == false
assert _likely_(true) == true assert _likely_(true) == true
} }
@ -26,7 +26,7 @@ fn test_likely_returns_the_value_of_its_bool_argument() {
// _unlikely_ is the same as _likely_ from the V point of view: // _unlikely_ is the same as _likely_ from the V point of view:
fn test_unlikely_type() { fn test_unlikely_type() {
assert typeof(_unlikely_(false)) == 'bool' assert typeof(_unlikely_(false)).name == 'bool'
assert _unlikely_(false) == false assert _unlikely_(false) == false
assert _unlikely_(true) == true assert _unlikely_(true) == true
} }

View File

@ -4,13 +4,13 @@ fn test_anyfloat() {
c := f32(6.75) / 3.0 c := f32(6.75) / 3.0
d := 16.5 / f32(2) d := 16.5 / f32(2)
assert a == 51.515 assert a == 51.515
assert typeof(a) == 'f64' assert typeof(a).name == 'f64'
assert b == f64(15.3) assert b == f64(15.3)
assert typeof(b) == 'f64' assert typeof(b).name == 'f64'
assert c == 2.25 assert c == 2.25
assert typeof(c) == 'f32' assert typeof(c).name == 'f32'
assert d == 8.25 assert d == 8.25
assert typeof(d) == 'f32' assert typeof(d).name == 'f32'
} }
fn g(x f32) f32 { fn g(x f32) f32 {
@ -92,9 +92,9 @@ fn test_rune() {
assert x == 67 assert x == 67
c := b + a c := b + a
assert c == rune(70) assert c == rune(70)
assert typeof(c) == 'rune' assert typeof(c).name == 'rune'
d := i64(12) d := i64(12)
e := b + d e := b + d
assert e == i64(79) assert e == i64(79)
assert typeof(e) == 'i64' assert typeof(e).name == 'i64'
} }

View File

@ -54,7 +54,7 @@ pub fn (ms MySumType) str() string {
int { return ms.str() } int { return ms.str() }
f32 { return ms.str() } f32 { return ms.str() }
// FooBar { return it.x.str() } // FooBar { return it.x.str() }
else { return 'unknown: ' + typeof(ms) } else { return ms.type_name() }
} }
} }
@ -74,6 +74,10 @@ fn test_typeof_on_sumtypes() {
assert typeof(a).name == 'MySumType' assert typeof(a).name == 'MySumType'
assert typeof(b).name == 'MySumType' assert typeof(b).name == 'MySumType'
assert typeof(c).name == 'MySumType' assert typeof(c).name == 'MySumType'
assert a.str() == '32'
assert b.str() == '123.'
assert c.str() == 'FooBar'
} }
// //