Skip to content

Remove some uses of FunctionType::Param::getOldType() and other cleanups #22468

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/swift/Basic/Statistics.def
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,12 @@ FRONTEND_STATISTIC(Sema, NumDeclsDeserialized)
/// Number of declarations validated.
FRONTEND_STATISTIC(Sema, NumDeclsValidated)

/// Number of declarations type checked.
FRONTEND_STATISTIC(Sema, NumDeclsTypechecked)

/// Number of declarations finalized.
FRONTEND_STATISTIC(Sema, NumDeclsFinalized)

/// Number of full function bodies typechecked.
FRONTEND_STATISTIC(Sema, NumFunctionsTypechecked)

Expand Down
13 changes: 9 additions & 4 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1034,13 +1034,17 @@ FuncDecl *ASTContext::getEqualIntDecl() const {
return nullptr;

auto intType = getIntDecl()->getDeclaredType();
auto isIntParam = [&](AnyFunctionType::Param param) {
return (!param.isVariadic() && !param.isInOut() &&
param.getPlainType()->isEqual(intType));
};
auto boolType = getBoolDecl()->getDeclaredType();
auto decl = lookupOperatorFunc(*this, "==",
intType, [=](FunctionType *type) {
// Check for the signature: (Int, Int) -> Bool
if (type->getParams().size() != 2) return false;
if (!type->getParams()[0].getOldType()->isEqual(intType) ||
!type->getParams()[1].getOldType()->isEqual(intType)) return false;
if (!isIntParam(type->getParams()[0]) ||
!isIntParam(type->getParams()[1])) return false;
return type->getResult()->isEqual(boolType);
});
getImpl().EqualIntDecl = decl;
Expand Down Expand Up @@ -1227,8 +1231,9 @@ FuncDecl *ASTContext::getIsOSVersionAtLeastDecl() const {
if (intrinsicsParams.size() != 3)
return nullptr;

if (llvm::any_of(intrinsicsParams, [](const AnyFunctionType::Param &p) {
return !isBuiltinWordType(p.getOldType());
if (llvm::any_of(intrinsicsParams, [](AnyFunctionType::Param param) {
return (param.isVariadic() || param.isInOut() ||
!isBuiltinWordType(param.getPlainType()));
})) {
return nullptr;
}
Expand Down
30 changes: 18 additions & 12 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4127,8 +4127,15 @@ findProtocolSelfReferences(const ProtocolDecl *proto, Type type,
// the parameter type.
if (auto funcTy = type->getAs<AnyFunctionType>()) {
auto inputKind = SelfReferenceKind::None();
for (auto &elt : funcTy->getParams()) {
inputKind |= findProtocolSelfReferences(proto, elt.getOldType(),
for (auto param : funcTy->getParams()) {
// inout parameters are invariant.
if (param.isInOut()) {
if (findProtocolSelfReferences(proto, param.getPlainType(),
skipAssocTypes)) {
return SelfReferenceKind::Other();
}
}
inputKind |= findProtocolSelfReferences(proto, param.getParameterType(),
skipAssocTypes);
}
auto resultKind = findProtocolSelfReferences(proto, funcTy->getResult(),
Expand Down Expand Up @@ -4159,14 +4166,6 @@ findProtocolSelfReferences(const ProtocolDecl *proto, Type type,
skipAssocTypes);
}

// InOut types are invariant.
if (auto inOutType = type->getAs<InOutType>()) {
if (findProtocolSelfReferences(proto, inOutType->getObjectType(),
skipAssocTypes)) {
return SelfReferenceKind::Other();
}
}

// Bound generic types are invariant.
if (auto boundGenericType = type->getAs<BoundGenericType>()) {
for (auto paramType : boundGenericType->getGenericArgs()) {
Expand Down Expand Up @@ -4237,8 +4236,15 @@ ProtocolDecl::findProtocolSelfReferences(const ValueDecl *value,
// as a function result type.
if (!allowCovariantParameters) {
auto inputKind = SelfReferenceKind::None();
for (auto &elt : type->castTo<AnyFunctionType>()->getParams()) {
inputKind |= ::findProtocolSelfReferences(this, elt.getOldType(),
for (auto param : type->castTo<AnyFunctionType>()->getParams()) {
// inout parameters are invariant.
if (param.isInOut()) {
if (::findProtocolSelfReferences(this, param.getPlainType(),
skipAssocTypes)) {
return SelfReferenceKind::Other();
}
}
inputKind |= ::findProtocolSelfReferences(this, param.getParameterType(),
skipAssocTypes);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/ClangImporter/ImportDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1654,7 +1654,7 @@ static std::pair<Type, ParamDecl *> decomposeSubscriptSetter(FuncDecl *setter) {
->castTo<AnyFunctionType>()
->getResult()
->castTo<AnyFunctionType>()
->getParams().front().getOldType();
->getParams().front().getParameterType();
ParamDecl *keyDecl = PL->get(1);

return {elementType, keyDecl};
Expand Down
2 changes: 1 addition & 1 deletion lib/IRGen/GenProto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2849,7 +2849,7 @@ void NecessaryBindings::addTypeMetadata(CanType type) {
}
if (auto fn = dyn_cast<FunctionType>(type)) {
for (const auto &elt : fn.getParams())
addTypeMetadata(elt.getOldType());
addTypeMetadata(elt.getPlainType());
addTypeMetadata(fn.getResult());
return;
}
Expand Down
6 changes: 4 additions & 2 deletions lib/SILGen/SILGenBridging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,10 @@ static void expandTupleTypes(CanType type, SmallVectorImpl<CanType> &results) {
static SmallVector<CanType, 8>
expandTupleTypes(AnyFunctionType::CanParamArrayRef params) {
SmallVector<CanType, 8> results;
for (auto param : params)
expandTupleTypes(param.getOldType(), results);
for (auto param : params) {
assert(!param.isInOut() && !param.isVariadic());
expandTupleTypes(param.getPlainType(), results);
}
return results;
}

Expand Down
4 changes: 3 additions & 1 deletion lib/SILGen/SILGenConstructor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ static SILValue emitConstructorMetatypeArg(SILGenFunction &SGF,
auto ctorFnType = ctor->getInterfaceType()->castTo<AnyFunctionType>();
assert(ctorFnType->getParams().size() == 1 &&
"more than one self parameter?");
Type metatype = ctorFnType->getParams()[0].getOldType();
auto param = ctorFnType->getParams()[0];
assert(!param.isVariadic() && !param.isInOut());
Type metatype = param.getPlainType();
auto *DC = ctor->getInnermostDeclContext();
auto &AC = SGF.getASTContext();
auto VD =
Expand Down
2 changes: 1 addition & 1 deletion lib/SILOptimizer/Utils/Generics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ static std::pair<unsigned, unsigned> getTypeDepthAndWidth(Type t) {
for (auto &Param : Params) {
unsigned TypeWidth;
unsigned TypeDepth;
std::tie(TypeDepth, TypeWidth) = getTypeDepthAndWidth(Param.getOldType());
std::tie(TypeDepth, TypeWidth) = getTypeDepthAndWidth(Param.getParameterType());
if (TypeDepth > MaxTypeDepth)
MaxTypeDepth = TypeDepth;
Width += TypeWidth;
Expand Down
8 changes: 4 additions & 4 deletions lib/Sema/ConstraintSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -874,8 +874,7 @@ std::pair<Type, Type>
ConstraintSystem::getTypeOfReference(ValueDecl *value,
FunctionRefKind functionRefKind,
ConstraintLocatorBuilder locator,
DeclContext *useDC,
const DeclRefExpr *base) {
DeclContext *useDC) {
if (value->getDeclContext()->isTypeContext() && isa<FuncDecl>(value)) {
// Unqualified lookup can find operator names within nominal types.
auto func = cast<FuncDecl>(value);
Expand Down Expand Up @@ -963,7 +962,8 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
// Determine the type of the value, opening up that type if necessary.
bool wantInterfaceType = !varDecl->getDeclContext()->isLocalContext();
Type valueType =
getUnopenedTypeOfReference(varDecl, Type(), useDC, base, wantInterfaceType);
getUnopenedTypeOfReference(varDecl, Type(), useDC, /*base=*/nullptr,
wantInterfaceType);

assert(!valueType->hasUnboundGenericType() &&
!valueType->hasTypeParameter());
Expand Down Expand Up @@ -1185,7 +1185,7 @@ ConstraintSystem::getTypeOfMemberReference(

// If the base is a module type, just use the type of the decl.
if (baseObjTy->is<ModuleType>()) {
return getTypeOfReference(value, functionRefKind, locator, useDC, base);
return getTypeOfReference(value, functionRefKind, locator, useDC);
}

FunctionType::Param baseObjParam(baseObjTy);
Expand Down
3 changes: 1 addition & 2 deletions lib/Sema/ConstraintSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -2279,8 +2279,7 @@ class ConstraintSystem {
ValueDecl *decl,
FunctionRefKind functionRefKind,
ConstraintLocatorBuilder locator,
DeclContext *useDC,
const DeclRefExpr *base = nullptr);
DeclContext *useDC);

/// Return the type-of-reference of the given value.
///
Expand Down
3 changes: 1 addition & 2 deletions lib/Sema/MiscDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4224,8 +4224,7 @@ Optional<Identifier> TypeChecker::omitNeedlessWords(VarDecl *var) {
return None;

// Dig out the type of the variable.
Type type = var->getInterfaceType()->getReferenceStorageReferent()
->getWithoutSpecifierType();
Type type = var->getValueInterfaceType();
while (auto optObjectTy = type->getOptionalObjectType())
type = optObjectTy;

Expand Down
4 changes: 2 additions & 2 deletions lib/Sema/TypeCheckAvailability.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2108,10 +2108,10 @@ bool isSubscriptReturningString(const ValueDecl *D, ASTContext &Context) {
return false;

const auto &param = params.front();
if (param.hasLabel() || param.isVariadic())
if (param.hasLabel() || param.isVariadic() || param.isInOut())
return false;

auto inputTy = param.getOldType()->getAs<BoundGenericStructType>();
auto inputTy = param.getPlainType()->getAs<BoundGenericStructType>();
if (!inputTy)
return false;

Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/TypeCheckCaptures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class FindCapturedVars : public ASTWalker {
});

for (const auto &param : gft->getParams())
param.getOldType().walk(walker);
param.getPlainType().walk(walker);

gft->getResult().walk(walker);
}
Expand Down
15 changes: 8 additions & 7 deletions lib/Sema/TypeCheckDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2063,6 +2063,9 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
explicit DeclChecker(TypeChecker &TC) : TC(TC) {}

void visit(Decl *decl) {
if (TC.Context.Stats)
TC.Context.Stats->getFrontendCounters().NumDeclsTypechecked++;

FrontendStatsTracer StatsTracer(TC.Context.Stats, "typecheck-decl", decl);
PrettyStackTraceDecl StackTrace("type-checking", decl);

Expand Down Expand Up @@ -3862,13 +3865,8 @@ void TypeChecker::validateDecl(ValueDecl *D) {
auto valueParams = accessor->getParameters();

// Determine the value type.
Type valueIfaceTy;
if (auto VD = dyn_cast<VarDecl>(storage)) {
valueIfaceTy = VD->getInterfaceType()->getReferenceStorageReferent();
} else {
auto SD = cast<SubscriptDecl>(storage);
valueIfaceTy = SD->getElementInterfaceType();

Type valueIfaceTy = storage->getValueInterfaceType();
if (auto SD = dyn_cast<SubscriptDecl>(storage)) {
// Copy the index types instead of re-validating them.
auto indices = SD->getIndices();
for (size_t i = 0, e = indices->size(); i != e; ++i) {
Expand Down Expand Up @@ -4413,6 +4411,9 @@ static void finalizeType(TypeChecker &TC, NominalTypeDecl *nominal) {
}

void TypeChecker::finalizeDecl(ValueDecl *decl) {
if (Context.Stats)
Context.Stats->getFrontendCounters().NumDeclsFinalized++;

validateDecl(decl);

if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
Expand Down
22 changes: 13 additions & 9 deletions lib/Sema/TypeCheckDeclObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -825,18 +825,22 @@ bool swift::isRepresentableInObjC(const SubscriptDecl *SD, ObjCReason Reason) {
if (SubscriptType->getParams().size() != 1)
return false;

Type IndicesType = SubscriptType->getParams()[0].getOldType();
if (IndicesType->hasError())
auto IndexParam = SubscriptType->getParams()[0];
if (IndexParam.isInOut())
return false;

bool IndicesResult =
IndicesType->isRepresentableIn(ForeignLanguage::ObjectiveC,
SD->getDeclContext());
Type IndexType = SubscriptType->getParams()[0].getParameterType();
if (IndexType->hasError())
return false;

bool IndexResult =
IndexType->isRepresentableIn(ForeignLanguage::ObjectiveC,
SD->getDeclContext());

Type ElementType = SD->getElementInterfaceType();
bool ElementResult = ElementType->isRepresentableIn(
ForeignLanguage::ObjectiveC, SD->getDeclContext());
bool Result = IndicesResult && ElementResult;
bool Result = IndexResult && ElementResult;

if (Result && checkObjCInExtensionContext(SD, Diagnose))
return false;
Expand All @@ -845,7 +849,7 @@ bool swift::isRepresentableInObjC(const SubscriptDecl *SD, ObjCReason Reason) {
return Result;

SourceRange TypeRange;
if (!IndicesResult)
if (!IndexResult)
TypeRange = SD->getIndices()->getSourceRange();
else
TypeRange = SD->getElementTypeLoc().getSourceRange();
Expand All @@ -854,8 +858,8 @@ bool swift::isRepresentableInObjC(const SubscriptDecl *SD, ObjCReason Reason) {
.highlight(TypeRange);

diagnoseTypeNotRepresentableInObjC(SD->getDeclContext(),
!IndicesResult ? IndicesType
: ElementType,
!IndexResult ? IndexType
: ElementType,
TypeRange);
describeObjCReason(SD, Reason);

Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/TypeCheckGeneric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ void TypeChecker::checkReferencedGenericParams(GenericContext *dc) {
ReferencedGenericTypeWalker paramsAndResultWalker;
auto *funcTy = decl->getInterfaceType()->castTo<GenericFunctionType>();
for (const auto &param : funcTy->getParams())
param.getOldType().walk(paramsAndResultWalker);
param.getPlainType().walk(paramsAndResultWalker);
funcTy->getResult().walk(paramsAndResultWalker);

// Set of generic params referenced in parameter types,
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/TypeCheckPattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1587,7 +1587,7 @@ bool TypeChecker::coerceParameterListToType(ParameterList *P, ClosureExpr *CE,
bool hadError = false;
for (const auto &param : FN->getParams()) {
params.push_back(param);
hadError |= param.getOldType()->hasError();
hadError |= param.getPlainType()->hasError();
}

// Local function to check if the given type is valid e.g. doesn't have
Expand Down
6 changes: 2 additions & 4 deletions lib/Sema/TypeCheckProtocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -885,14 +885,12 @@ swift::matchWitness(TypeChecker &tc,
= cs->getTypeOfMemberReference(selfTy, witness, dc,
/*isDynamicResult=*/false,
FunctionRefKind::DoubleApply,
witnessLocator,
/*base=*/nullptr);
witnessLocator);
} else {
std::tie(openedFullWitnessType, openWitnessType)
= cs->getTypeOfReference(witness,
FunctionRefKind::DoubleApply,
witnessLocator,
/*base=*/nullptr);
witnessLocator, /*useDC=*/nullptr);
}
openWitnessType = openWitnessType->getRValueType();

Expand Down
10 changes: 10 additions & 0 deletions test/IRGen/partial_apply_generic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,13 @@ let g = dietaryFad(Chicken())
do {
try g()
} catch {}

//
// Incorrect assertion regarding inout parameters in NecessaryBindings
//

func coyote<T, U>(_ t: T, _ u: U) {}

func hawk<A, B, C>(_: A, _ b: B, _ c: C) {
let fn: (Optional<(A) -> B>, @escaping (inout B, C) -> ()) -> () = coyote
}
20 changes: 20 additions & 0 deletions test/decl/func/dynamic_self.swift
Original file line number Diff line number Diff line change
Expand Up @@ -393,3 +393,23 @@ final class FinalFactory : FactoryPattern {
self.init(factory: FinalFactory(_string: string))
}
}

// Operators returning Self

class SelfOperator {
required init() {}

static func +(lhs: SelfOperator, rhs: SelfOperator) -> Self {
return self.init()
}

func double() -> Self {
// FIXME: Should this work?
return self + self // expected-error {{cannot convert return expression of type 'SelfOperator' to return type 'Self'}}
}
}

func useSelfOperator() {
let s = SelfOperator()
_ = s + s
}