edubart / nelua-lang

Minimal, efficient, statically-typed and meta-programmable systems programming language heavily inspired by Lua, which compiles to C and native code.
https://nelua.io
MIT License
2k stars 62 forks source link

spanT.__convert: sequence by-value misdetected as 0-based container #188

Closed leafi closed 2 years ago

leafi commented 2 years ago

Bug description

When a span is created by spanT.convert from a sequence(T), spanT.convert misdetects sequences as having zero-based indices. As sequences have semi-secret 0th indices, sequence.__atindex(0) doesn't fail, but the resulting span is one index earlier than it should be.

If instead a span is created by spanT.__convert from a *sequence(T), there is no off-by-one error.

The check in question: https://github.com/edubart/nelua-lang/blob/e87be950f13b7f9fed6f5b4e4440e8248ac49836/lib/span.nelua#L106

Code example

require 'iterators'
require 'sequence'
require 'span'
require 'string'

local seq: sequence(string)
seq:push('Hello!')

local spa_container_val: span(string) = seq
local spa_container_ref: span(string) = &seq

for i,v in ipairs(spa_container_val) do print(i, '`' .. v .. '`') end
for i,v in ipairs(spa_container_ref) do print(i, '`' .. v .. '`') end

-- Expected:
-- 0    `Hello!`
-- 0    `Hello!`

-- Received:
-- 0    ``
-- 0    `Hello!`

Workaround

Pass &sequence not sequence; the values.type.subtype.is_sequence and 1 or 0 check in span.nelua then works, because the type of values is &sequence and the subtype is a sequence.

Environment

Just updated to master - Git hash: 09ce17098db8a11b0ae9182ec02ff2f112304d03. Arch Linux, x86_64. GCC 11.2.0.

edubart commented 2 years ago

Thanks for reporting this, I've fixed in commit https://github.com/edubart/nelua-lang/commit/19cf3a575890b2b9c1e411a70d63b4c1c0676375 and added proper test for this in the test suite.