@@ -2086,8 +2086,6 @@ namespace {
20862086
20872087 bool diagnoseMoveOnlyGeneric (TypeRepr *repr,
20882088 Type unboundTy, Type genericArgTy);
2089- bool diagnoseMissingOwnership (TypeRepr *repr,
2090- TypeResolutionOptions options);
20912089
20922090 bool diagnoseDisallowedExistential (TypeRepr *repr);
20932091
@@ -2360,60 +2358,49 @@ bool TypeResolver::diagnoseMoveOnlyGeneric(TypeRepr *repr,
23602358 return false ;
23612359}
23622360
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 ;
23752361
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+
23772369 if (options.hasBase (TypeResolverContext::EnumElementDecl))
2378- return false ;
2370+ return false ; // no need for ownership in enum cases.
23792371
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
23832374
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
23872377
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 ();
23912381
23922382 // We don't yet support any ownership specifiers for parameters of subscript
23932383 // decls, give a tailored error message saying you simply can't use a
23942384 // noncopyable type here.
23952385 if (options.hasBase (TypeResolverContext::SubscriptDecl)) {
2396- diagnose (repr-> getLoc () , diag::noncopyable_parameter_subscript_unsupported);
2386+ diags. diagnose (loc , diag::noncopyable_parameter_subscript_unsupported);
23972387 } else {
23982388 // general error diagnostic
2399- diagnose (repr->getLoc (),
2400- diag::noncopyable_parameter_requires_ownership);
2389+ diags.diagnose (loc, diag::noncopyable_parameter_requires_ownership, ty);
24012390
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" )
24042393 .fixItInsert (repr->getStartLoc (), " borrowing " );
24052394
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" )
24082397 .fixItInsert (repr->getStartLoc (), " inout " );
24092398
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" )
24122401 .fixItInsert (repr->getStartLoc (), " consuming " );
24132402 }
24142403
2415- // to avoid duplicate diagnostics
2416- repr->setInvalid ();
24172404 return true ;
24182405}
24192406
@@ -3473,6 +3460,8 @@ TypeResolver::resolveASTFunctionTypeParams(TupleTypeRepr *inputRepr,
34733460 SmallVector<AnyFunctionType::Param, 8 > elements;
34743461 elements.reserve (inputRepr->getNumElements ());
34753462
3463+ auto *dc = getDeclContext ();
3464+
34763465 auto elementOptions = options.withoutContext (true );
34773466 elementOptions.setContext (TypeResolverContext::FunctionInput);
34783467 for (unsigned i = 0 , end = inputRepr->getNumElements (); i != end; ++i) {
@@ -3517,7 +3506,7 @@ TypeResolver::resolveASTFunctionTypeParams(TupleTypeRepr *inputRepr,
35173506 if (ATR->getAttrs ().has (TAK_noDerivative)) {
35183507 if (diffKind == DifferentiabilityKind::NonDifferentiable &&
35193508 isDifferentiableProgrammingEnabled (
3520- *getDeclContext () ->getParentSourceFile ()))
3509+ *dc ->getParentSourceFile ()))
35213510 diagnose (nestedRepr->getLoc (),
35223511 diag::attr_only_on_parameters_of_differentiable,
35233512 " @noDerivative" )
@@ -3565,6 +3554,11 @@ TypeResolver::resolveASTFunctionTypeParams(TupleTypeRepr *inputRepr,
35653554 }
35663555 }
35673556
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+
35683562 Identifier argumentLabel;
35693563 Identifier parameterName;
35703564 if (inputRepr->getElement (i).NameLoc .isValid () &&
@@ -4389,10 +4383,6 @@ TypeResolver::resolveDeclRefTypeRepr(DeclRefTypeRepr *repr,
43894383 }
43904384 }
43914385
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-
43964386 // Hack to apply context-specific @escaping to a typealias with an underlying
43974387 // function type.
43984388 if (result->is <FunctionType>())
@@ -4435,9 +4425,6 @@ TypeResolver::resolveOwnershipTypeRepr(OwnershipTypeRepr *repr,
44354425 options.setContext (TypeResolverContext::InoutFunctionInput);
44364426 }
44374427
4438- // Remember that we've seen an ownership specifier for this base type.
4439- options |= TypeResolutionFlags::HasOwnership;
4440-
44414428 auto result = resolveType (repr->getBase (), options);
44424429 if (result->hasError ())
44434430 return result;
0 commit comments