The following script shows a dict<number>
allowing string values after a legacy call map()
. It still reports as as dict<number>
, despite containing strings. At the script level, legacy let
can add an invalid type to the dictionary too:
vim9script echo "---- myDict is type dict<number> ----" var myDict: dict<number> = {'one': 1, 'two': 2} echo myDict echo myDict->typename() echo "\n---- myDict containing strings ----" def BreakMyDict() legacy call map(s:myDict, {i -> $"item {i}"}) enddef BreakMyDict() echo $"myDict is now {myDict}" echo myDict->typename() echo myDict['one']->typename() echo myDict['two']->typename() echo "\n---- myDict containing any ----" legacy let s:myDict['two'] = (2, ) echo $"myDict is now {myDict}" echo myDict->typename() echo myDict['one']->typename() echo myDict['two']->typename()
# " This undermines Vim9 script's type safety guarantees. # " Code relying on declared types fails unexpectedly. # " Since `typename()` reports incorrect information, even runtime # " type checking does not detect the type mismatch # " E.g., Later in code, presuming dict<number> is safe ... if myDict->typename() == 'dict<number>' # " Yes, sure is ... try var mySum: number = myDict['one'] + 1 catch echo v:exception # " E1030: Using String as a Number endtry try var mySum: number = 1 + myDict['two'] catch echo v:exception # " E1520: Using Tuple as a Number endtry endif
Version 9.1 w/ 1833
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.