@@ -4447,13 +4447,37 @@ fn checkMatchExpr(self: *Self, expr_idx: CIR.Expr.Idx, env: *Env, match: CIR.Exp
44474447 // If so, we'll skip exhaustiveness checking since the types may be invalid
44484448 var had_type_error = false ;
44494449
4450+ // For matches desugared from `?` operator, verify the condition unifies with Try type FIRST.
4451+ // If it doesn't, report the specific error and skip pattern checking to avoid confusing errors.
4452+ var has_invalid_try = false ;
4453+ if (match .is_try_suffix ) {
4454+ // Get the actual Try type from builtins and instantiate it with fresh type vars
4455+ const try_type_var = ModuleEnv .varFrom (self .builtin_ctx .try_stmt );
4456+ const copied_try_var = if (self .builtin_ctx .builtin_module ) | builtin_env |
4457+ try self .copyVar (try_type_var , builtin_env , Region .zero ())
4458+ else
4459+ try_type_var ;
4460+ const try_var = try self .instantiateVar (copied_try_var , env , .use_root_instantiated );
4461+
4462+ // Unify the condition with Try type
4463+ const try_result = try self .unify (try_var , cond_var , env );
4464+ if (! try_result .isOk ()) {
4465+ has_invalid_try = true ;
4466+ self .setDetailIfTypeMismatch (try_result , problem.TypeMismatchDetail { .invalid_try_operator = .{
4467+ .expr = match .cond ,
4468+ } });
4469+ }
4470+ }
4471+
44504472 // Manually check the 1st branch
44514473 // The type of the branch's body becomes the var other branch bodies must unify
44524474 // against.
44534475 const first_branch_idx = branch_idxs [0 ];
44544476 const first_branch = self .cir .store .getMatchBranch (first_branch_idx );
44554477 const first_branch_ptrn_idxs = self .cir .store .sliceMatchBranchPatterns (first_branch .patterns );
44564478
4479+ // Skip pattern checking if we already know the condition isn't a Try type
4480+ // This prevents confusing cascading errors about pattern incompatibility
44574481 for (first_branch_ptrn_idxs ) | branch_ptrn_idx | {
44584482 const branch_ptrn = self .cir .store .getMatchBranchPattern (branch_ptrn_idx );
44594483 try self .checkPattern (branch_ptrn .pattern , env );
@@ -4474,7 +4498,7 @@ fn checkMatchExpr(self: *Self, expr_idx: CIR.Expr.Idx, env: *Env, match: CIR.Exp
44744498 for (branch_idxs [1.. ], 1.. ) | branch_idx , branch_cur_index | {
44754499 const branch = self .cir .store .getMatchBranch (branch_idx );
44764500
4477- // First, check the patterns of this branch
4501+ // First, check the patterns of this branch (skip if invalid try to avoid confusing errors)
44784502 const branch_ptrn_idxs = self .cir .store .sliceMatchBranchPatterns (branch .patterns );
44794503 for (branch_ptrn_idxs , 0.. ) | branch_ptrn_idx , cur_ptrn_index | {
44804504 // Check the pattern's sub types
@@ -4509,7 +4533,7 @@ fn checkMatchExpr(self: *Self, expr_idx: CIR.Expr.Idx, env: *Env, match: CIR.Exp
45094533 for (branch_idxs [branch_cur_index + 1 .. ], branch_cur_index + 1.. ) | other_branch_idx , other_branch_cur_index | {
45104534 const other_branch = self .cir .store .getMatchBranch (other_branch_idx );
45114535
4512- // Still check the other patterns
4536+ // Still check the other patterns (skip if invalid try to avoid confusing errors)
45134537 const other_branch_ptrn_idxs = self .cir .store .sliceMatchBranchPatterns (other_branch .patterns );
45144538 for (other_branch_ptrn_idxs , 0.. ) | other_branch_ptrn_idx , other_cur_ptrn_index | {
45154539 // Check the pattern's sub types
@@ -4538,29 +4562,6 @@ fn checkMatchExpr(self: *Self, expr_idx: CIR.Expr.Idx, env: *Env, match: CIR.Exp
45384562 }
45394563 }
45404564
4541- // For matches desugared from `?` operator, verify the condition unifies with Try type.
4542- // If it doesn't, report an error. Skip exhaustiveness checking for invalid try since
4543- // the desugared match only handles Ok/Err branches and would report confusing errors.
4544- var has_invalid_try = false ;
4545- if (match .is_try_suffix ) {
4546- // Get the actual Try type from builtins and instantiate it with fresh type vars
4547- const try_type_var = ModuleEnv .varFrom (self .builtin_ctx .try_stmt );
4548- const copied_try_var = if (self .builtin_ctx .builtin_module ) | builtin_env |
4549- try self .copyVar (try_type_var , builtin_env , Region .zero ())
4550- else
4551- try_type_var ;
4552- const try_var = try self .instantiateVar (copied_try_var , env , .use_root_instantiated );
4553-
4554- // Unify the condition with Try type
4555- const try_result = try self .unify (try_var , cond_var , env );
4556- if (! try_result .isOk ()) {
4557- has_invalid_try = true ;
4558- self .setDetailIfTypeMismatch (try_result , problem.TypeMismatchDetail { .invalid_try_operator = .{
4559- .expr = match .cond ,
4560- } });
4561- }
4562- }
4563-
45644565 // Unify the root expr with the match value
45654566 _ = try self .unify (ModuleEnv .varFrom (expr_idx ), val_var , env );
45664567
0 commit comments