vlang

/

v Public
0 commits 40 issues 0 pull requests 0 contributors Discussions Projects CI

committed 56 years ago · View patch
1 files changed +39 -3
vlib/v/gen/c/match.v +39 -3

@@ -194,6 +194,14 @@ fn (mut g Gen) match_expr_sumtype(node ast.MatchExpr, is_expr bool, cond_var str

194194 dot_or_ptr := g.dot_or_ptr(node.cond_type)

195195 use_ternary := is_expr && tmp_var == ''

196196 cond_sym := g.table.final_sym(node.cond_type)

197+ // Tracks the runtime type tags already handled by earlier arms of this match.

198+ // With alias/runtime-tag matching, a variant and an alias of it (e.g. `u8` and

199+ // `type EmptyExpr = u8`, both variants of the same sumtype) expand to the same

200+ // set of tags, so distinct arms can produce identical `_typ == ...` conditions.

201+ // Emitting both yields a duplicated `else if` condition (a -Wduplicated-cond

202+ // error under -cstrict) and the later arm is unreachable anyway, so drop the

203+ // already-covered tags and skip an arm once nothing fresh remains.

204+ mut seen_tag_idxs := map[string]bool{}

197205 for j, branch in node.branches {

198206 mut sumtype_index := 0

199207 // iterates through all types in sumtype branches

@@ -210,6 +218,36 @@ fn (mut g Gen) match_expr_sumtype(node ast.MatchExpr, is_expr bool, cond_var str

210218 branch_type = branch_expr.typ

211219 }

212220 }

221+ mut sumtype_fresh_idx_exprs := []string{}

222+ if !branch.is_else && cond_sym.kind == .sum_type && sumtype_index < branch.exprs.len {

223+ ce := unsafe { &branch.exprs[sumtype_index] }

224+ if ce is ast.TypeNode {

225+ variant_type := g.unwrap_generic(g.recheck_concrete_type(ce.typ))

226+ all_idx_exprs := g.matching_sumtype_variant_type_idx_exprs(node.cond_type,

227+ variant_type)

228+ if use_ternary {

229+ // Ternary `?:` chains cannot drop an arm, so keep every tag.

230+ sumtype_fresh_idx_exprs = all_idx_exprs.clone()

231+ } else {

232+ for idx_expr in all_idx_exprs {

233+ if idx_expr !in seen_tag_idxs {

234+ sumtype_fresh_idx_exprs << idx_expr

235+ }

236+ }

237+ if sumtype_fresh_idx_exprs.len == 0 {

238+ // every tag of this arm is already handled above: unreachable, skip it

239+ sumtype_index++

240+ if branch.exprs.len == 0 || sumtype_index == branch.exprs.len {

241+ break

242+ }

243+ continue

244+ }

245+ for idx_expr in sumtype_fresh_idx_exprs {

246+ seen_tag_idxs[idx_expr] = true

247+ }

248+ }

249+ }

250+ }

213251 if branch.is_else || (use_ternary && is_last) {

214252 if use_ternary {

215253 // TODO: too many branches. maybe separate ?: matches

@@ -248,9 +286,7 @@ fn (mut g Gen) match_expr_sumtype(node ast.MatchExpr, is_expr bool, cond_var str

248286 if cur_expr is ast.None {

249287 g.write('${tag_expr} == ${ast.none_type.idx()} /* none */')

250288 } else if cur_expr is ast.TypeNode {

251- variant_type := g.unwrap_generic(g.recheck_concrete_type(cur_expr.typ))

252- g.write_type_tag_condition(tag_expr, '==', g.matching_sumtype_variant_type_idx_exprs(node.cond_type,

253- variant_type))

289+ g.write_type_tag_condition(tag_expr, '==', sumtype_fresh_idx_exprs)

254290 } else {

255291 g.write('${tag_expr} == ')

256292 g.expr(cur_expr)