Skip to content

checker.compareNodes treats a source file missing from fileIndexMap as file index 0 #64218

Description

@NAVEENKUMARKR777

🔎 Search Terms

compareNodes fileIndexMap, CompareTypes ordering, unindexed source file

Version & Regression Information

Code

internal/checker/utilities.go:

func (c *Checker) compareNodes(n1, n2 *ast.Node) int {
	...
	s1 := ast.GetSourceFileOfNode(n1)
	s2 := ast.GetSourceFileOfNode(n2)
	if s1 != s2 {
		f1 := c.fileIndexMap[s1]
		f2 := c.fileIndexMap[s2]
		// Order by index of file in the containing program
		return f1 - f2
	}
	...
}

fileIndexMap (createFileIndexMap in checker.go) is built only from the program's own file list. A source file that isn't a key — e.g. a synthetic file constructed by a custom host, or a content-mapper-produced supplemental file parsed outside the program — hits a plain map lookup, which returns Go's zero value for a missing key. That's indistinguishable from a real file that actually occupies index 0.

Actual behavior

  • An unindexed file compares as equal to whichever real file occupies index 0.
  • Two different unindexed files compare as equal to each other.

compareNodes/CompareTypes aren't purely cosmetic — they're used as a tiebreaker during real type inference (inference.go), so a wrong comparison here can affect more than display/declaration-emit order.

Expected behavior

A file missing from fileIndexMap should never be treated as if it were index 0. It should consistently sort relative to indexed files (e.g. always after them), and two different unindexed files should not collapse to "equal" — they should still get some deterministic order (e.g. by file name).

Fix

Opened #64217, which extracts the comparison into a small helper that uses the two-value map form to distinguish "index 0" from "not present," and adds a unit test constructing exactly this scenario (one indexed file, two independently-parsed never-indexed files).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions