mirror of
https://github.com/roc-lang/roc.git
synced 2025-12-23 08:48:03 +00:00
Fix Ubuntu CI
This commit is contained in:
parent
781166eeb7
commit
ba3e667e5b
4 changed files with 148 additions and 60 deletions
|
|
@ -1280,51 +1280,77 @@ pub fn canonicalizeFile(
|
|||
}
|
||||
}
|
||||
|
||||
// Phase 1.5.5: Create placeholders for top-level decls
|
||||
// This ensures they're available when processing associated blocks
|
||||
// IMPORTANT: Only do this for type-modules, not apps/hosted/etc
|
||||
// Apps and other module types process their decls normally without placeholders
|
||||
// Phase 1.5.5: Process anno-only top-level type annotations EARLY
|
||||
// For type-modules, anno-only top-level type annotations (like list_get_unsafe) need to be
|
||||
// processed before associated blocks so they can be referenced inside those blocks
|
||||
// IMPORTANT: Only process anno-only (no matching decl), and only for type-modules
|
||||
switch (self.env.module_kind) {
|
||||
.type_module => {
|
||||
const top_level_stmts = self.parse_ir.store.statementSlice(file.statements);
|
||||
for (top_level_stmts) |stmt_id| {
|
||||
var i: usize = 0;
|
||||
while (i < top_level_stmts.len) : (i += 1) {
|
||||
const stmt_id = top_level_stmts[i];
|
||||
const stmt = self.parse_ir.store.getStatement(stmt_id);
|
||||
switch (stmt) {
|
||||
.decl => |decl| {
|
||||
const pattern = self.parse_ir.store.getPattern(decl.pattern);
|
||||
if (pattern == .ident) {
|
||||
const pattern_ident_tok = pattern.ident.ident_tok;
|
||||
if (self.parse_ir.tokens.resolveIdentifier(pattern_ident_tok)) |decl_ident| {
|
||||
const region = self.parse_ir.tokenizedRegionToRegion(decl.region);
|
||||
const placeholder_pattern = Pattern{
|
||||
.assign = .{
|
||||
.ident = decl_ident,
|
||||
},
|
||||
};
|
||||
const placeholder_pattern_idx = try self.env.addPattern(placeholder_pattern, region);
|
||||
try self.placeholder_idents.put(self.env.gpa, decl_ident, {});
|
||||
const current_scope = &self.scopes.items[self.scopes.items.len - 1];
|
||||
try current_scope.idents.put(self.env.gpa, decl_ident, placeholder_pattern_idx);
|
||||
if (stmt == .type_anno) {
|
||||
const ta = stmt.type_anno;
|
||||
const name_ident = self.parse_ir.tokens.resolveIdentifier(ta.name) orelse continue;
|
||||
|
||||
// Check if there's a matching decl (skipping malformed statements)
|
||||
const has_matching_decl = blk: {
|
||||
var next_i = i + 1;
|
||||
while (next_i < top_level_stmts.len) : (next_i += 1) {
|
||||
const next_stmt = self.parse_ir.store.getStatement(top_level_stmts[next_i]);
|
||||
// Skip malformed statements
|
||||
if (next_stmt == .malformed) continue;
|
||||
// Check if this is a matching decl
|
||||
if (next_stmt == .decl) {
|
||||
const next_pattern = self.parse_ir.store.getPattern(next_stmt.decl.pattern);
|
||||
if (next_pattern == .ident) {
|
||||
if (self.parse_ir.tokens.resolveIdentifier(next_pattern.ident.ident_tok)) |decl_ident| {
|
||||
break :blk name_ident.idx == decl_ident.idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Found a non-malformed, non-matching statement
|
||||
break :blk false;
|
||||
}
|
||||
},
|
||||
.type_anno => |type_anno| {
|
||||
// Also create placeholders for top-level type annotations (like list_get_unsafe)
|
||||
// These are anno-only defs that need to be available in associated blocks
|
||||
if (self.parse_ir.tokens.resolveIdentifier(type_anno.name)) |anno_ident| {
|
||||
const region = self.parse_ir.tokenizedRegionToRegion(type_anno.region);
|
||||
const placeholder_pattern = Pattern{
|
||||
.assign = .{
|
||||
.ident = anno_ident,
|
||||
},
|
||||
};
|
||||
const placeholder_pattern_idx = try self.env.addPattern(placeholder_pattern, region);
|
||||
try self.placeholder_idents.put(self.env.gpa, anno_ident, {});
|
||||
const current_scope = &self.scopes.items[self.scopes.items.len - 1];
|
||||
try current_scope.idents.put(self.env.gpa, anno_ident, placeholder_pattern_idx);
|
||||
// Reached end of statements
|
||||
break :blk false;
|
||||
};
|
||||
|
||||
// Skip if there's a matching decl - it will be processed normally
|
||||
if (has_matching_decl) continue;
|
||||
|
||||
const region = self.parse_ir.tokenizedRegionToRegion(ta.region);
|
||||
|
||||
// Extract type variables and canonicalize the annotation
|
||||
const type_vars_top: u32 = @intCast(self.scratch_idents.top());
|
||||
try self.extractTypeVarIdentsFromASTAnno(ta.anno, type_vars_top);
|
||||
const type_var_scope = self.scopeEnterTypeVar();
|
||||
defer self.scopeExitTypeVar(type_var_scope);
|
||||
const type_anno_idx = try self.canonicalizeTypeAnno(ta.anno, .inline_anno);
|
||||
|
||||
// Canonicalize where clauses if present
|
||||
const where_clauses = if (ta.where) |where_coll| blk: {
|
||||
const where_slice = self.parse_ir.store.whereClauseSlice(.{ .span = self.parse_ir.store.getCollection(where_coll).span });
|
||||
const where_start = self.env.store.scratchWhereClauseTop();
|
||||
for (where_slice) |where_idx| {
|
||||
const canonicalized_where = try self.canonicalizeWhereClause(where_idx, .inline_anno);
|
||||
try self.env.store.addScratchWhereClause(canonicalized_where);
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
break :blk try self.env.store.whereClauseSpanFrom(where_start);
|
||||
} else null;
|
||||
|
||||
// Create the anno-only def immediately
|
||||
const def_idx = try self.createAnnoOnlyDef(name_ident, type_anno_idx, where_clauses, region);
|
||||
try self.env.store.addScratchDef(def_idx);
|
||||
|
||||
// If exposed, register it
|
||||
const ident_text = self.env.getIdent(name_ident);
|
||||
if (self.exposed_ident_texts.contains(ident_text)) {
|
||||
const def_idx_u16: u16 = @intCast(@intFromEnum(def_idx));
|
||||
try self.env.setExposedNodeIndexById(name_ident, def_idx_u16);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -1485,6 +1511,41 @@ pub fn canonicalizeFile(
|
|||
continue;
|
||||
};
|
||||
|
||||
// For type-modules, check if this is an anno-only annotation that was already processed in Phase 1.5.5
|
||||
// We need to check if there's a matching decl - if there isn't, this was processed early
|
||||
switch (self.env.module_kind) {
|
||||
.type_module => {
|
||||
// Check if there's a matching decl (skipping malformed statements)
|
||||
const has_matching_decl = blk: {
|
||||
var check_i = i + 1;
|
||||
while (check_i < ast_stmt_idxs.len) : (check_i += 1) {
|
||||
const check_stmt = self.parse_ir.store.getStatement(ast_stmt_idxs[check_i]);
|
||||
// Skip malformed statements
|
||||
if (check_stmt == .malformed) continue;
|
||||
// Check if this is a matching decl
|
||||
if (check_stmt == .decl) {
|
||||
const check_pattern = self.parse_ir.store.getPattern(check_stmt.decl.pattern);
|
||||
if (check_pattern == .ident) {
|
||||
if (self.parse_ir.tokens.resolveIdentifier(check_pattern.ident.ident_tok)) |decl_ident| {
|
||||
break :blk name_ident.idx == decl_ident.idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Found a non-malformed, non-matching statement
|
||||
break :blk false;
|
||||
}
|
||||
// Reached end of statements
|
||||
break :blk false;
|
||||
};
|
||||
|
||||
// Skip if this is anno-only (no matching decl) - it was processed in Phase 1.5.5
|
||||
if (!has_matching_decl) {
|
||||
continue;
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
// First, make the top of our scratch list
|
||||
const type_vars_top: u32 = @intCast(self.scratch_idents.top());
|
||||
|
||||
|
|
|
|||
|
|
@ -1174,6 +1174,17 @@ g : e -> e where module(e).A, module(e).B
|
|||
^^
|
||||
|
||||
|
||||
**MALFORMED WHERE CLAUSE**
|
||||
This where clause could not be parsed correctly.
|
||||
|
||||
**everything.md:56:12:56:17:**
|
||||
```roc
|
||||
g : e -> e where module(e).A, module(e).B
|
||||
```
|
||||
^^^^^
|
||||
|
||||
Check the syntax of your where clause.
|
||||
|
||||
**WHERE CLAUSE NOT ALLOWED IN TYPE DECLARATION**
|
||||
You cannot define a `where` clause inside a type declaration.
|
||||
|
||||
|
|
@ -1222,17 +1233,6 @@ import I2 exposing [
|
|||
```
|
||||
|
||||
|
||||
**MALFORMED WHERE CLAUSE**
|
||||
This where clause could not be parsed correctly.
|
||||
|
||||
**everything.md:56:12:56:17:**
|
||||
```roc
|
||||
g : e -> e where module(e).A, module(e).B
|
||||
```
|
||||
^^^^^
|
||||
|
||||
Check the syntax of your where clause.
|
||||
|
||||
**UNUSED VARIABLE**
|
||||
Variable `b` is not used anywhere in your code.
|
||||
|
||||
|
|
|
|||
|
|
@ -23,17 +23,6 @@ import u.R}g:r->R.a.E
|
|||
^
|
||||
|
||||
|
||||
**MODULE NOT FOUND**
|
||||
The module `u.R` was not found in this Roc project.
|
||||
|
||||
You're attempting to use this module here:
|
||||
**fuzz_crash_042.md:1:1:1:11:**
|
||||
```roc
|
||||
import u.R}g:r->R.a.E
|
||||
```
|
||||
^^^^^^^^^^
|
||||
|
||||
|
||||
**MODULE NOT IMPORTED**
|
||||
There is no module with the name `R.a` imported into this Roc file.
|
||||
|
||||
|
|
@ -45,6 +34,17 @@ import u.R}g:r->R.a.E
|
|||
^^^^^
|
||||
|
||||
|
||||
**MODULE NOT FOUND**
|
||||
The module `u.R` was not found in this Roc project.
|
||||
|
||||
You're attempting to use this module here:
|
||||
**fuzz_crash_042.md:1:1:1:11:**
|
||||
```roc
|
||||
import u.R}g:r->R.a.E
|
||||
```
|
||||
^^^^^^^^^^
|
||||
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
KwImport,LowerIdent,NoSpaceDotUpperIdent,CloseCurly,LowerIdent,OpColon,LowerIdent,OpArrow,UpperIdent,NoSpaceDotLowerIdent,NoSpaceDotUpperIdent,
|
||||
|
|
|
|||
|
|
@ -77,6 +77,24 @@ process = |list| "processed"
|
|||
^^^^
|
||||
|
||||
|
||||
**DUPLICATE DEFINITION**
|
||||
The name `transform` is being redeclared in this scope.
|
||||
|
||||
The redeclaration is here:
|
||||
**underscore_in_regular_annotations.md:29:1:29:10:**
|
||||
```roc
|
||||
transform = |_, b| b
|
||||
```
|
||||
^^^^^^^^^
|
||||
|
||||
But `transform` was already defined here:
|
||||
**underscore_in_regular_annotations.md:28:1:28:21:**
|
||||
```roc
|
||||
transform : _a -> _b -> _b
|
||||
```
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
LowerIdent,OpColon,Underscore,OpArrow,Underscore,
|
||||
|
|
@ -245,6 +263,13 @@ transform = |_, b| b
|
|||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can-ir
|
||||
(d-let
|
||||
(p-assign (ident "transform"))
|
||||
(e-anno-only)
|
||||
(annotation
|
||||
(ty-fn (effectful false)
|
||||
(ty-rigid-var (name "_a"))
|
||||
(ty-rigid-var (name "_b")))))
|
||||
(d-let
|
||||
(p-assign (ident "main"))
|
||||
(e-lambda
|
||||
|
|
@ -360,6 +385,7 @@ transform = |_, b| b
|
|||
~~~clojure
|
||||
(inferred-types
|
||||
(defs
|
||||
(patt (type "_a -> _b"))
|
||||
(patt (type "_arg -> _ret"))
|
||||
(patt (type "a -> a"))
|
||||
(patt (type "List(_elem) -> Str"))
|
||||
|
|
@ -368,6 +394,7 @@ transform = |_, b| b
|
|||
(patt (type "a -> b, List(a) -> List(b)"))
|
||||
(patt (type "_arg, c -> c")))
|
||||
(expressions
|
||||
(expr (type "_a -> _b"))
|
||||
(expr (type "_arg -> _ret"))
|
||||
(expr (type "a -> a"))
|
||||
(expr (type "List(_elem) -> Str"))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue