mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Sema: remove TypeResolver::diagnoseMoveOnlyGeneric
This commit is contained in:
@@ -2106,9 +2106,6 @@ namespace {
|
|||||||
repr->setInvalid();
|
repr->setInvalid();
|
||||||
return diags.diagnose(std::forward<ArgTypes>(Args)...);
|
return diags.diagnose(std::forward<ArgTypes>(Args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool diagnoseMoveOnlyGeneric(TypeRepr *repr,
|
|
||||||
Type unboundTy, Type genericArgTy);
|
|
||||||
|
|
||||||
bool diagnoseDisallowedExistential(TypeRepr *repr);
|
bool diagnoseDisallowedExistential(TypeRepr *repr);
|
||||||
|
|
||||||
@@ -2500,33 +2497,6 @@ bool TypeResolver::diagnoseInvalidPlaceHolder(OpaqueReturnTypeRepr *repr) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks the given type, assuming that it appears as an argument for a
|
|
||||||
/// generic parameter in the \c repr, to see if it is move-only.
|
|
||||||
///
|
|
||||||
/// Because generic type parameters currently all assume copyability of
|
|
||||||
/// the substituted type, it's an error for a move-only type to appear
|
|
||||||
/// as an argument for type parameters.
|
|
||||||
///
|
|
||||||
/// returns true if an error diagnostic was emitted
|
|
||||||
bool TypeResolver::diagnoseMoveOnlyGeneric(TypeRepr *repr,
|
|
||||||
Type unboundTy,
|
|
||||||
Type genericArgTy) {
|
|
||||||
if (getASTContext().LangOpts.hasFeature(Feature::NoncopyableGenerics))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (genericArgTy->isNoncopyable()) {
|
|
||||||
if (unboundTy) {
|
|
||||||
diagnoseInvalid(repr, repr->getLoc(), diag::noncopyable_generics_specific,
|
|
||||||
genericArgTy, unboundTy);
|
|
||||||
} else {
|
|
||||||
diagnoseInvalid(repr, repr->getLoc(), diag::noncopyable_generics,
|
|
||||||
genericArgTy);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool swift::diagnoseMissingOwnership(ParamSpecifier ownership,
|
bool swift::diagnoseMissingOwnership(ParamSpecifier ownership,
|
||||||
TypeRepr *repr, Type ty,
|
TypeRepr *repr, Type ty,
|
||||||
@@ -5011,17 +4981,26 @@ NeverNullType TypeResolver::resolveArrayType(ArrayTypeRepr *repr,
|
|||||||
// If the standard library isn't loaded, we ought to let the user know
|
// If the standard library isn't loaded, we ought to let the user know
|
||||||
// something has gone terribly wrong, since the rest of the compiler is going
|
// something has gone terribly wrong, since the rest of the compiler is going
|
||||||
// to assume it can canonicalize [T] to Array<T>.
|
// to assume it can canonicalize [T] to Array<T>.
|
||||||
if (!ctx.getArrayDecl()) {
|
{
|
||||||
ctx.Diags.diagnose(repr->getBrackets().Start,
|
// Check that we can validly substitute the baseTy into an array. We do not
|
||||||
diag::sugar_type_not_found, 0);
|
// actually resolve to that valid array type, as we want to return the
|
||||||
return ErrorType::get(ctx);
|
// sugared Type node ArraySliceType instead!
|
||||||
}
|
auto *arrayDecl = ctx.getArrayDecl();
|
||||||
|
if (!arrayDecl) {
|
||||||
|
ctx.Diags.diagnose(repr->getBrackets().Start,
|
||||||
|
diag::sugar_type_not_found, 0);
|
||||||
|
return ErrorType::get(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
// do not allow move-only types in an array
|
Type genericArgs[1] = {baseTy};
|
||||||
if (diagnoseMoveOnlyGeneric(repr,
|
auto arrayTy =
|
||||||
ctx.getArrayDecl()->getDeclaredInterfaceType(),
|
resolution.applyUnboundGenericArguments(arrayDecl,
|
||||||
baseTy)) {
|
/*parentTy=*/nullptr,
|
||||||
return ErrorType::get(ctx);
|
repr->getBrackets().Start,
|
||||||
|
genericArgs);
|
||||||
|
if (arrayTy->hasError()) {
|
||||||
|
return ErrorType::get(ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ArraySliceType::get(baseTy);
|
return ArraySliceType::get(baseTy);
|
||||||
@@ -5116,11 +5095,17 @@ NeverNullType TypeResolver::resolveOptionalType(OptionalTypeRepr *repr,
|
|||||||
return ErrorType::get(ctx);
|
return ErrorType::get(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not allow move-only types in an optional
|
{
|
||||||
if (diagnoseMoveOnlyGeneric(repr,
|
// Check that we can validly substitute the baseTy into an Optional
|
||||||
ctx.getOptionalDecl()->getDeclaredInterfaceType(),
|
Type genericArgs[1] = {baseTy};
|
||||||
baseTy)) {
|
auto substTy =
|
||||||
return ErrorType::get(ctx);
|
resolution.applyUnboundGenericArguments(ctx.getOptionalDecl(),
|
||||||
|
/*parentTy=*/nullptr,
|
||||||
|
repr->getQuestionLoc(),
|
||||||
|
genericArgs);
|
||||||
|
if (substTy->hasError()) {
|
||||||
|
return ErrorType::get(ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return optionalTy;
|
return optionalTy;
|
||||||
@@ -5221,11 +5206,17 @@ NeverNullType TypeResolver::resolveImplicitlyUnwrappedOptionalType(
|
|||||||
return ErrorType::get(ctx);
|
return ErrorType::get(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not allow move-only types in an implicitly-unwrapped optional
|
{
|
||||||
if (diagnoseMoveOnlyGeneric(repr,
|
// Check that we can validly substitute the baseTy into an Optional
|
||||||
ctx.getOptionalDecl()->getDeclaredInterfaceType(),
|
Type genericArgs[1] = {baseTy};
|
||||||
baseTy)) {
|
auto substTy =
|
||||||
return ErrorType::get(ctx);
|
resolution.applyUnboundGenericArguments(ctx.getOptionalDecl(),
|
||||||
|
/*parentTy=*/nullptr,
|
||||||
|
repr->getExclamationLoc(),
|
||||||
|
genericArgs);
|
||||||
|
if (substTy->hasError()) {
|
||||||
|
return ErrorType::get(ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return uncheckedOptionalTy;
|
return uncheckedOptionalTy;
|
||||||
|
|||||||
@@ -286,6 +286,8 @@ enum class CheckedCastContextKind {
|
|||||||
};
|
};
|
||||||
|
|
||||||
namespace TypeChecker {
|
namespace TypeChecker {
|
||||||
|
// DANGER: callers must verify that elementType satisfies the requirements of
|
||||||
|
// the Wrapped generic parameter, as this function will not do so!
|
||||||
Type getOptionalType(SourceLoc loc, Type elementType);
|
Type getOptionalType(SourceLoc loc, Type elementType);
|
||||||
|
|
||||||
/// Bind an UnresolvedDeclRefExpr by performing name lookup and
|
/// Bind an UnresolvedDeclRefExpr by performing name lookup and
|
||||||
|
|||||||
@@ -484,3 +484,14 @@ struct SSS: ~Copyable, PPP {}
|
|||||||
protocol PPP: ~Copyable {}
|
protocol PPP: ~Copyable {}
|
||||||
let global__old__: any PPP = SSS() // expected-error {{value of type 'SSS' does not conform to specified type 'Copyable'}}
|
let global__old__: any PPP = SSS() // expected-error {{value of type 'SSS' does not conform to specified type 'Copyable'}}
|
||||||
let global__new__: any PPP & ~Copyable = SSS()
|
let global__new__: any PPP & ~Copyable = SSS()
|
||||||
|
|
||||||
|
|
||||||
|
struct Example<T> {}
|
||||||
|
|
||||||
|
struct TestResolution {
|
||||||
|
var maybeNC: NC? = nil // expected-error {{type 'NC' does not conform to protocol 'Copyable'}}
|
||||||
|
var maybeIOUNC: NC! = nil // expected-error {{type 'NC' does not conform to protocol 'Copyable'}}
|
||||||
|
var arrayNC: [NC] = [] // expected-error {{type 'NC' does not conform to protocol 'Copyable'}}
|
||||||
|
var dictNC: [String: NC] = [:] // expected-error {{type 'NC' does not conform to protocol 'Copyable'}}
|
||||||
|
var exampleNC: Example<NC> = Example() // expected-error {{type 'NC' does not conform to protocol 'Copyable'}}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user