@@ -2086,8 +2086,6 @@ namespace {
2086
2086
2087
2087
bool diagnoseMoveOnlyGeneric (TypeRepr *repr,
2088
2088
Type unboundTy, Type genericArgTy);
2089
- bool diagnoseMissingOwnership (TypeRepr *repr,
2090
- TypeResolutionOptions options);
2091
2089
2092
2090
bool diagnoseDisallowedExistential (TypeRepr *repr);
2093
2091
@@ -2360,60 +2358,49 @@ bool TypeResolver::diagnoseMoveOnlyGeneric(TypeRepr *repr,
2360
2358
return false ;
2361
2359
}
2362
2360
2363
- // / Assuming this repr has resolved to a noncopyable type, checks
2364
- // / to see if that resolution happened in a context requiring an ownership
2365
- // / annotation. If it did and there was no ownership specified, emits a
2366
- // / diagnostic.
2367
- // /
2368
- // / \returns true if an error diagnostic was emitted
2369
- bool TypeResolver::diagnoseMissingOwnership (TypeRepr *repr,
2370
- TypeResolutionOptions options) {
2371
- // Though this is only required on function inputs... we can ignore
2372
- // InoutFunctionInput since it's already got ownership.
2373
- if (!options.is (TypeResolverContext::FunctionInput))
2374
- return false ;
2375
2361
2376
- // Enum cases don't need to specify ownership for associated values
2362
+ bool swift::diagnoseMissingOwnership (ASTContext &ctx, DeclContext *dc,
2363
+ ParamSpecifier ownership,
2364
+ TypeRepr *repr, Type ty,
2365
+ TypeResolutionOptions options) {
2366
+ assert (!ty->hasError ());
2367
+ assert (!options.contains (TypeResolutionFlags::SILType));
2368
+
2377
2369
if (options.hasBase (TypeResolverContext::EnumElementDecl))
2378
- return false ;
2370
+ return false ; // no need for ownership in enum cases.
2379
2371
2380
- // Otherwise, we require ownership.
2381
- if (options.contains (TypeResolutionFlags::HasOwnership))
2382
- return false ;
2372
+ if (!ty->isNoncopyable (dc))
2373
+ return false ; // copyable types do not need ownership
2383
2374
2384
- // Don't diagnose in SIL; ownership is already required there.
2385
- if (options.contains (TypeResolutionFlags::SILType))
2386
- return false ;
2375
+ if (ownership != ParamSpecifier::Default)
2376
+ return false ; // it has ownership
2387
2377
2388
- // ////////////////
2389
- // At this point, we know we have a noncopyable parameter that is missing an
2390
- // ownership specifier, so we need to emit an error
2378
+ auto &diags = ctx. Diags ;
2379
+ auto loc = repr-> getLoc ();
2380
+ repr-> setInvalid ();
2391
2381
2392
2382
// We don't yet support any ownership specifiers for parameters of subscript
2393
2383
// decls, give a tailored error message saying you simply can't use a
2394
2384
// noncopyable type here.
2395
2385
if (options.hasBase (TypeResolverContext::SubscriptDecl)) {
2396
- diagnose (repr-> getLoc () , diag::noncopyable_parameter_subscript_unsupported);
2386
+ diags. diagnose (loc , diag::noncopyable_parameter_subscript_unsupported);
2397
2387
} else {
2398
2388
// general error diagnostic
2399
- diagnose (repr->getLoc (),
2400
- diag::noncopyable_parameter_requires_ownership);
2389
+ diags.diagnose (loc, diag::noncopyable_parameter_requires_ownership, ty);
2401
2390
2402
- diagnose (repr-> getLoc () , diag::noncopyable_parameter_ownership_suggestion,
2403
- " borrowing" , " for an immutable reference" )
2391
+ diags. diagnose (loc , diag::noncopyable_parameter_ownership_suggestion,
2392
+ " borrowing" , " for an immutable reference" )
2404
2393
.fixItInsert (repr->getStartLoc (), " borrowing " );
2405
2394
2406
- diagnose (repr-> getLoc () , diag::noncopyable_parameter_ownership_suggestion,
2407
- " inout" , " for a mutable reference" )
2395
+ diags. diagnose (loc , diag::noncopyable_parameter_ownership_suggestion,
2396
+ " inout" , " for a mutable reference" )
2408
2397
.fixItInsert (repr->getStartLoc (), " inout " );
2409
2398
2410
- diagnose (repr-> getLoc () , diag::noncopyable_parameter_ownership_suggestion,
2411
- " consuming" , " to take the value from the caller" )
2399
+ diags. diagnose (loc , diag::noncopyable_parameter_ownership_suggestion,
2400
+ " consuming" , " to take the value from the caller" )
2412
2401
.fixItInsert (repr->getStartLoc (), " consuming " );
2413
2402
}
2414
2403
2415
- // to avoid duplicate diagnostics
2416
- repr->setInvalid ();
2417
2404
return true ;
2418
2405
}
2419
2406
@@ -3473,6 +3460,8 @@ TypeResolver::resolveASTFunctionTypeParams(TupleTypeRepr *inputRepr,
3473
3460
SmallVector<AnyFunctionType::Param, 8 > elements;
3474
3461
elements.reserve (inputRepr->getNumElements ());
3475
3462
3463
+ auto *dc = getDeclContext ();
3464
+
3476
3465
auto elementOptions = options.withoutContext (true );
3477
3466
elementOptions.setContext (TypeResolverContext::FunctionInput);
3478
3467
for (unsigned i = 0 , end = inputRepr->getNumElements (); i != end; ++i) {
@@ -3517,7 +3506,7 @@ TypeResolver::resolveASTFunctionTypeParams(TupleTypeRepr *inputRepr,
3517
3506
if (ATR->getAttrs ().has (TAK_noDerivative)) {
3518
3507
if (diffKind == DifferentiabilityKind::NonDifferentiable &&
3519
3508
isDifferentiableProgrammingEnabled (
3520
- *getDeclContext () ->getParentSourceFile ()))
3509
+ *dc ->getParentSourceFile ()))
3521
3510
diagnose (nestedRepr->getLoc (),
3522
3511
diag::attr_only_on_parameters_of_differentiable,
3523
3512
" @noDerivative" )
@@ -3565,6 +3554,11 @@ TypeResolver::resolveASTFunctionTypeParams(TupleTypeRepr *inputRepr,
3565
3554
}
3566
3555
}
3567
3556
3557
+ // Validate the presence of ownership for a noncopyable parameter.
3558
+ if (inStage (TypeResolutionStage::Interface))
3559
+ diagnoseMissingOwnership (getASTContext (), dc, ownership,
3560
+ eltTypeRepr, ty, options);
3561
+
3568
3562
Identifier argumentLabel;
3569
3563
Identifier parameterName;
3570
3564
if (inputRepr->getElement (i).NameLoc .isValid () &&
@@ -4389,10 +4383,6 @@ TypeResolver::resolveDeclRefTypeRepr(DeclRefTypeRepr *repr,
4389
4383
}
4390
4384
}
4391
4385
4392
- // Noncopyable types must have an ownership specifier when used as a parameter
4393
- if (inStage (TypeResolutionStage::Interface) && result->isNoncopyable (dc))
4394
- diagnoseMissingOwnership (repr, options);
4395
-
4396
4386
// Hack to apply context-specific @escaping to a typealias with an underlying
4397
4387
// function type.
4398
4388
if (result->is <FunctionType>())
@@ -4435,9 +4425,6 @@ TypeResolver::resolveOwnershipTypeRepr(OwnershipTypeRepr *repr,
4435
4425
options.setContext (TypeResolverContext::InoutFunctionInput);
4436
4426
}
4437
4427
4438
- // Remember that we've seen an ownership specifier for this base type.
4439
- options |= TypeResolutionFlags::HasOwnership;
4440
-
4441
4428
auto result = resolveType (repr->getBase (), options);
4442
4429
if (result->hasError ())
4443
4430
return result;
0 commit comments