Skip to content

self-host P3 slice 3: name resolution -- every name bound as both backends bind it (E_NAME) #8092

Closed

Description

@gHashTag

Part of #5980 (phase P3: "the semantic passes t27c runs before codegen (name resolution, ...)"). This is the third P3 slice, name resolution.

t27c's typecheck resolves no name (see #8087). An undeclared identifier, a function or type read as a value, a module name, parameter or local declared twice, a shadow Zig refuses, and a field the struct lacks all pass typecheck with 0 errors. gen-c writes C for them that cc refuses, or that computes something else.

gen-c's C also has one namespace and one declaration order that t27 does not have (see #8088):

  • a module initializer naming a later const;
  • a literal const written as #define that rewrites a local, parameter or field of its name;
  • a call of a function a local shadows;
  • a test or bench whose test_/bench_ C name another declaration has.

This slice

The core binds every name as both backends do, and refuses with E_NAME (5) what either refuses:

  • every name read is a local, local array or for capture in scope, a parameter, or a module const, var or array; every field read is one its struct has;
  • each module name, parameter, and local in scope is declared once, and no local, parameter or capture shadows another; a capture shadows no module name;
  • the four C namespace and order rules above.

An assignment to a for capture is E_UNSOUND (17): Zig's capture is a constant, and in C the assignment changes the loop.

Accepted, as both backends take them:

  • sibling blocks reusing a name;
  • a local, a parameter shadowing a module var, a function that is not called, a struct, or a const C writes as a variable;
  • a function called before its declaration;
  • a module var declared after the function that reads it.

Fixtures, core tests, and the DDC repin, as in earlier slices. Measured on the t27c lab against t27c typecheck, gen-c + cc and the Zig route.

User Scenarios

  • Given a T27 module containing an undeclared identifier, when running t27c typecheck, then the compiler fails with error code E_NAME (5)
  • Given a T27 module assigning to a for loop capture variable, when running t27c typecheck, then the compiler fails with error code E_UNSOUND (17)
  • Given a T27 module where a local shadows a module-level function that is called, when running t27c typecheck, then the compiler fails with error code E_NAME (5)

Requirements

FR-001: The typecheck pass MUST bind every name read as a local, local array, for capture, parameter, module const, module var, module array, or struct field, and reject with E_NAME (5) any name that is not so bound.
FR-002: The typecheck pass MUST reject with E_NAME (5) any module name, parameter, or local declared more than once in the same scope, and any local, parameter, or capture that shadows another local, parameter, or capture, and any capture that shadows a module name.
FR-003: The typecheck pass MUST reject with E_NAME (5) the four C namespace and order conflicts: a module initializer naming a later const; a literal const written as #define that rewrites a local, parameter, or field of the same name; a call of a function that a local shadows; a test or bench whose test_/bench_ C name collides with another declaration.
FR-004: The typecheck pass MUST reject with E_UNSOUND (17) any assignment to a for capture variable.
FR-005: The typecheck pass MUST accept sibling blocks reusing a name; a local or parameter shadowing a module var, an uncalled function, a struct, or a const that C writes as a variable; a function called before its declaration; a module var declared after the function that reads it.

Success Criteria

  • t27c typecheck on the name-resolution fixture suite exits 0 for all valid cases and exits non-zero with the expected error code (E_NAME=5 or E_UNSOUND=17) for all invalid cases
  • python -m pytest bootstrap/t27c.py -k "name_resolution" runs 12 tests and all pass (exit 0)
  • ./scripts/ddc-repin.sh completes successfully (exit 0)

Boundary

  • bootstrap/t27c.py

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions