nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.54k stars 1.47k forks source link

slicing in `collect` macro as add operation doesn't work #18405

Open hamidb80 opened 3 years ago

hamidb80 commented 3 years ago

the compiler gives type mismatch error for slicing in collect macro

Example

import tables, sugar
const document = ["this", "is a", "sequence", "of strings"]

let table1 = collect initTable:
  for word in document:
    # {word: 2}      # works [1]
    # {word[1]: 2}   # works [2]
    # {$word[0..2]: 2} # works [3]
    # {word[0..2]: 2}  # doesn't work [4]

    # {2: word}  # works [5]
    {2: word[0..2]}  # doesn't work [6]

echo table1

Current Output

compiler error for [4]

<myCode>.nim(4, 22) template/generic instantiation of `collect` from here
nim-#devel\lib\pure\sugar.nim(312, 29) Error: type mismatch: got <Table[system.char, system.int], string, int literal(2)>
but expected one of:
proc `[]=`(s: var string; i: BackwardsIndex; x: char)
  first type mismatch at position: 0
<...>
expression: `[]=`(collectResult_385875975, word[0 .. 2], 2)

compiler error for [6]:

<MYcode>.nim(4, 22) template/generic instantiation of `collect` from here
C:\Users\HamidB80\.choosenim\toolchains\nim-#devel\lib\pure\sugar.nim(312, 29) Error: type mismatch: got <Table[system.int, system.char], int literal(2), string>
but expected one of:
<...>
expression: `[]=`(collectResult_385875975, 2, word[0 .. 2])

Expected Output

compiles successfully

Additional Information

maybe related to #12383

my environment:

Nim Compiler Version 1.5.1 [Windows: amd64]
Compiled at 2021-06-20
Copyright (c) 2006-2021 by Andreas Rumpf

active boot switches: -d:release
hamidb80 commented 3 years ago

new investigation:

import sugar

func makeSlice(slice: HSlice[int ,int]): auto =
    slice

let a = 1..2
let ranges = collect newseq:
  for i in 0..10:
    # a         # works [7]
    # makeSlice 1 .. 2   # works [8]
    1 .. 2   # doesn't work [9]
planetis-m commented 3 years ago

Output of collect looks ok:

var collectResult_402653193 = initTable[typeof do:
  for word in document:
    2, typeof do:
  for word in document:
    word[0 .. 2]]()
for word in document:
  collectResult_402653193[2] = word[0 .. 2]
collectResult_402653193

this echo typeof "this"[0..2] outputs char ...also echo typeof(1..2) int

ringabout commented 3 years ago

echo typeof(1..2) == int works as intended. Because .. has iterators and procs overloads and the iterator one is preferred by default.

Use typeof(1..2, typeOfProc) to get HSlice[int, int].

planetis-m commented 1 year ago

I cannot fix it, I added bindSym"typeOfProc" to the calls of typeof but this doesn't work:

let ranges = block:
  var collectResult_570425399 = newseq[typeof(
    for i in 0 .. 10: 1 .. 2, typeOfProc)]()
  for i in 0 .. 10:
    collectResult_570425399.add(1 .. 2)
  collectResult_570425399

Error: expression '1 .. 2' is of type 'HSlice[system.int, system.int]' and has to be used (or discarded)

Actually everything breaks if you make it typeOfProc.

metagn commented 3 months ago

typeof with typeOfProc doesn't support for expressions because the compiler just doesn't pass the typeof flag which is required for for expressions..