@@ -1237,19 +1237,41 @@ bool RValueTreatedAsLValueFailure::diagnoseAsError() {
1237
1237
subElementDiagID = diag::assignment_lhs_is_apply_expression;
1238
1238
}
1239
1239
} else if (auto inoutExpr = dyn_cast<InOutExpr>(diagExpr)) {
1240
- if (auto restriction = getRestrictionForType (getType (inoutExpr))) {
1241
- PointerTypeKind pointerKind;
1242
- if (restriction->second == ConversionRestrictionKind::ArrayToPointer &&
1243
- restriction->first ->getAnyPointerElementType (pointerKind) &&
1244
- (pointerKind == PTK_UnsafePointer ||
1245
- pointerKind == PTK_UnsafeRawPointer)) {
1246
- // If we're converting to an UnsafePointer, then the programmer
1247
- // specified an & unnecessarily. Produce a fixit hint to remove it.
1248
- emitDiagnostic (inoutExpr->getLoc (),
1249
- diag::extra_address_of_unsafepointer, restriction->first )
1250
- .highlight (inoutExpr->getSourceRange ())
1251
- .fixItRemove (inoutExpr->getStartLoc ());
1252
- return true ;
1240
+ if (auto *parentExpr = findParentExpr (inoutExpr)) {
1241
+ if (auto *call =
1242
+ dyn_cast_or_null<ApplyExpr>(findParentExpr (parentExpr))) {
1243
+ // Since this `inout` expression is an argument to a call/operator
1244
+ // let's figure out whether this is an impliict conversion from
1245
+ // array to an unsafe pointer type and diagnose it.
1246
+ unsigned argIdx = 0 ;
1247
+ if (auto *TE = dyn_cast<TupleExpr>(parentExpr)) {
1248
+ for (unsigned n = TE->getNumElements (); argIdx != n; ++argIdx) {
1249
+ if (TE->getElement (argIdx) == inoutExpr)
1250
+ break ;
1251
+ }
1252
+ }
1253
+
1254
+ auto *argLoc = getConstraintLocator (
1255
+ call, {ConstraintLocator::ApplyArgument,
1256
+ LocatorPathElt::ApplyArgToParam (argIdx, argIdx,
1257
+ ParameterTypeFlags ())});
1258
+
1259
+ if (auto info = getFunctionArgApplyInfo (argLoc)) {
1260
+ auto &cs = getConstraintSystem ();
1261
+ auto paramType = info->getParamType ();
1262
+ auto argType = getType (inoutExpr)->getWithoutSpecifierType ();
1263
+
1264
+ PointerTypeKind ptr;
1265
+ if (cs.isArrayType (argType) &&
1266
+ paramType->getAnyPointerElementType (ptr) &&
1267
+ (ptr == PTK_UnsafePointer || ptr == PTK_UnsafeRawPointer)) {
1268
+ emitDiagnostic (inoutExpr->getLoc (),
1269
+ diag::extra_address_of_unsafepointer, paramType)
1270
+ .highlight (inoutExpr->getSourceRange ())
1271
+ .fixItRemove (inoutExpr->getStartLoc ());
1272
+ return true ;
1273
+ }
1274
+ }
1253
1275
}
1254
1276
}
1255
1277
0 commit comments