@@ -3171,27 +3171,38 @@ fn checkBlockStatements(self: *Self, statements: []const CIR.Statement.Idx, env:
31713171
31723172 switch (stmt ) {
31733173 .s_decl = > | decl_stmt | {
3174+ const decl_expr_var : Var = ModuleEnv .varFrom (decl_stmt .expr );
3175+ const decl_pattern_var : Var = ModuleEnv .varFrom (decl_stmt .pattern );
3176+
31743177 // Check the pattern
31753178 try self .checkPattern (decl_stmt .pattern , env , .no_expectation );
3176- const decl_pattern_var : Var = ModuleEnv .varFrom (decl_stmt .pattern );
3179+
3180+ // Create placeholder for the annotation, if it exists
3181+ var mb_instantiated_anno_var : ? Var = null ;
31773182
31783183 // Evaluate the rhs of the expression
3179- const decl_expr_var : Var = ModuleEnv .varFrom (decl_stmt .expr );
31803184 {
3185+ // Enter a new rank
3186+ try env .var_pool .pushRank ();
3187+ defer env .var_pool .popRank ();
3188+
31813189 // Check the annotation, if it exists
31823190 const expectation = blk : {
31833191 if (decl_stmt .anno ) | annotation_idx | {
31843192 // Generate the annotation type var in-place
31853193 try self .generateAnnotationType (annotation_idx , env );
31863194 const annotation_var = ModuleEnv .varFrom (annotation_idx );
31873195
3188- // TODO: If we instantiate here, then var lookups break. But if we don't
3189- // then the type anno gets corrupted if we have an error in the body
3190- // const instantiated_anno_var = try self.instantiateVarPreserveRigids(
3191- // annotation_var,
3192- // rank,
3193- // .use_last_var,
3194- // );
3196+ // Here we copy the annotation before we unify against it
3197+ //
3198+ // This is so if there's an error in the expr/ptrn, we can preserve
3199+ // the annotation so other places that reference it still get the
3200+ // type of the annotation.
3201+ mb_instantiated_anno_var = try self .instantiateVarPreserveRigids (
3202+ annotation_var ,
3203+ env ,
3204+ .use_last_var ,
3205+ );
31953206
31963207 // Return the expectation
31973208 break :blk Expected {
@@ -3202,10 +3213,6 @@ fn checkBlockStatements(self: *Self, statements: []const CIR.Statement.Idx, env:
32023213 }
32033214 };
32043215
3205- // Enter a new rank
3206- try env .var_pool .pushRank ();
3207- defer env .var_pool .popRank ();
3208-
32093216 does_fx = try self .checkExpr (decl_stmt .expr , env , expectation ) or does_fx ;
32103217
32113218 // Now that we are existing the scope, we must generalize then pop this rank
@@ -3215,10 +3222,19 @@ fn checkBlockStatements(self: *Self, statements: []const CIR.Statement.Idx, env:
32153222 try self .checkDeferredStaticDispatchConstraints (env );
32163223 }
32173224
3218- _ = try self .unify (decl_pattern_var , decl_expr_var , env );
3225+ if (mb_instantiated_anno_var != null and
3226+ self .types .resolveVar (decl_expr_var ).desc .content == .err )
3227+ {
3228+ // If there was an annotation AND the expr errored, then
3229+ // unify the ptrn against the annotation
3230+ const instantiated_anno_var = mb_instantiated_anno_var .? ;
3231+ _ = try self .unify (decl_pattern_var , instantiated_anno_var , env );
3232+ } else {
3233+ // Otherwise, unify the ptrn and expr
3234+ _ = try self .unify (decl_pattern_var , decl_expr_var , env );
3235+ }
32193236
32203237 // Unify the pattern with the expression
3221-
32223238 _ = try self .unify (stmt_var , decl_pattern_var , env );
32233239 },
32243240 .s_var = > | var_stmt | {
0 commit comments