Definition capabilities are not available later in the same term #540
Description
Describe the bug
When making a definition, the definition can be used later in the same term (separated by semicolon), but it is not in the map that records the capabilities/requirements of definitions, so a build
using it may not give the proper devices.
To Reproduce
Start a new classic mode game, and execute
def m = move end; build {m}
You will see that the robot is built but does not move. To see why this happens, quit and start a new game with --cheat
. First, switch to creative and create "logger"
, then switch back. Now execute
def m = move end; r <- build {log "hi"; m}; view r
We can see that the built robot does not have any treads
, and failed with a runtime capability check saying that it does not have the devices necessary to move
. The problem is that at the time the build
is executed, the capability map does not have an entry for m
, so capability analysis on the program log "hi"; m
concludes that it needs only a logger
and a solar panel
.
Note that let
seems to have the same issue. For example, we get the same behavior using something like let m = move in build {m}
.
Expected behavior
Anything defined with def
should be fully available (including capability analysis) immediately after the definition.
Additional context
Discovered this while preparing #533. This is especially a problem in test scenarios, where a solution program to be run on the base must consist of a single term (as opposed to interactive use, where many separate programs are executed in sequence). Any test scenario which wishes to use a def
as part of its solution program will likely not work at the moment.
Also, none of this will be an issue once we (eventually) implement some kind of effect type system with built-in capability tracking, as in #231 .