@@ -2246,74 +2246,64 @@ bool AvailabilityWalker::diagnoseIncDecRemoval(const ValueDecl *D,
2246
2246
return false ;
2247
2247
}
2248
2248
2249
- // / If this is a call to an unavailable sizeof family functions , diagnose it
2249
+ // / If this is a call to an unavailable sizeof family function , diagnose it
2250
2250
// / with a fixit hint and return true. If not, or if we fail, return false.
2251
2251
bool AvailabilityWalker::diagnoseMemoryLayoutMigration (const ValueDecl *D,
2252
- SourceRange R,
2253
- const AvailableAttr *Attr,
2254
- const ApplyExpr *call) {
2252
+ SourceRange R,
2253
+ const AvailableAttr *Attr,
2254
+ const ApplyExpr *call) {
2255
2255
2256
2256
if (!D->getModuleContext ()->isStdlibModule ())
2257
2257
return false ;
2258
2258
2259
- std::pair<StringRef, bool > KindValue
2260
- = llvm::StringSwitch<std::pair<StringRef, bool >>(D->getNameStr ())
2261
- .Case (" sizeof" , {" size" , false })
2262
- .Case (" alignof" , {" alignment" , false })
2263
- .Case (" strideof" , {" stride" , false })
2264
- .Default ({});
2265
-
2266
- if (KindValue.first .empty ())
2259
+ StringRef Property = llvm::StringSwitch<StringRef>(D->getNameStr ())
2260
+ .Case (" sizeof" , " size" )
2261
+ .Case (" alignof" , " alignment" )
2262
+ .Case (" strideof" , " stride" )
2263
+ .Default (StringRef ());
2264
+ if (Property.empty ())
2267
2265
return false ;
2268
2266
2269
- auto Kind = KindValue.first ;
2270
- auto isValue = KindValue.second ;
2271
-
2272
2267
auto args = dyn_cast<ParenExpr>(call->getArg ());
2273
2268
if (!args)
2274
2269
return false ;
2275
2270
2276
- auto subject = args->getSubExpr ();
2277
- if (!isValue) {
2278
- // sizeof(type(of: x)) is equivalent to sizeofValue(x)
2279
- if (auto DTE = dyn_cast<DynamicTypeExpr>(subject)) {
2280
- subject = DTE->getBase ();
2281
- isValue = true ;
2282
- }
2283
- }
2284
-
2285
2271
EncodedDiagnosticMessage EncodedMessage (Attr->Message );
2286
2272
auto diag = TC.diagnose (R.Start , diag::availability_decl_unavailable_msg,
2287
2273
D->getFullName (), EncodedMessage.Message );
2288
2274
diag.highlight (R);
2289
2275
2276
+ auto subject = args->getSubExpr ();
2277
+
2290
2278
StringRef Prefix = " MemoryLayout<" ;
2291
2279
StringRef Suffix = " >." ;
2292
- if (isValue) {
2293
- auto valueType = subject->getType ()->getRValueType ();
2280
+
2281
+ if (auto DTE = dyn_cast<DynamicTypeExpr>(subject)) {
2282
+ // Replace `sizeof(type(of: x))` with `MemoryLayout<X>.size`, where `X` is
2283
+ // the static type of `x`. The previous spelling misleadingly hinted that
2284
+ // `sizeof(_:)` might return the size of the *dynamic* type of `x`, when
2285
+ // it is not the case.
2286
+ auto valueType = DTE->getBase ()->getType ()->getRValueType ();
2294
2287
if (!valueType || valueType->hasError ()) {
2295
- // If we don't have a suitable argument, we cannot emit a fix-it .
2288
+ // If we don't have a suitable argument, we can't emit a fixit .
2296
2289
return true ;
2297
2290
}
2298
-
2299
- // NOTE: We are destructively replacing the source text here.
2300
- // `sizeof(type(of: doSomething()))` => `MemoryLayout<T>.size`, where T is
2301
- // the return type of `doSomething()`. If that function has any side
2302
- // effects, this replacement will break the source.
2291
+ // Note that in rare circumstances we may be destructively replacing the
2292
+ // source text. For example, we'd replace `sizeof(type(of: doSomething()))`
2293
+ // with `MemoryLayout<T>.size`, if T is the return type of `doSomething()`.
2303
2294
diag.fixItReplace (call->getSourceRange (),
2304
- (Prefix + valueType->getString () + Suffix + Kind ).str ());
2295
+ (Prefix + valueType->getString () + Suffix + Property ).str ());
2305
2296
} else {
2306
2297
SourceRange PrefixRange (call->getStartLoc (), args->getLParenLoc ());
2307
2298
SourceRange SuffixRange (args->getRParenLoc ());
2308
2299
2309
- // We must truncate `.self`.
2310
- // E.g. sizeof(T.self) => MemoryLayout<T>.size
2300
+ // We must remove `.self`.
2311
2301
if (auto *DSE = dyn_cast<DotSelfExpr>(subject))
2312
2302
SuffixRange.Start = DSE->getDotLoc ();
2313
2303
2314
2304
diag
2315
2305
.fixItReplace (PrefixRange, Prefix)
2316
- .fixItReplace (SuffixRange, (Suffix + Kind ).str ());
2306
+ .fixItReplace (SuffixRange, (Suffix + Property ).str ());
2317
2307
}
2318
2308
2319
2309
return true ;
0 commit comments