feat(switch): switch 允许重复 case 标签(match 仍禁止)

- HandlesMatch / MatchGenMixin:值标签去重仅对 match 生效;switch 允许重复 case
  标签(按书写顺序,先出现者生效);通配臂多个(default / case _)仍 fail-fast
- wiki/07-control-flow.md 同步该语义
This commit is contained in:
TermiNexus committed 2026-10-03 00:18:55 +08:00
1 parent fabd92adc7
commit a3bb62f2c3
1 file changed
+7 -6
+7 -6
View File
@@ -90,10 +90,11 @@ novirtual class MatchGenMixin:
m_node: ast.Match* = ast.Match*(node)
# 重名 case 检测(fail-fast):C 的 switch 不允许重复 case 标签(重复标签让
# 某个臂永远不可达,且常意味着漏改的分支);通配臂(match 的 `case _` /
# switch 的 `default`)只允许一个。在任何 IR 产出之前检查,保证报错即终止。
# 报文前缀按 is_switch 区分(switch / match),便于定位。
# 重名 case 检测(fail-fast):**match 不允许重复 case 标签**(重复标签让
# 某个臂永远不可达,且常意味着漏改的分支);**switch 允许重复标签**(按书写
# 顺序,先出现者生效),故仅对 match 做值标签去重。
# 通配臂(match 的 `case _` / switch 的 `default`)两者都只允许一个。
# 在任何 IR 产出之前检查,保证报错即终止。报文前缀按 is_switch 区分。
kind_label: str = "match"
default_label: str = "`case _`"
if m_node.is_switch != 0:
@@ -112,7 +113,7 @@ novirtual class MatchGenMixin:
if dpat.kind() == ast.ASTKind.MatchAs \
and rawptr[ast.MatchAs](dpat).pattern is None:
default_cnt = default_cnt + 1
else:
elif m_node.is_switch == 0:
dcj: int = dci + 1
while dcj < ccn:
dcase2: ast.AST* = cases_chk.get(dcj)
@@ -120,7 +121,7 @@ novirtual class MatchGenMixin:
dpat2: ast.AST* = rawptr[ast.MatchCase](dcase2).pattern
if self._case_label_same(dpat, dpat2) != 0:
self.Gen.TypeGenErr.fatal_error(dcase2,
f"{kind_label} 出现重名 case:第 {dci} 与第 {dcj} 个 case 的标签相同(C switch 不允许重复 case 标签)",
f"match 出现重名 case:第 {dci} 与第 {dcj} 个 case 的标签相同(match 不允许重复 case 标签)",
"SyntaxError")
dcj = dcj + 1
dci = dci + 1