@@ -4452,7 +4452,7 @@ fn (mut g Parser) parse_declaration_after_name(name string, is_mut bool) ! {
44524452
44534453fn fastc_normalize_inferred_type (typ string ) string {
44544454 return match typ {
4455- 'integer literal' { 'int' }
4455+ 'integer literal' , 'negative integer literal' { 'int' }
44564456 'float literal' { 'f64' }
44574457 'nil' { 'voidptr' }
44584458 else { typ }
@@ -9311,6 +9311,9 @@ fn (g &Parser) infer_expression_type(tokens []FastcExpressionToken) !string {
93119311 if ! fastc_is_numeric_expression_type (operand_type) {
93129312 return g.unsupported ('arithmetic `${tokens [start ].tok .str ()}` on non-numeric type `${operand_type }`' )
93139313 }
9314+ if tokens[start].tok == .minus && operand_type == 'integer literal' {
9315+ return 'negative integer literal'
9316+ }
93149317 return operand_type
93159318 }
93169319 if tokens[start].tok in [.amp, .and] {
@@ -9583,19 +9586,36 @@ fn fastc_number_expression_type(literal string) string {
95839586 && clean.contains_any ('eE' )) {
95849587 return 'float literal'
95859588 }
9589+ if clean.starts_with ('-' ) {
9590+ return 'negative integer literal'
9591+ }
95869592 return 'integer literal'
95879593}
95889594
95899595fn fastc_common_arithmetic_type (left string , right string ) string {
95909596 if left == right && fastc_is_numeric_expression_type (left) {
95919597 return left
95929598 }
9593- if left == 'integer literal' && fastc_is_integer_type (right) {
9599+ if left == 'negative integer literal' && fastc_is_unsigned_integer_type (right) {
9600+ return ''
9601+ }
9602+ if right == 'negative integer literal' && fastc_is_unsigned_integer_type (left) {
9603+ return ''
9604+ }
9605+ if fastc_is_integer_literal_expression_type (left) && fastc_is_integer_type (right) {
95949606 return right
95959607 }
9596- if right == 'integer literal' && fastc_is_integer_type (left) {
9608+ if fastc_is_integer_literal_expression_type ( right) && fastc_is_integer_type (left) {
95979609 return left
95989610 }
9611+ if fastc_is_integer_literal_expression_type (left)
9612+ && fastc_is_integer_literal_expression_type (right) {
9613+ return if left == 'negative integer literal' || right == 'negative integer literal' {
9614+ 'negative integer literal'
9615+ } else {
9616+ 'integer literal'
9617+ }
9618+ }
95999619 if left == 'float literal' && right in ['f32' , 'f64' ] {
96009620 return right
96019621 }
@@ -9606,11 +9626,16 @@ fn fastc_common_arithmetic_type(left string, right string) string {
96069626}
96079627
96089628fn fastc_is_numeric_expression_type (typ string ) bool {
9609- return typ in ['integer literal' , 'float literal' , 'f32' , 'f64' ] || fastc_is_integer_type (typ)
9629+ return fastc_is_integer_literal_expression_type (typ) || typ in ['float literal' , 'f32' , 'f64' ]
9630+ || fastc_is_integer_type (typ)
96109631}
96119632
96129633fn fastc_is_integer_expression_type (typ string ) bool {
9613- return typ == 'integer literal' || fastc_is_integer_type (typ)
9634+ return fastc_is_integer_literal_expression_type (typ) || fastc_is_integer_type (typ)
9635+ }
9636+
9637+ fn fastc_is_integer_literal_expression_type (typ string ) bool {
9638+ return typ in ['integer literal' , 'negative integer literal' ]
96149639}
96159640
96169641fn fastc_call_types_are_compatible (actual string , expected string ) bool {
@@ -9620,6 +9645,9 @@ fn fastc_call_types_are_compatible(actual string, expected string) bool {
96209645 if actual == 'integer literal' {
96219646 return fastc_is_integer_type (expected)
96229647 }
9648+ if actual == 'negative integer literal' {
9649+ return fastc_is_integer_type (expected) && ! fastc_is_unsigned_integer_type (expected)
9650+ }
96239651 if actual == 'float literal' {
96249652 return expected in ['f32' , 'f64' ]
96259653 }
@@ -9647,6 +9675,9 @@ fn fastc_selfhost_types_are_compatible(actual string, expected string) bool {
96479675 || (expected_base == 'map' && actual_base.starts_with ('Map_' )) {
96489676 return true
96499677 }
9678+ if actual == 'negative integer literal' && fastc_is_unsigned_integer_type (expected) {
9679+ return false
9680+ }
96509681 if fastc_is_integer_expression_type (actual) && fastc_is_integer_type (expected) {
96519682 return true
96529683 }
@@ -9711,6 +9742,10 @@ fn fastc_is_integer_type(typ string) bool {
97119742 'u32' , 'u64' , 'unsigned int' , 'usize' ]
97129743}
97139744
9745+ fn fastc_is_unsigned_integer_type (typ string ) bool {
9746+ return typ in ['byte' , 'u8' , 'u16' , 'u32' , 'u64' , 'unsigned int' , 'usize' ]
9747+ }
9748+
97149749fn fastc_nondecimal_literal_is_type_sensitive (literal string ) bool {
97159750 clean := literal.replace ('_' , '' )
97169751 if clean.len < = 2 || clean[0 ] != `0` {
0 commit comments