@@ -13454,28 +13454,43 @@ parse_unwriteable_target(pm_parser_t *parser, pm_node_t *target) {
1345413454 return (pm_node_t *) result;
1345513455}
1345613456
13457+ static bool
13458+ parse_target_implicit_parameter_each(const pm_node_t *node, void *data) {
13459+ switch (PM_NODE_TYPE(node)) {
13460+ case PM_LOCAL_VARIABLE_READ_NODE:
13461+ case PM_IT_LOCAL_VARIABLE_READ_NODE: {
13462+ pm_parser_t *parser = (pm_parser_t *) data;
13463+ pm_node_list_t *implicit_parameters = &parser->current_scope->implicit_parameters;
13464+
13465+ for (size_t index = 0; index < implicit_parameters->size; index++) {
13466+ if (implicit_parameters->nodes[index] == node) {
13467+ // If the node is not the last one in the list, we need to
13468+ // shift the remaining nodes down to fill the gap. This is
13469+ // extremely unlikely to happen.
13470+ if (index != implicit_parameters->size - 1) {
13471+ memmove(&implicit_parameters->nodes[index], &implicit_parameters->nodes[index + 1], (implicit_parameters->size - index - 1) * sizeof(pm_node_t *));
13472+ }
13473+
13474+ implicit_parameters->size--;
13475+ break;
13476+ }
13477+ }
13478+
13479+ return false;
13480+ }
13481+ default:
13482+ return true;
13483+ }
13484+ }
13485+
1345713486/**
1345813487 * When an implicit local variable is written to or targeted, it becomes a
1345913488 * regular, named local variable. This function removes it from the list of
1346013489 * implicit parameters when that happens.
1346113490 */
1346213491static void
13463- parse_target_implicit_parameter(pm_parser_t *parser, pm_node_t *node) {
13464- pm_node_list_t *implicit_parameters = &parser->current_scope->implicit_parameters;
13465-
13466- for (size_t index = 0; index < implicit_parameters->size; index++) {
13467- if (implicit_parameters->nodes[index] == node) {
13468- // If the node is not the last one in the list, we need to shift the
13469- // remaining nodes down to fill the gap. This is extremely unlikely
13470- // to happen.
13471- if (index != implicit_parameters->size - 1) {
13472- memmove(&implicit_parameters->nodes[index], &implicit_parameters->nodes[index + 1], (implicit_parameters->size - index - 1) * sizeof(pm_node_t *));
13473- }
13474-
13475- implicit_parameters->size--;
13476- break;
13477- }
13478- }
13492+ parse_target_implicit_parameter(pm_parser_t *parser, const pm_node_t *node) {
13493+ pm_visit_node(node, parse_target_implicit_parameter_each, parser);
1347913494}
1348013495
1348113496/**
@@ -13851,18 +13866,12 @@ parse_write(pm_parser_t *parser, pm_node_t *target, pm_token_t *operator, pm_nod
1385113866 // syntax error. In this case we'll fall through to our default
1385213867 // handling. We need to free the value that we parsed because there
1385313868 // is no way for us to attach it to the tree at this point.
13854- switch (PM_NODE_TYPE(value)) {
13855- case PM_LOCAL_VARIABLE_READ_NODE:
13856- case PM_IT_LOCAL_VARIABLE_READ_NODE:
13857- // Since it is possible for the value to be an implicit
13858- // parameter, we need to remove it from the list of implicit
13859- // parameters.
13860- parse_target_implicit_parameter(parser, value);
13861- break;
13862- default:
13863- break;
13864- }
13865-
13869+ //
13870+ // Since it is possible for the value to contain an implicit
13871+ // parameter somewhere in its subtree, we need to walk it and remove
13872+ // any implicit parameters from the list of implicit parameters for
13873+ // the current scope.
13874+ parse_target_implicit_parameter(parser, value);
1386613875 pm_node_destroy(parser, value);
1386713876 }
1386813877 PRISM_FALLTHROUGH
0 commit comments