@@ -63,7 +63,6 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E,
63
63
bool isExprStmt) {
64
64
class DiagnoseWalker : public ASTWalker {
65
65
SmallPtrSet<Expr*, 4 > AlreadyDiagnosedMetatypes;
66
- SmallPtrSet<DeclRefExpr*, 4 > AlreadyDiagnosedNoEscapes;
67
66
SmallPtrSet<DeclRefExpr*, 4 > AlreadyDiagnosedBitCasts;
68
67
69
68
// Keep track of acceptable DiscardAssignmentExpr's.
@@ -84,23 +83,6 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E,
84
83
DiagnoseWalker (TypeChecker &TC, const DeclContext *DC, bool isExprStmt)
85
84
: IsExprStmt(isExprStmt), TC(TC), DC(DC) {}
86
85
87
- // Selector for the partial_application_of_function_invalid diagnostic
88
- // message.
89
- struct PartialApplication {
90
- enum : unsigned {
91
- MutatingMethod,
92
- SuperInit,
93
- SelfInit,
94
- };
95
- enum : unsigned {
96
- Error,
97
- CompatibilityWarning,
98
- };
99
- unsigned compatibilityWarning: 1 ;
100
- unsigned kind : 2 ;
101
- unsigned level : 29 ;
102
- };
103
-
104
86
// Not interested in going outside a basic expression.
105
87
std::pair<bool , Stmt *> walkToStmtPre (Stmt *S) override {
106
88
return { false , S };
@@ -129,9 +111,6 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E,
129
111
checkUseOfMetaTypeName (Base);
130
112
}
131
113
132
- // Verify noescape parameter uses.
133
- checkNoEscapeParameterUse (DRE, Parent.getAsExpr (), OperandKind::None);
134
-
135
114
// Verify warn_unqualified_access uses.
136
115
checkUnqualifiedAccessUse (DRE);
137
116
@@ -155,12 +134,6 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E,
155
134
if (auto *IOE = dyn_cast<InOutExpr>(SE->getBase ()))
156
135
if (IOE->isImplicit ())
157
136
AcceptableInOutExprs.insert (IOE);
158
-
159
- visitIndices (SE, [&](unsigned argIndex, Expr *arg) {
160
- arg = lookThroughArgument (arg);
161
- if (auto *DRE = dyn_cast<DeclRefExpr>(arg))
162
- checkNoEscapeParameterUse (DRE, SE, OperandKind::Argument);
163
- });
164
137
}
165
138
166
139
if (auto *KPE = dyn_cast<KeyPathExpr>(E)) {
@@ -170,21 +143,6 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E,
170
143
}
171
144
}
172
145
173
- if (auto *AE = dyn_cast<CollectionExpr>(E)) {
174
- visitCollectionElements (AE, [&](unsigned argIndex, Expr *arg) {
175
- arg = lookThroughArgument (arg);
176
- if (auto *DRE = dyn_cast<DeclRefExpr>(arg))
177
- checkNoEscapeParameterUse (DRE, AE, OperandKind::Argument);
178
- });
179
- }
180
-
181
- // Check decl refs in withoutActuallyEscaping blocks.
182
- if (auto MakeEsc = dyn_cast<MakeTemporarilyEscapableExpr>(E)) {
183
- if (auto DRE =
184
- dyn_cast<DeclRefExpr>(MakeEsc->getNonescapingClosureValue ()))
185
- checkNoEscapeParameterUse (DRE, MakeEsc, OperandKind::MakeEscapable);
186
- }
187
-
188
146
// Check function calls, looking through implicit conversions on the
189
147
// function and inspecting the arguments directly.
190
148
if (auto *Call = dyn_cast<ApplyExpr>(E)) {
@@ -221,7 +179,10 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E,
221
179
222
180
ConcreteDeclRef callee;
223
181
if (auto *calleeDRE = dyn_cast<DeclRefExpr>(base)) {
224
- checkNoEscapeParameterUse (calleeDRE, Call, OperandKind::Callee);
182
+ // This only cares about declarations of noescape function type.
183
+ auto AFT = calleeDRE->getType ()->getAs <FunctionType>();
184
+ if (AFT && AFT->isNoEscape ())
185
+ checkNoEscapeParameterCall (Call);
225
186
checkForSuspiciousBitCasts (calleeDRE, Call);
226
187
callee = calleeDRE->getDeclRef ();
227
188
@@ -267,12 +228,6 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E,
267
228
unwrapped, operand);
268
229
}
269
230
}
270
-
271
- // Also give special treatment to noescape function arguments.
272
- arg = lookThroughArgument (arg);
273
-
274
- if (auto *DRE = dyn_cast<DeclRefExpr>(arg))
275
- checkNoEscapeParameterUse (DRE, Call, OperandKind::Argument);
276
231
});
277
232
}
278
233
@@ -339,25 +294,12 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E,
339
294
}
340
295
}
341
296
342
- static void visitIndices (SubscriptExpr *subscript,
343
- llvm::function_ref<void (unsigned , Expr*)> fn) {
344
- auto *indexArgs = subscript->getIndex ();
345
- argExprVisitArguments (indexArgs, fn);
346
- }
347
-
348
297
static void visitArguments (ApplyExpr *apply,
349
298
llvm::function_ref<void (unsigned , Expr*)> fn) {
350
299
auto *arg = apply->getArg ();
351
300
argExprVisitArguments (arg, fn);
352
301
}
353
302
354
- static void visitCollectionElements (CollectionExpr *collection,
355
- llvm::function_ref<void (unsigned , Expr*)> fn) {
356
- auto elts = collection->getElements ();
357
- for (auto i : indices (elts))
358
- fn (i, elts[i]);
359
- }
360
-
361
303
static Expr *lookThroughArgument (Expr *arg) {
362
304
while (1 ) {
363
305
if (auto conv = dyn_cast<ImplicitConversionExpr>(arg))
@@ -572,61 +514,6 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E,
572
514
.highlight (problematicArg->getSourceRange ());
573
515
}
574
516
575
- enum class OperandKind {
576
- None,
577
- Callee,
578
- Argument,
579
- MakeEscapable,
580
- };
581
-
582
- // / The DRE argument is a reference to a noescape parameter. Verify that
583
- // / its uses are ok.
584
- void checkNoEscapeParameterUse (DeclRefExpr *DRE, Expr *parent,
585
- OperandKind useKind) {
586
- // This only cares about declarations of noescape function type.
587
- auto AFT = DRE->getType ()->getAs <FunctionType>();
588
- if (!AFT || !AFT->isNoEscape ())
589
- return ;
590
-
591
- // Only diagnose this once. If we check and accept this use higher up in
592
- // the AST, don't recheck here.
593
- if (!AlreadyDiagnosedNoEscapes.insert (DRE).second )
594
- return ;
595
-
596
- // The only valid use of the noescape parameter is an immediate call,
597
- // either as the callee or as an argument (in which case, the typechecker
598
- // validates that the noescape bit didn't get stripped off), or as
599
- // a special case, e.g. in the binding of a withoutActuallyEscaping block
600
- // or the argument of a type(of: ...).
601
- if (parent) {
602
- if (auto apply = dyn_cast<ApplyExpr>(parent)) {
603
- if (isa<ParamDecl>(DRE->getDecl ()) && useKind == OperandKind::Callee)
604
- checkNoEscapeParameterCall (apply);
605
- return ;
606
- } else if (isa<SubscriptExpr>(parent)
607
- && useKind == OperandKind::Argument) {
608
- return ;
609
- } else if (isa<MakeTemporarilyEscapableExpr>(parent)) {
610
- return ;
611
- } else if (isa<DynamicTypeExpr>(parent)) {
612
- return ;
613
- }
614
- }
615
-
616
- TC.diagnose (DRE->getStartLoc (), diag::invalid_noescape_use,
617
- cast<VarDecl>(DRE->getDecl ())->getName (),
618
- isa<ParamDecl>(DRE->getDecl ()));
619
-
620
- // If we're a parameter, emit a helpful fixit to add @escaping
621
- auto paramDecl = dyn_cast<ParamDecl>(DRE->getDecl ());
622
- if (paramDecl) {
623
- TC.diagnose (paramDecl->getStartLoc (), diag::noescape_parameter,
624
- paramDecl->getName ())
625
- .fixItInsert (paramDecl->getTypeLoc ().getSourceRange ().Start ,
626
- " @escaping " );
627
- }
628
- }
629
-
630
517
// Diagnose metatype values that don't appear as part of a property,
631
518
// method, or constructor reference.
632
519
void checkUseOfMetaTypeName (Expr *E) {
0 commit comments