Skip to content

Commit

Permalink
system: explicit </<= overloads for cstring (nim-lang#1047)
Browse files Browse the repository at this point in the history
## Summary

Introduce an explicit overload of the `<` and `<=` system operators for
`cstring`, removing the reliance on `cstring` being implicitly
convertible to `pointer`.

## Details

`cstring` is currently always implicitly convertible to `pointer`,
which meant that the `LePtr` and `LtPtr` magic overloads were chosen so
far (through introduction of an implicit conversion for the arguments).

This is a problem for the upcoming MIR rework, as there the result of
each operation has to be assignable to a temporary. Since `jsgen`
treats the `cstring`-to-`pointer` conversion as a no-op, the assignment
would result in a typing error within the JS code generator.

As a preparation for both the MIR rework and for revisiting the
semantics of cstrings, explicit `<` and `<=` overloads are introduced
for `cstring`. Using imported overloads when the JS backend is enabled
wouldn't work, as that'd prevent the comparison operators from being
used in compile-time(-only) contexts.

The introduction is backwards compatible with the csources compiler, so
no new conditional symbol is required. For `tset_with_range.nim` the
number of mismatching overloads in the error message is updated.
  • Loading branch information
zerbina committed Dec 3, 2023
1 parent 6a347e9 commit 5d4430e
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 1 deletion.
2 changes: 2 additions & 0 deletions lib/system/comparisons.nim
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ proc `<=`*[T](x, y: set[T]): bool {.magic: "LeSet", noSideEffect.} =
proc `<=`*(x, y: bool): bool {.magic: "LeB", noSideEffect.}
proc `<=`*[T](x, y: ref T): bool {.magic: "LePtr", noSideEffect.}
proc `<=`*(x, y: pointer): bool {.magic: "LePtr", noSideEffect.}
proc `<=`*(x, y: cstring): bool {.magic: "LePtr", noSideEffect.}

proc `<`*[Enum: enum](x, y: Enum): bool {.magic: "LtEnum", noSideEffect.}
proc `<`*(x, y: string): bool {.magic: "LtStr", noSideEffect.} =
Expand Down Expand Up @@ -124,6 +125,7 @@ proc `<`*(x, y: bool): bool {.magic: "LtB", noSideEffect.}
proc `<`*[T](x, y: ref T): bool {.magic: "LtPtr", noSideEffect.}
proc `<`*[T](x, y: ptr T): bool {.magic: "LtPtr", noSideEffect.}
proc `<`*(x, y: pointer): bool {.magic: "LtPtr", noSideEffect.}
proc `<`*(x, y: cstring): bool {.magic: "LtPtr", noSideEffect.}

template `!=`*(x, y: untyped): untyped =
## Unequals operator. This is a shorthand for `not (x == y)`.
Expand Down
2 changes: 1 addition & 1 deletion tests/stdlib/types/sets/tset_with_range.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ proc `<`[T](x, y: set[T]): bool
first type mismatch at position: 2
required type for y: set[T]
but expression 'x' is of type: set[range 1..5(uint8)]
20 other mismatching symbols have been suppressed; compile with --showAllMismatches:on to see them
21 other mismatching symbols have been suppressed; compile with --showAllMismatches:on to see them
expression: {1'u8, 5} < x'''
description: '''
Expand Down

0 comments on commit 5d4430e

Please sign in to comment.