File tree Expand file tree Collapse file tree 2 files changed +46
-1
lines changed Expand file tree Collapse file tree 2 files changed +46
-1
lines changed Original file line number Diff line number Diff line change @@ -50,8 +50,32 @@ class TypeVariableRefFinder : public ASTWalker {
50
50
51
51
std::pair<bool , Expr *> walkToExprPre (Expr *expr) override {
52
52
if (auto *DRE = dyn_cast<DeclRefExpr>(expr)) {
53
- if (auto type = CS.getTypeIfAvailable (DRE->getDecl ()))
53
+ auto *decl = DRE->getDecl ();
54
+
55
+ if (auto type = CS.getTypeIfAvailable (DRE->getDecl ())) {
56
+ // If this is not one of the closure parameters which
57
+ // is inferrable from the body, let's replace type
58
+ // variables with errors to avoid bringing external
59
+ // information to the element component.
60
+ if (type->hasTypeVariable () && !isa<ParamDecl>(decl)) {
61
+ // If there are type variables left in the simplified version,
62
+ // it means that this is an invalid external declaration
63
+ // relative to this element's context.
64
+ if (CS.simplifyType (type)->hasTypeVariable ()) {
65
+ auto transformedTy = type.transform ([&](Type type) {
66
+ if (auto *typeVar = type->getAs <TypeVariableType>()) {
67
+ return ErrorType::get (CS.getASTContext ());
68
+ }
69
+ return type;
70
+ });
71
+
72
+ CS.setType (decl, transformedTy);
73
+ return {true , expr};
74
+ }
75
+ }
76
+
54
77
inferVariables (type);
78
+ }
55
79
}
56
80
57
81
return {true , expr};
Original file line number Diff line number Diff line change @@ -329,3 +329,24 @@ func test_unknown_refs_in_tilde_operator() {
329
329
}
330
330
}
331
331
}
332
+
333
+ // rdar://92347054 - crash during conjunction processing
334
+ func test_no_crash_with_circular_ref_due_to_error( ) {
335
+ struct S { // expected-note {{did you mean 'S'?}}
336
+ var x : Int ?
337
+ }
338
+
339
+ func test( v: Int ? , arr: [ S ] ) -> Int { // expected-note {{did you mean 'v'?}}
340
+ // There is missing `f` here which made body of the
341
+ // `if` a multiple statement closure instead that uses
342
+ // `next` inside.
343
+ i let x = v, let next = arr. first? . x { // expected-error {{cannot find 'i' in scope}}
344
+ // expected-error@-1 {{consecutive statements on a line must be separated by ';'}}
345
+ // expected-error@-2 {{'let' cannot appear nested inside another 'var' or 'let' pattern}}
346
+ // expected-error@-3 {{cannot call value of non-function type 'Int?'}}
347
+ print ( next)
348
+ return x
349
+ }
350
+ return 0
351
+ }
352
+ }
You can’t perform that action at this time.
0 commit comments