Sema: Clean up diagnoseMissingOwnership()

- Pass down the TypeResolution instance so we can get the generic
  signature. This ensures we always use the correct signature in
  SIL mode.

- Don't diagnose if the type contains error types.
This commit is contained in:
Slava Pestov
2024-02-01 15:53:04 -05:00
parent 3fe15febc3
commit 2f4ed5a949
8 changed files with 29 additions and 40 deletions

View File

@@ -2323,17 +2323,20 @@ static Type validateParameterType(ParamDecl *decl) {
break;
}
if (auto *varargTypeRepr = dyn_cast<VarargTypeRepr>(nestedRepr)) {
// If the element is a variadic parameter, resolve the parameter type as if
// it were in non-parameter position, since we want functions to be
// @escaping in this case.
options.setContext(TypeResolverContext::VariadicFunctionInput);
options |= TypeResolutionFlags::Direct;
// If the element is a variadic parameter, resolve the parameter type as if
// it were in non-parameter position, since we want functions to be
// @escaping in this case.
options.setContext(isa<VarargTypeRepr>(nestedRepr)
? TypeResolverContext::VariadicFunctionInput
: TypeResolverContext::FunctionInput);
options |= TypeResolutionFlags::Direct;
const auto resolution =
TypeResolution::forInterface(dc, options, unboundTyOpener,
PlaceholderType::get,
/*packElementOpener*/ nullptr);
const auto resolution =
TypeResolution::forInterface(dc, options, unboundTyOpener,
PlaceholderType::get,
/*packElementOpener*/ nullptr);
if (auto *varargTypeRepr = dyn_cast<VarargTypeRepr>(nestedRepr)) {
Ty = resolution.resolveType(nestedRepr);
// Monovariadic types (T...) for <T> resolve to [T].
@@ -2347,13 +2350,6 @@ static Type validateParameterType(ParamDecl *decl) {
return ErrorType::get(ctx);
}
} else {
options.setContext(TypeResolverContext::FunctionInput);
options |= TypeResolutionFlags::Direct;
const auto resolution =
TypeResolution::forInterface(dc, options, unboundTyOpener,
PlaceholderType::get,
/*packElementOpener*/ nullptr);
Ty = resolution.resolveType(decl->getTypeRepr());
}
@@ -2364,8 +2360,7 @@ static Type validateParameterType(ParamDecl *decl) {
// Validate the presence of ownership for a parameter with an inverse applied.
if (!Ty->hasUnboundGenericType() &&
diagnoseMissingOwnership(ctx, dc, ownership,
decl->getTypeRepr(), Ty, options)) {
diagnoseMissingOwnership(ownership, decl->getTypeRepr(), Ty, resolution)) {
decl->setInvalid();
return ErrorType::get(ctx);
}

View File

@@ -2526,23 +2526,30 @@ bool TypeResolver::diagnoseMoveOnlyGeneric(TypeRepr *repr,
}
bool swift::diagnoseMissingOwnership(ASTContext &ctx, DeclContext *dc,
ParamSpecifier ownership,
bool swift::diagnoseMissingOwnership(ParamSpecifier ownership,
TypeRepr *repr, Type ty,
TypeResolutionOptions options) {
const TypeResolution &resolution) {
auto options = resolution.getOptions();
assert(!ty->hasError());
assert(!options.contains(TypeResolutionFlags::SILType));
if (options.hasBase(TypeResolverContext::EnumElementDecl))
return false; // no need for ownership in enum cases.
if (!isInterfaceTypeNoncopyable(ty, dc->getGenericEnvironmentOfContext()))
// The parameter type is written with respect to the surrounding
// generic environment.
ty = GenericEnvironment::mapTypeIntoContext(
resolution.getGenericSignature().getGenericEnvironment(),
ty);
if (ty->hasError() || !ty->isNoncopyable())
return false; // copyable types do not need ownership
if (ownership != ParamSpecifier::Default)
return false; // it has ownership
auto &diags = ctx.Diags;
auto &diags = resolution.getASTContext().Diags;
auto loc = repr->getLoc();
repr->setInvalid();
@@ -3776,8 +3783,7 @@ TypeResolver::resolveASTFunctionTypeParams(TupleTypeRepr *inputRepr,
if (inStage(TypeResolutionStage::Interface)
&& !ty->hasUnboundGenericType()
&& !options.contains(TypeResolutionFlags::SILMode)) {
diagnoseMissingOwnership(getASTContext(), dc, ownership,
eltTypeRepr, ty, options);
diagnoseMissingOwnership(ownership, eltTypeRepr, ty, resolution);
// @_staticExclusiveOnly types cannot be passed as 'inout' in function
// types.

View File

@@ -674,12 +674,10 @@ void diagnoseInvalidGenericArguments(SourceLoc loc, ValueDecl *decl,
/// \param repr the repr for the type of the parameter.
/// \param ty the non-error resolved type of the repr.
/// \param ownership the ownership kind of the parameter
/// \param dc the decl context used for resolving the type
/// \returns true iff a diagnostic was emitted and the \c repr was invalidated.
bool diagnoseMissingOwnership(ASTContext &ctx, DeclContext *dc,
ParamSpecifier ownership,
bool diagnoseMissingOwnership(ParamSpecifier ownership,
TypeRepr *repr, Type ty,
TypeResolutionOptions options);
const TypeResolution &resolution);
} // end namespace swift

View File

@@ -1,7 +1,5 @@
// RUN: %target-typecheck-verify-swift
// XFAIL: noncopyable_generics
//===----------------------------------------------------------------------===//
// Type-check function definitions
//===----------------------------------------------------------------------===//

View File

@@ -1,7 +1,5 @@
// RUN: %target-typecheck-verify-swift
// XFAIL: noncopyable_generics
protocol P {
associatedtype A
}

View File

@@ -1,7 +1,5 @@
// RUN: %target-typecheck-verify-swift
// XFAIL: noncopyable_generics
// Tests for typealias inside protocols
protocol Bad {

View File

@@ -1,7 +1,5 @@
// RUN: %target-typecheck-verify-swift
// XFAIL: noncopyable_generics
public struct Wrapped<Values>: Sequence where Values: Sequence {
public var values: Values

View File

@@ -1,7 +1,5 @@
// RUN: %target-typecheck-verify-swift
// XFAIL: noncopyable_generics
protocol P {
associatedtype A
}