flan/test/programs/shadow-builtin.flan
Joseph Ferano e03028819c A defn named after a builtin now wins, and says so once
The author's rule: "allow shadowing but warn". A user (defn get ...) is
legal, the user's definition wins at every call site in the file that wrote
it, and the compiler warns once at the definition.

Builtin-wins was never a rule anybody wrote: named_call is one match on the
name, the builtin arms are string literals, and the three arms that look a
name up are the last three in it. So a guard goes first, the trailing three
are factored into ordinary_call, and both routes into it resolve a name the
same way.

The shadow stops at the file that declared it. An imported package's names
were qualified at the import, so a get written inside one is the builtin's
and stays the builtin's; the prelude is excluded by its file for the same
reason. programs/shadow-builtin.flan is both halves at once.

The warning prints from build_program, which is what every command and the
dev daemon's reload go through, in the shape --warn-memory established:
file:line:col, the squiggle, and an exit status that does not move.

And the message that described the old world is gone — the builtin-arity
note said a defn does not replace a builtin, which is no longer true and is
no longer reachable.
2026-09-20 19:46:43 +07:00

25 lines
997 B
Plaintext

;;;; A defn named after a builtin, and what the name means afterwards.
;;;;
;;;; "Allow shadowing but warn": this file's (defn get ...) is legal, it wins
;;;; at every call site in this file, and the compiler says so once at the
;;;; definition — the warning is on stderr and the exit status does not move.
;;;;
;;;; Two calls, and between them the whole rule:
;;;;
;;;; - (get p) is one argument, which the builtin get does not take. It
;;;; compiles, and it prints the field, because the name resolves to the
;;;; definition below and the builtin is not consulted about its arity.
;;;; - (shadowed/field m) reaches into the imported package, whose body calls
;;;; the builtin get on a dyn map. The shadow does not follow it there: a
;;;; package's own calls mean what they meant when the package was written.
(import shadowed "pkgs/shadowed")
(defstruct P [x i32])
(defn get [p P] i32 (.x p))
(defn main [] ()
(println (get (P {.x 7})))
(println (shadowed/field {:a 1 :b 4})))