Files
Nim/tests/sets/trangeincompatible.nim
metagn 7dfadb8b4e stricter set type match, implicit conversion for literals (#24176)
fixes #18396, fixes #20142

Set types with base types matching less than a generic match (so
subrange matches, conversion matches, int conversion matches) are now
considered mismatching, as their representation is different on the
backends (except VM and JS), causing codegen issues. An exception is
granted for set literal types, which now implicitly convert each element
to the matched base type, so things like `s == {'a', 'b'}` are still
possible where `s` is `set[range['a'..'z']]`. Also every conversion
match in this case is unified under the normal "conversion" match, so a
literal doesn't match one set type better than the other, unless it's
equal.

However `{'a', 'b'} == s` or `{'a', 'b'} - s` etc is now not possible.
when it used to work in the VM. So this is somewhat breaking, and needs
a changelog entry.
2024-10-03 20:39:55 +02:00

33 lines
988 B
Nim

block: # issue #20142
let
s1: set['a' .. 'g'] = {'a', 'e'}
s2: set['a' .. 'g'] = {'b', 'c', 'd', 'f'} # this works fine
s3 = {'b', 'c', 'd', 'f'}
doAssert s1 != s2
doAssert s1 == {range['a'..'g'] 'a', 'e'}
doAssert s2 == {range['a'..'g'] 'b', 'c', 'd', 'f'}
# literal conversion:
doAssert s1 == {'a', 'e'}
doAssert s2 == {'b', 'c', 'd', 'f'}
doAssert s3 == {'b', 'c', 'd', 'f'}
doAssert not compiles(s1 == s3)
doAssert not compiles(s2 == s3)
# can't convert literal 'z', overload match fails
doAssert not compiles(s1 == {'a', 'z'})
block: # issue #18396
var s1: set[char] = {'a', 'b'}
var s2: set['a'..'z'] = {'a', 'b'}
doAssert s1 == {'a', 'b'}
doAssert s2 == {range['a'..'z'] 'a', 'b'}
doAssert s2 == {'a', 'b'}
doAssert not compiles(s1 == s2)
block: # issue #16270
var s1: set[char] = {'a', 'b'}
var s2: set['a'..'z'] = {'a', 'c'}
doAssert not (compiles do: s2 = s2 + s1)
s2 = s2 + {'a', 'b'}
doAssert s2 == {'a', 'b', 'c'}