From bcbe967fdd1d26bc138092d9d6a36e28c55940d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Thu, 27 Jul 2023 15:02:37 +0100 Subject: [PATCH] internal/core/compile: reject "_" as an alias name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "_" stands for "top", and it was already being rejected as a label, but it was still being allowed for alias or let declarations, causing confusing errors such as: unreferenced alias or let clause _ Reject all three the same way. Fixes #2381. Signed-off-by: Daniel Martí Change-Id: Iad909813756c5df4421e96e0bdb2a071dc7c66f1 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/556985 TryBot-Result: CUEcueckoo Unity-Result: CUE porcuepine Reviewed-by: Marcel van Lohuizen --- cue/testdata/compile/err_top.txtar | 48 ++++++++++++++++++++++++++++++ cue/testdata/compile/labels.txtar | 20 ------------- internal/core/compile/compile.go | 3 ++ 3 files changed, 51 insertions(+), 20 deletions(-) create mode 100644 cue/testdata/compile/err_top.txtar diff --git a/cue/testdata/compile/err_top.txtar b/cue/testdata/compile/err_top.txtar new file mode 100644 index 00000000000..cb869d8a2c2 --- /dev/null +++ b/cue/testdata/compile/err_top.txtar @@ -0,0 +1,48 @@ +-- in.cue -- +disallowTopAsAlias: { + _=X: 1 +} + +disallowTopAsLet: { + let _ = 1 +} + +disallowTopAsLabel: { + _: 1 + a: _ // Should not compile to a reference. +} + +// TODO: disallow dollar as label? This is according to the spec, but it +// will be a breaking change and $ was reserved for referring to the root of +// a file, which we very likely will never implement. +// disallowDollarAsLabel: { +// $: 1 +// } + +-- out/compile -- +disallowTopAsAlias: cannot use _ as alias or let clause: + ./in.cue:2:2 +disallowTopAsLet: cannot use _ as alias or let clause: + ./in.cue:6:6 +disallowTopAsLabel: cannot use _ as label: + ./in.cue:10:2 +--- in.cue +{ + disallowTopAsAlias: { + X: 1 + } + disallowTopAsLet: { + let _ = 1 + } + disallowTopAsLabel: { + _|_(cannot use _ as label) + a: _ + } +} +-- out/eval -- +disallowTopAsAlias: cannot use _ as alias or let clause: + ./in.cue:2:2 +disallowTopAsLet: cannot use _ as alias or let clause: + ./in.cue:6:6 +disallowTopAsLabel: cannot use _ as label: + ./in.cue:10:2 diff --git a/cue/testdata/compile/labels.txtar b/cue/testdata/compile/labels.txtar index 563c3a40f54..0c9c60f37c6 100644 --- a/cue/testdata/compile/labels.txtar +++ b/cue/testdata/compile/labels.txtar @@ -24,18 +24,6 @@ ok11: [list.FlattenN([string], 1)]: string // disallowed in evaluator bad1: [ for x in [1, 2, 3] {x}]: string -disallowTopAsLabel: { - _: 1 - a: _ // Should not compile to a reference. -} - -// TODO: disallow dollar as label? This is according to the spec, but it -// will be a breaking change and $ was reserved for referring to the root of -// a file, which we very likely will never implement. -// disallowDollarAsLabel: { -// $: 1 -// } - saneReferencesInComprehensions: { for _ in [1] { a: _ // Should not compile to a reference. @@ -44,8 +32,6 @@ saneReferencesInComprehensions: { -- out/compile -- bad1: comprehension values not allowed in this position: ./in.cue:24:9 -disallowTopAsLabel: cannot use _ as label: - ./in.cue:27:2 --- in.cue { dis1: ("dev"|"prd") @@ -95,10 +81,6 @@ disallowTopAsLabel: cannot use _ as label: bad1: { [_|_(comprehension values not allowed in this position)]: string } - disallowTopAsLabel: { - _|_(cannot use _ as label) - a: _ - } saneReferencesInComprehensions: { for _, _ in [ 1, @@ -110,5 +92,3 @@ disallowTopAsLabel: cannot use _ as label: -- out/eval -- bad1: comprehension values not allowed in this position: ./in.cue:24:9 -disallowTopAsLabel: cannot use _ as label: - ./in.cue:27:2 diff --git a/internal/core/compile/compile.go b/internal/core/compile/compile.go index 99f7b67ad27..f870b3ec05b 100644 --- a/internal/core/compile/compile.go +++ b/internal/core/compile/compile.go @@ -189,6 +189,9 @@ func (c *compiler) insertAlias(id *ast.Ident, a aliasEntry) *adt.Bottom { "alias %q already declared; previous declaration at %s", id.Name, e.source.Pos()) } + if id.Name == "_" { + return c.errf(id, "cannot use _ as alias or let clause") + } m[id.Name] = a return nil