Sema: Use AbstractFunctionDecl::computeType()

This commit is contained in:
Slava Pestov
2018-07-21 05:29:39 -07:00
parent 106878005e
commit 1b7fbb45e6
5 changed files with 27 additions and 180 deletions

View File

@@ -704,20 +704,9 @@ static FuncDecl *deriveEncodable_encode(DerivedConformance &derived) {
// output: ()
// Create from the inside out:
// (to: Encoder)
auto encoderType = C.getEncoderDecl()->getDeclaredInterfaceType();
auto inputTypeElt = TupleTypeElt(encoderType, C.Id_to);
auto inputType = TupleType::get(ArrayRef<TupleTypeElt>(inputTypeElt), C);
// throws
auto extInfo = FunctionType::ExtInfo(FunctionTypeRepresentation::Swift,
/*Throws=*/true);
// ()
auto returnType = TupleType::getEmpty(C);
// (to: Encoder) throws -> ()
auto innerType = FunctionType::get(inputType, returnType, extInfo);
// Params: (self [implicit], Encoder)
auto *selfDecl = ParamDecl::createSelf(SourceLoc(), conformanceDC);
auto *encoderParam = new (C)
@@ -745,21 +734,10 @@ static FuncDecl *deriveEncodable_encode(DerivedConformance &derived) {
encodeDecl->getAttrs().add(attr);
}
// Evaluate the type of Self in (Self) -> (Encoder) throws -> ().
Type selfType = conformanceDC->getDeclaredInterfaceType();
Type interfaceType;
if (auto sig = conformanceDC->getGenericSignatureOfContext()) {
// Evaluate the below, but in a generic environment (if Self is generic).
encodeDecl->setGenericEnvironment(
conformanceDC->getGenericEnvironmentOfContext());
interfaceType = GenericFunctionType::get(sig, selfType, innerType,
FunctionType::ExtInfo());
} else {
// (Self) -> innerType == (Encoder) throws -> ()
interfaceType = FunctionType::get(selfType, innerType);
}
if (auto env = conformanceDC->getGenericEnvironmentOfContext())
encodeDecl->setGenericEnvironment(env);
encodeDecl->computeType(FunctionType::ExtInfo().withThrows());
encodeDecl->setInterfaceType(interfaceType);
encodeDecl->setValidationToChecked();
encodeDecl->copyFormalAccessFrom(derived.Nominal,
/*sourceIsParentContext*/ true);
@@ -1030,26 +1008,13 @@ static ValueDecl *deriveDecodable_init(DerivedConformance &derived) {
// output: Self
// Compute from the inside out:
// (from: Decoder)
auto decoderType = C.getDecoderDecl()->getDeclaredInterfaceType();
auto inputTypeElt = TupleTypeElt(decoderType, C.Id_from);
auto inputType = TupleType::get(ArrayRef<TupleTypeElt>(inputTypeElt), C);
// throws
auto extInfo = FunctionType::ExtInfo(FunctionTypeRepresentation::Swift,
/*Throws=*/true);
// (Self)
auto returnType = derived.Nominal->getDeclaredInterfaceType();
// (from: Decoder) throws -> (Self)
Type innerType = FunctionType::get(inputType, returnType, extInfo);
// Params: (self [implicit], Decoder)
// self should be inout if the type is a value type; not inout otherwise.
auto *selfDecl = ParamDecl::createSelf(SourceLoc(), conformanceDC,
/*isStatic=*/false,
/*isInOut=*/!classDecl);
auto decoderType = C.getDecoderDecl()->getDeclaredInterfaceType();
auto *decoderParamDecl = new (C) ParamDecl(
VarDecl::Specifier::Default, SourceLoc(), SourceLoc(), C.Id_from,
SourceLoc(), C.Id_decoder, decoderType, conformanceDC);
@@ -1075,29 +1040,11 @@ static ValueDecl *deriveDecodable_init(DerivedConformance &derived) {
initDecl->getAttrs().add(reqAttr);
}
auto selfParam = computeSelfParam(initDecl);
auto initSelfParam = computeSelfParam(initDecl, /*init=*/true);
Type interfaceType;
Type initializerType;
if (auto sig = conformanceDC->getGenericSignatureOfContext()) {
// Evaluate the below, but in a generic environment (if Self is generic).
initDecl->setGenericEnvironment(
conformanceDC->getGenericEnvironmentOfContext());
interfaceType = GenericFunctionType::get(sig, {selfParam}, innerType,
FunctionType::ExtInfo());
initializerType = GenericFunctionType::get(sig, {initSelfParam}, innerType,
FunctionType::ExtInfo());
} else {
// (Self) -> (Decoder) throws -> (Self)
interfaceType = FunctionType::get({selfParam}, innerType,
FunctionType::ExtInfo());
initializerType = FunctionType::get({initSelfParam}, innerType,
FunctionType::ExtInfo());
}
if (auto env = conformanceDC->getGenericEnvironmentOfContext())
initDecl->setGenericEnvironment(env);
initDecl->computeType(AnyFunctionType::ExtInfo().withThrows());
initDecl->setInterfaceType(interfaceType);
initDecl->setValidationToChecked();
initDecl->setInitializerInterfaceType(initializerType);
initDecl->copyFormalAccessFrom(derived.Nominal,
/*sourceIsParentContext*/ true);

View File

@@ -141,37 +141,11 @@ static ValueDecl *deriveInitDecl(DerivedConformance &derived, Type paramType,
// Synthesize the body.
synthesizer(initDecl);
// Compute the type of the initializer.
TupleTypeElt element(paramType, paramName);
TupleTypeElt interfaceElement(paramType, paramName);
auto interfaceArgType = TupleType::get(interfaceElement, C);
// Compute the interface type of the initializer.
Type retInterfaceType =
OptionalType::get(parentDC->getDeclaredInterfaceType());
Type interfaceType = FunctionType::get(interfaceArgType, retInterfaceType);
auto selfParam = computeSelfParam(initDecl);
auto initSelfParam = computeSelfParam(initDecl, /*init*/ true);
if (auto env = parentDC->getGenericEnvironmentOfContext())
initDecl->setGenericEnvironment(env);
initDecl->computeType();
Type allocIfaceType;
Type initIfaceType;
if (auto sig = parentDC->getGenericSignatureOfContext()) {
initDecl->setGenericEnvironment(parentDC->getGenericEnvironmentOfContext());
allocIfaceType = GenericFunctionType::get(sig, {selfParam},
interfaceType,
FunctionType::ExtInfo());
initIfaceType = GenericFunctionType::get(sig, {initSelfParam},
interfaceType,
FunctionType::ExtInfo());
} else {
allocIfaceType = FunctionType::get({selfParam},
interfaceType, FunctionType::ExtInfo());
initIfaceType = FunctionType::get({initSelfParam},
interfaceType, FunctionType::ExtInfo());
}
initDecl->setInterfaceType(allocIfaceType);
initDecl->setInitializerInterfaceType(initIfaceType);
initDecl->setAccess(derived.Nominal->getFormalAccess());
initDecl->setValidationToChecked();

View File

@@ -647,25 +647,11 @@ deriveEquatable_eq(DerivedConformance &derived, Identifier generatedIdentifier,
eqDecl->setBodySynthesizer(bodySynthesizer);
// Compute the type.
Type paramsTy = params->getInterfaceType(C);
// Compute the interface type.
Type interfaceTy;
auto selfParam = computeSelfParam(eqDecl);
if (auto genericSig = parentDC->getGenericSignatureOfContext()) {
eqDecl->setGenericEnvironment(parentDC->getGenericEnvironmentOfContext());
if (auto genericEnv = parentDC->getGenericEnvironmentOfContext())
eqDecl->setGenericEnvironment(genericEnv);
eqDecl->computeType();
interfaceTy = FunctionType::get(paramsTy, boolTy,
AnyFunctionType::ExtInfo());
interfaceTy = GenericFunctionType::get(genericSig, {selfParam}, interfaceTy,
AnyFunctionType::ExtInfo());
} else {
interfaceTy = FunctionType::get(paramsTy, boolTy);
interfaceTy = FunctionType::get({selfParam}, interfaceTy,
FunctionType::ExtInfo());
}
eqDecl->setInterfaceType(interfaceTy);
eqDecl->copyFormalAccessFrom(derived.Nominal, /*sourceIsParentContext*/ true);
eqDecl->setValidationToChecked();
@@ -781,24 +767,9 @@ deriveHashable_hashInto(DerivedConformance &derived,
hashDecl->setImplicit();
hashDecl->setBodySynthesizer(bodySynthesizer);
// Evaluate type of Self in (Self) -> (into: inout Hasher) -> ()
auto selfParam = computeSelfParam(hashDecl);
auto inoutFlag = ParameterTypeFlags().withInOut(true);
auto hasherParam = AnyFunctionType::Param(hasherType, C.Id_into, inoutFlag);
auto innerType = FunctionType::get({hasherParam}, returnType,
FunctionType::ExtInfo());
Type interfaceType;
if (auto sig = parentDC->getGenericSignatureOfContext()) {
hashDecl->setGenericEnvironment(parentDC->getGenericEnvironmentOfContext());
interfaceType = GenericFunctionType::get(sig, {selfParam}, innerType,
FunctionType::ExtInfo());
} else {
// (Self) -> innerType == (inout Hasher) -> ()
interfaceType = FunctionType::get({selfParam}, innerType,
FunctionType::ExtInfo());
}
hashDecl->setInterfaceType(interfaceType);
if (auto env = parentDC->getGenericEnvironmentOfContext())
hashDecl->setGenericEnvironment(env);
hashDecl->computeType();
hashDecl->copyFormalAccessFrom(derived.Nominal);
hashDecl->setValidationToChecked();
@@ -1104,21 +1075,11 @@ static ValueDecl *deriveHashable_hashValue(DerivedConformance &derived) {
getterDecl->setImplicit();
getterDecl->setBodySynthesizer(&deriveBodyHashable_hashValue);
// Compute the type of hashValue().
Type methodType = FunctionType::get(TupleType::getEmpty(C), intType);
// Compute the interface type of hashValue().
Type interfaceType;
auto selfParam = computeSelfParam(getterDecl);
if (auto sig = parentDC->getGenericSignatureOfContext()) {
getterDecl->setGenericEnvironment(parentDC->getGenericEnvironmentOfContext());
interfaceType = GenericFunctionType::get(sig, {selfParam}, methodType,
AnyFunctionType::ExtInfo());
} else
interfaceType = FunctionType::get({selfParam}, methodType,
AnyFunctionType::ExtInfo());
if (auto env = parentDC->getGenericEnvironmentOfContext())
getterDecl->setGenericEnvironment(env);
getterDecl->computeType();
getterDecl->setInterfaceType(interfaceType);
getterDecl->setValidationToChecked();
getterDecl->copyFormalAccessFrom(derived.Nominal,
/*sourceIsParentContext*/ true);

View File

@@ -341,37 +341,11 @@ deriveRawRepresentable_init(DerivedConformance &derived) {
initDecl->setImplicit();
initDecl->setBodySynthesizer(&deriveBodyRawRepresentable_init);
// Compute the type of the initializer.
TupleTypeElt element(rawType, C.Id_rawValue);
TupleTypeElt interfaceElement(rawInterfaceType, C.Id_rawValue);
auto interfaceArgType = TupleType::get(interfaceElement, C);
// Compute the interface type of the initializer.
Type retInterfaceType
= OptionalType::get(parentDC->getDeclaredInterfaceType());
Type interfaceType = FunctionType::get(interfaceArgType, retInterfaceType);
auto selfParam = computeSelfParam(initDecl);
auto initSelfParam = computeSelfParam(initDecl, /*init*/ true);
if (auto env = parentDC->getGenericEnvironmentOfContext())
initDecl->setGenericEnvironment(env);
initDecl->computeType();
Type allocIfaceType;
Type initIfaceType;
if (auto sig = parentDC->getGenericSignatureOfContext()) {
initDecl->setGenericEnvironment(parentDC->getGenericEnvironmentOfContext());
allocIfaceType = GenericFunctionType::get(sig, {selfParam},
interfaceType,
FunctionType::ExtInfo());
initIfaceType = GenericFunctionType::get(sig, {initSelfParam},
interfaceType,
FunctionType::ExtInfo());
} else {
allocIfaceType = FunctionType::get({selfParam},
interfaceType, FunctionType::ExtInfo());
initIfaceType = FunctionType::get({initSelfParam},
interfaceType, FunctionType::ExtInfo());
}
initDecl->setInterfaceType(allocIfaceType);
initDecl->setInitializerInterfaceType(initIfaceType);
initDecl->copyFormalAccessFrom(enumDecl, /*sourceIsParentContext*/true);
initDecl->setValidationToChecked();

View File

@@ -309,19 +309,10 @@ DerivedConformance::declareDerivedPropertyGetter(TypeChecker &tc,
getterDecl->getAttrs().add(new (C) FinalAttr(/*IsImplicit=*/true));
// Compute the interface type of the getter.
Type interfaceType = FunctionType::get(TupleType::getEmpty(C),
propertyInterfaceType);
auto selfParam = computeSelfParam(getterDecl);
if (auto sig = parentDC->getGenericSignatureOfContext()) {
getterDecl->setGenericEnvironment(
parentDC->getGenericEnvironmentOfContext());
interfaceType = GenericFunctionType::get(sig, {selfParam},
interfaceType,
FunctionType::ExtInfo());
} else
interfaceType = FunctionType::get({selfParam}, interfaceType,
FunctionType::ExtInfo());
getterDecl->setInterfaceType(interfaceType);
if (auto env = parentDC->getGenericEnvironmentOfContext())
getterDecl->setGenericEnvironment(env);
getterDecl->computeType();
getterDecl->copyFormalAccessFrom(property);
getterDecl->setValidationToChecked();