38
38
using namespace swift ;
39
39
40
40
ExportContext::ExportContext (DeclContext *DC, FragileFunctionKind kind,
41
- bool spi, bool exported, bool deprecated)
41
+ bool spi, bool exported, bool implicit,
42
+ bool deprecated)
42
43
: DC(DC), FragileKind(kind) {
43
44
SPI = spi;
44
45
Exported = exported;
46
+ Implicit = implicit;
45
47
Deprecated = deprecated;
46
48
Reason = ExportabilityReason::General;
47
49
}
@@ -180,12 +182,10 @@ ExportContext ExportContext::forDeclSignature(Decl *D) {
180
182
181
183
bool exported = ::isExported (D);
182
184
183
- return ExportContext (DC, fragileKind, spi, exported, deprecated);
185
+ return ExportContext (DC, fragileKind, spi, exported, implicit, deprecated);
184
186
}
185
187
186
188
ExportContext ExportContext::forFunctionBody (DeclContext *DC) {
187
- assert (DC && " Use ExportContext::forImplicit() for implicit decls" );
188
-
189
189
bool implicit = false ;
190
190
bool deprecated = false ;
191
191
forEachOuterDecl (DC,
@@ -204,12 +204,7 @@ ExportContext ExportContext::forFunctionBody(DeclContext *DC) {
204
204
assert (fragileKind.kind == FragileFunctionKind::None);
205
205
}
206
206
207
- return ExportContext (DC, fragileKind, spi, exported, deprecated);
208
- }
209
-
210
- ExportContext ExportContext::forImplicit () {
211
- return ExportContext (nullptr , FragileFunctionKind (),
212
- false , false , false );
207
+ return ExportContext (DC, fragileKind, spi, exported, implicit, deprecated);
213
208
}
214
209
215
210
ExportContext ExportContext::withReason (ExportabilityReason reason) const {
@@ -1700,29 +1695,6 @@ someEnclosingDeclMatches(SourceRange ReferenceRange,
1700
1695
return Pred (abstractSyntaxDeclForAvailableAttribute (DeclToSearch));
1701
1696
}
1702
1697
1703
- // / Returns true if the reference or any of its parents is an
1704
- // / implicit function.
1705
- static bool isInsideImplicitFunction (SourceRange ReferenceRange,
1706
- const DeclContext *DC) {
1707
- auto IsInsideImplicitFunc = [](const Decl *D) {
1708
- auto *AFD = dyn_cast<AbstractFunctionDecl>(D);
1709
- return AFD && AFD->isImplicit ();
1710
- };
1711
-
1712
- return someEnclosingDeclMatches (ReferenceRange, DC, IsInsideImplicitFunc);
1713
- }
1714
-
1715
- // / Returns true if the reference or any of its parents is an
1716
- // / unavailable (or obsoleted) declaration.
1717
- static bool isInsideUnavailableDeclaration (SourceRange ReferenceRange,
1718
- const DeclContext *ReferenceDC) {
1719
- auto IsUnavailable = [](const Decl *D) {
1720
- return D->getAttrs ().getUnavailable (D->getASTContext ());
1721
- };
1722
-
1723
- return someEnclosingDeclMatches (ReferenceRange, ReferenceDC, IsUnavailable);
1724
- }
1725
-
1726
1698
// / Returns true if the reference or any of its parents is an
1727
1699
// / unconditional unavailable declaration for the same platform.
1728
1700
static bool isInsideCompatibleUnavailableDeclaration (
@@ -2135,21 +2107,14 @@ void TypeChecker::diagnoseIfDeprecated(SourceRange ReferenceRange,
2135
2107
if (!Attr)
2136
2108
return ;
2137
2109
2138
- auto *ReferenceDC = Where.getDeclContext ();
2139
-
2140
- // We don't want deprecated declarations to trigger warnings
2141
- // in synthesized code.
2142
- if (ReferenceRange.isInvalid () &&
2143
- isInsideImplicitFunction (ReferenceRange, ReferenceDC)) {
2144
- return ;
2145
- }
2146
2110
// We match the behavior of clang to not report deprecation warnings
2147
2111
// inside declarations that are themselves deprecated on all deployment
2148
2112
// targets.
2149
2113
if (Where.isDeprecated ()) {
2150
2114
return ;
2151
2115
}
2152
2116
2117
+ auto *ReferenceDC = Where.getDeclContext ();
2153
2118
auto &Context = ReferenceDC->getASTContext ();
2154
2119
if (!Context.LangOpts .DisableAvailabilityChecking ) {
2155
2120
AvailabilityContext RunningOSVersions =
@@ -2351,16 +2316,6 @@ bool swift::diagnoseExplicitUnavailability(
2351
2316
if (!Attr)
2352
2317
return false ;
2353
2318
2354
- // Suppress the diagnostic if we are in synthesized code inside
2355
- // a synthesized function and the reference is lexically
2356
- // contained in a declaration that is itself marked unavailable.
2357
- // The right thing to do here is to not synthesize that code in the
2358
- // first place. rdar://problem/20491640
2359
- if (R.isInvalid () && isInsideImplicitFunction (R, DC) &&
2360
- isInsideUnavailableDeclaration (R, DC)) {
2361
- return false ;
2362
- }
2363
-
2364
2319
// Calling unavailable code from within code with the same
2365
2320
// unavailability is OK -- the eventual caller can't call the
2366
2321
// enclosing code in the same situations it wouldn't be able to
@@ -2512,20 +2467,6 @@ class AvailabilityWalker : public ASTWalker {
2512
2467
SmallVector<const Expr *, 16 > ExprStack;
2513
2468
ExportContext Where;
2514
2469
2515
- // / Returns true if DC is an \c init(rawValue:) declaration and it is marked
2516
- // / implicit.
2517
- bool inSynthesizedInitRawValue () {
2518
- auto *DC = Where.getDeclContext ();
2519
- auto init = dyn_cast_or_null<ConstructorDecl>(
2520
- DC->getInnermostDeclarationDeclContext ());
2521
-
2522
- return init &&
2523
- init->isImplicit () &&
2524
- init->getParameters ()->size () == 1 &&
2525
- init->getParameters ()->get (0 )->getArgumentName () ==
2526
- Context.Id_rawValue ;
2527
- }
2528
-
2529
2470
public:
2530
2471
AvailabilityWalker (ExportContext Where)
2531
2472
: Context(Where.getDeclContext()->getASTContext ()), Where(Where) {}
@@ -2548,20 +2489,8 @@ class AvailabilityWalker : public ASTWalker {
2548
2489
};
2549
2490
2550
2491
if (auto DR = dyn_cast<DeclRefExpr>(E)) {
2551
- DeclAvailabilityFlags flags = None;
2552
- if (inSynthesizedInitRawValue ())
2553
- // HACK: If a raw-value enum has cases with `@available(introduced:)`
2554
- // attributes, the auto-derived `init(rawValue:)` will contain
2555
- // DeclRefExprs which reference those cases. It will also contain
2556
- // appropriate `guard #available` statements to keep them from running
2557
- // on older versions, but the availability checker can't verify that
2558
- // because the synthesized code uses invalid SourceLocs. Don't diagnose
2559
- // these errors; instead, take it on faith that
2560
- // DerivedConformanceRawRepresentable will do the right thing.
2561
- flags |= DeclAvailabilityFlag::AllowPotentiallyUnavailable;
2562
-
2563
2492
diagAvailability (DR->getDeclRef (), DR->getSourceRange (),
2564
- getEnclosingApplyExpr (), flags );
2493
+ getEnclosingApplyExpr (), None );
2565
2494
maybeDiagStorageAccess (DR->getDecl (), DR->getSourceRange (), DC);
2566
2495
}
2567
2496
if (auto MR = dyn_cast<MemberRefExpr>(E)) {
@@ -2861,9 +2790,6 @@ AvailabilityWalker::diagAvailability(ConcreteDeclRef declRef, SourceRange R,
2861
2790
if (!isAccessorWithDeprecatedStorage)
2862
2791
TypeChecker::diagnoseIfDeprecated (R, Where, D, call);
2863
2792
2864
- if (Flags.contains (DeclAvailabilityFlag::AllowPotentiallyUnavailable))
2865
- return false ;
2866
-
2867
2793
if (Flags.contains (DeclAvailabilityFlag::AllowPotentiallyUnavailableProtocol)
2868
2794
&& isa<ProtocolDecl>(D))
2869
2795
return false ;
@@ -3041,7 +2967,10 @@ AvailabilityWalker::diagnoseMemoryLayoutMigration(const ValueDecl *D,
3041
2967
3042
2968
// / Diagnose uses of unavailable declarations.
3043
2969
void swift::diagAvailability (const Expr *E, DeclContext *DC) {
3044
- AvailabilityWalker walker (ExportContext::forFunctionBody (DC));
2970
+ auto where = ExportContext::forFunctionBody (DC);
2971
+ if (where.isImplicit ())
2972
+ return ;
2973
+ AvailabilityWalker walker (where);
3045
2974
const_cast <Expr*>(E)->walk (walker);
3046
2975
}
3047
2976
@@ -3051,8 +2980,8 @@ class StmtAvailabilityWalker : public ASTWalker {
3051
2980
ExportContext Where;
3052
2981
3053
2982
public:
3054
- explicit StmtAvailabilityWalker (DeclContext *DC )
3055
- : Where(ExportContext::forFunctionBody(DC) ) {}
2983
+ explicit StmtAvailabilityWalker (ExportContext where )
2984
+ : Where(where ) {}
3056
2985
3057
2986
// / We'll visit the expression from performSyntacticExprDiagnostics().
3058
2987
std::pair<bool , Expr *> walkToExprPre (Expr *E) override {
@@ -3079,7 +3008,11 @@ void swift::diagAvailability(const Stmt *S, DeclContext *DC) {
3079
3008
if (isa<BraceStmt>(S))
3080
3009
return ;
3081
3010
3082
- StmtAvailabilityWalker walker (DC);
3011
+ auto where = ExportContext::forFunctionBody (DC);
3012
+ if (where.isImplicit ())
3013
+ return ;
3014
+
3015
+ StmtAvailabilityWalker walker (where);
3083
3016
const_cast <Stmt*>(S)->walk (walker);
3084
3017
}
3085
3018
@@ -3281,6 +3214,7 @@ bool swift::diagnoseDeclAvailability(const ValueDecl *Decl,
3281
3214
ExportContext Where,
3282
3215
DeclAvailabilityFlags Flags)
3283
3216
{
3217
+ assert (!Where.isImplicit ());
3284
3218
AvailabilityWalker AW (Where);
3285
3219
return AW.diagAvailability (const_cast <ValueDecl *>(Decl), R, nullptr , Flags);
3286
3220
}
0 commit comments