Bug 24169 – Confusion between array literal and associative array literal

Status
NEW
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2023-09-29T03:09:51Z
Last change time
2024-12-13T19:31:03Z
Keywords
pull
Assigned to
No Owner
Creator
Walter Bright
Moved to GitHub: dmd#20337 →

Comments

Comment #0 by bugzilla — 2023-09-29T03:09:51Z
int[3] a = [3, 1:1, 2:2]; compiles, while: auto a = [3, 1:1, 2:2]; fails with: "not an associative array initializer". Seems there is some confusion about which it is.
Comment #1 by bugzilla — 2023-09-29T03:20:33Z
The fault appears to lie with init.ArrayInitializer.isAssociativeArray(), which is way too eager to conclude it's an associative array. I suggest that it be amended to require, for an associative array: 1. all keys are present 2. the key type is not integrably promotable to size_t -or- the range of key values is more than twice the number of entries
Comment #2 by bugzilla — 2023-09-29T03:23:09Z
The key values should also all be positive for an array literal.
Comment #3 by dkorpel — 2023-09-29T09:27:19Z
> 1. all keys are present Sounds reasonable > 2. the key type is not integrably promotable to size_t Associative arrays with integer key types are valid, changing the inferred type of the literal to an integer array is a breaking change. > the range of key values is more than twice the number of entries This is trying to be clever, when the rule should be simple. It would be surprising when adding a key to an existing associative array suddenly turns it into an integer array or vice versa.
Comment #4 by bugzilla — 2023-09-29T16:57:26Z
> It would be surprising when adding a key to an existing associative array suddenly turns it into an integer array or vice versa. The change to add associative array literals did exactly that. It silently switched code from generating an array literal to an associative array literal. (The penalty is slow access, as array indexing is much faster.) I discovered this via testing.
Comment #5 by dkorpel — 2023-09-29T17:17:40Z
(In reply to Walter Bright from comment #4) > The change to add associative array literals did exactly that. A change in the past had an unfortunate side effect. How does this justify adding a new confusing rule? Imagine someone wrote this: ``` auto x = [ 0: 10, 4: 40, ]; void main() { x.byKeyValue.each!writeln; } ``` Then one day someone adds an entry: ``` auto x = [ 0: 10, 4: 40, 5: 50, ]; ``` With the proposed scheme, x would suddenly change type resulting in errors like `Error: none of the overloads of template `object.byKeyValue` are callable using argument types `!()(int[])`. How is the programmer supposed to know what happened here?
Comment #6 by dlang-bot — 2024-06-29T14:45:41Z
@ntrel created dlang/dmd pull request #16635 "Fix Bugzilla 24169 - Confusion between array literal and associative …" fixing this issue: - Fix Bugzilla 24169 - Confusion between array literal and associative array literal Infer an array initializer as an array if there are missing indexes. https://github.com/dlang/dmd/pull/16635
Comment #7 by robert.schadek — 2024-12-13T19:31:03Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/20337 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB