From d84e9801b581c611c6a8ae0169cda5d54e221ae1 Mon Sep 17 00:00:00 2001 From: Qi Xiao Date: Sat, 9 Jan 2021 23:33:24 +0000 Subject: [PATCH] Don't compile the arguments of special commands twice. This fixes #1204. --- pkg/eval/compile_effect.go | 6 +++++- pkg/eval/compile_effect_test.go | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/pkg/eval/compile_effect.go b/pkg/eval/compile_effect.go index 681404bb..5ea03c76 100644 --- a/pkg/eval/compile_effect.go +++ b/pkg/eval/compile_effect.go @@ -184,11 +184,13 @@ func (cp *compiler) formOp(n *parse.Form) effectOp { if n.Head != nil { headStr, ok := oneString(n.Head) + argOpsNeeded := true if ok { special, fnRef := resolveCmdHeadInternally(cp, headStr, n.Head) switch { case special != nil: specialOp = special(cp, n) + argOpsNeeded = false case fnRef != nil: headOp = variableOp{n.Head.Range(), false, headStr + FnSuffix, fnRef} default: @@ -199,7 +201,9 @@ func (cp *compiler) formOp(n *parse.Form) effectOp { // expression. headOp = cp.compoundOp(n.Head) } - argOps = cp.compoundOps(n.Args) + if argOpsNeeded { + argOps = cp.compoundOps(n.Args) + } } else { // Assignment form. lhs := cp.parseCompoundLValues(n.Vars) diff --git a/pkg/eval/compile_effect_test.go b/pkg/eval/compile_effect_test.go index 19790948..bc4e7e42 100644 --- a/pkg/eval/compile_effect_test.go +++ b/pkg/eval/compile_effect_test.go @@ -70,6 +70,10 @@ func TestCompileEffect(t *testing.T) { // Command errors when any optional evaluation errors. That("put &x=[][1]").Throws(ErrorWithType(errs.OutOfRange{}), "[][1]"), + // Regression test for #1204; ensures that the arguments of special + // forms are not accidentally compiled twice. + That("nop (and (use builtin)); nop $builtin:echo~").DoesNothing(), + // Assignments // -----------