Fix reallocation bug

This commit is contained in:
Richard Feldman 2025-11-24 22:58:00 -05:00
parent c02140827e
commit 02f4c3379c
No known key found for this signature in database
2 changed files with 37 additions and 36 deletions

View file

@ -1498,15 +1498,26 @@ fn processAssociatedItemsFirstPass(
// Also add user-facing alias (without module prefix) so "One.Two.value" works
// in addition to "module.One.Two.value"
// Add to module scope (index 0) so it's accessible from anywhere in the module
const fully_qualified_text = self.env.getIdent(qualified_idx);
const module_prefix = self.env.module_name;
if (std.mem.startsWith(u8, fully_qualified_text, module_prefix) and
fully_qualified_text.len > module_prefix.len and
fully_qualified_text[module_prefix.len] == '.')
{
const user_facing_text = fully_qualified_text[module_prefix.len + 1 ..];
const user_facing_idx = try self.env.insertIdent(base.Ident.for_text(user_facing_text));
try current_scope.idents.put(self.env.gpa, user_facing_idx, placeholder_pattern_idx);
// Copy user-facing text to a local buffer before calling insertIdent,
// because insertIdent may reallocate the string interner and invalidate
// any slices pointing into it (like fully_qualified_text)
const user_facing_start = module_prefix.len + 1;
const user_facing_len = fully_qualified_text.len - user_facing_start;
var user_facing_buf: [512]u8 = undefined;
if (user_facing_len <= user_facing_buf.len) {
@memcpy(user_facing_buf[0..user_facing_len], fully_qualified_text[user_facing_start..]);
const user_facing_text = user_facing_buf[0..user_facing_len];
const user_facing_idx = try self.env.insertIdent(base.Ident.for_text(user_facing_text));
// Add to module scope so it persists after associated block scope exits
try self.scopes.items[0].idents.put(self.env.gpa, user_facing_idx, placeholder_pattern_idx);
}
}
}
}
@ -1535,15 +1546,26 @@ fn processAssociatedItemsFirstPass(
try current_scope.idents.put(self.env.gpa, qualified_idx, placeholder_pattern_idx);
// Also add user-facing alias (without module prefix)
// Add to module scope (index 0) so it's accessible from anywhere in the module
const fully_qualified_text = self.env.getIdent(qualified_idx);
const module_prefix = self.env.module_name;
if (std.mem.startsWith(u8, fully_qualified_text, module_prefix) and
fully_qualified_text.len > module_prefix.len and
fully_qualified_text[module_prefix.len] == '.')
{
const user_facing_text = fully_qualified_text[module_prefix.len + 1 ..];
const user_facing_idx = try self.env.insertIdent(base.Ident.for_text(user_facing_text));
try current_scope.idents.put(self.env.gpa, user_facing_idx, placeholder_pattern_idx);
// Copy user-facing text to a local buffer before calling insertIdent,
// because insertIdent may reallocate the string interner and invalidate
// any slices pointing into it (like fully_qualified_text)
const user_facing_start = module_prefix.len + 1;
const user_facing_len = fully_qualified_text.len - user_facing_start;
var user_facing_buf: [512]u8 = undefined;
if (user_facing_len <= user_facing_buf.len) {
@memcpy(user_facing_buf[0..user_facing_len], fully_qualified_text[user_facing_start..]);
const user_facing_text = user_facing_buf[0..user_facing_len];
const user_facing_idx = try self.env.insertIdent(base.Ident.for_text(user_facing_text));
// Add to module scope so it persists after associated block scope exits
try self.scopes.items[0].idents.put(self.env.gpa, user_facing_idx, placeholder_pattern_idx);
}
}
}
},
@ -8724,11 +8746,8 @@ fn scopeContains(
const scope = &self.scopes.items[scope_idx];
const map = scope.itemsConst(item_kind);
var iter = map.iterator();
while (iter.next()) |entry| {
if (name.idx == entry.key_ptr.idx) {
return entry.value_ptr.*;
}
if (map.get(name)) |pattern_idx| {
return pattern_idx;
}
}
return null;
@ -8938,15 +8957,10 @@ pub fn scopeIntroduceInternal(
const scope = &self.scopes.items[scope_idx];
const map = scope.itemsConst(item_kind);
var iter = map.iterator();
while (iter.next()) |entry| {
if (ident_idx.idx == entry.key_ptr.idx) {
declaration_scope_idx = scope_idx;
break;
}
if (map.get(ident_idx) != null) {
declaration_scope_idx = scope_idx;
break;
}
if (declaration_scope_idx != null) break;
}
// Now check if there are function boundaries between declaration and current scope

View file

@ -483,7 +483,6 @@ UNDEFINED VARIABLE - associated_items_truly_comprehensive.md:382:20:382:24
UNUSED VARIABLE - associated_items_truly_comprehensive.md:382:20:382:24
UNDEFINED VARIABLE - associated_items_truly_comprehensive.md:388:12:388:16
UNUSED VARIABLE - associated_items_truly_comprehensive.md:388:12:388:16
DOES NOT EXIST - associated_items_truly_comprehensive.md:451:11:451:32
# PROBLEMS
**UNDEFINED VARIABLE**
Nothing is named `val4` in this scope.
@ -531,19 +530,6 @@ The unused variable is declared here:
^^^^
**DOES NOT EXIST**
`Shadowing.useL2` does not exist.
`Shadowing` is in scope, but it has no associated `useL2`.
It's referenced here:
**associated_items_truly_comprehensive.md:451:11:451:32:**
```roc
shadow7 = Shadowing.L2.L3.useL2 # 2
```
^^^^^^^^^^^^^^^^^^^^^
# TOKENS
~~~zig
UpperIdent,OpColonEqual,OpenSquare,UpperIdent,CloseSquare,Dot,OpenCurly,
@ -3186,7 +3172,8 @@ anno2 = Annotated.L2.alsoTyped # 889
(p-assign (ident "associated_items_truly_comprehensive.Shadowing.L2.L3.useL1"))))
(d-let
(p-assign (ident "shadow7"))
(e-runtime-error (tag "nested_value_not_found")))
(e-lookup-local
(p-assign (ident "associated_items_truly_comprehensive.Shadowing.L2.L3.useL2"))))
(d-let
(p-assign (ident "shadow8"))
(e-lookup-local
@ -3701,7 +3688,7 @@ anno2 = Annotated.L2.alsoTyped # 889
(patt (type "e where [e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)])]"))
(patt (type "e where [e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)])]"))
(patt (type "e where [e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)])]"))
(patt (type "Error"))
(patt (type "e where [e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)])]"))
(patt (type "e where [e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)])]"))
(patt (type "e where [e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)])]"))
(patt (type "U64"))
@ -4035,7 +4022,7 @@ anno2 = Annotated.L2.alsoTyped # 889
(expr (type "e where [e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)])]"))
(expr (type "e where [e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)])]"))
(expr (type "e where [e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)])]"))
(expr (type "Error"))
(expr (type "e where [e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)])]"))
(expr (type "e where [e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)])]"))
(expr (type "e where [e.from_numeral : Numeral -> Try(e, [InvalidNumeral(Str)])]"))
(expr (type "U64"))