Skip to content
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
18 changes: 7 additions & 11 deletions include/swift/SILOptimizer/Utils/Local.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,21 +137,17 @@ ProjectBoxInst *getOrCreateProjectBox(AllocBoxInst *ABI, unsigned Index);
/// if possible.
void replaceDeadApply(ApplySite Old, ValueBase *New);

/// \brief Return true if the substitution map contains a
/// substitution that is an unbound generic type.
bool hasUnboundGenericTypes(const TypeSubstitutionMap &SubsMap);
/// \brief Return true if the substitution map contains replacement types
/// that are dependent on the type parameters of the caller.
bool hasTypeParameterTypes(SubstitutionMap &SubsMap);

/// Return true if the substitution list contains a substitution
/// that is an unbound generic.
bool hasUnboundGenericTypes(ArrayRef<Substitution> Subs);
/// \brief Return true if the substitution list contains replacement types
/// that are dependent on the type parameters of the caller.
bool hasArchetypes(ArrayRef<Substitution> Subs);

/// \brief Return true if the substitution map contains a
/// substitution that refers to the dynamic Self type.
bool hasDynamicSelfTypes(const TypeSubstitutionMap &SubsMap);

/// \brief Return true if the substitution list contains a
/// substitution that refers to the dynamic Self type.
bool hasDynamicSelfTypes(ArrayRef<Substitution> Subs);
bool hasDynamicSelfTypes(const SubstitutionMap &SubsMap);

/// \brief Return true if any call inside the given function may bind dynamic
/// 'Self' to a generic argument of the callee.
Expand Down
18 changes: 8 additions & 10 deletions lib/AST/ASTVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1249,17 +1249,17 @@ struct ASTNodeBase {};
Out << "\n";
abort();
}
CanType InputExprTy = E->getArg()->getType()->getCanonicalType();
CanType ResultExprTy = E->getType()->getCanonicalType();
if (ResultExprTy != FT->getResult()->getCanonicalType()) {
Type InputExprTy = E->getArg()->getType();
Type ResultExprTy = E->getType();
if (!ResultExprTy->isEqual(FT->getResult())) {
Out << "result of ApplyExpr does not match result type of callee:";
E->getType().print(Out);
Out << " vs. ";
FT->getResult()->print(Out);
Out << "\n";
abort();
}
if (InputExprTy != FT->getInput()->getCanonicalType()) {
if (!InputExprTy->isEqual(FT->getInput())) {
TupleType *TT = FT->getInput()->getAs<TupleType>();
if (isa<SelfApplyExpr>(E)) {
Type InputExprObjectTy;
Expand All @@ -1274,8 +1274,7 @@ struct ASTNodeBase {};
checkSameOrSubType(InputExprObjectTy, FunctionInputObjectTy,
"object argument and 'self' parameter");
} else if (!TT || TT->getNumElements() != 1 ||
TT->getElement(0).getType()->getCanonicalType()
!= InputExprTy) {
!TT->getElement(0).getType()->isEqual(InputExprTy)) {
Out << "Argument type does not match parameter type in ApplyExpr:"
"\nArgument type: ";
E->getArg()->getType().print(Out);
Expand Down Expand Up @@ -1892,8 +1891,7 @@ struct ASTNodeBase {};
return;
}

if (type->getCanonicalType() !=
conformance.getConcrete()->getType()->getCanonicalType()) {
if (!type->isEqual(conformance.getConcrete()->getType())) {
Out << "conforming type does not match conformance\n";
Out << "conforming type:\n";
type.dump(Out, 2);
Expand Down Expand Up @@ -2518,7 +2516,7 @@ struct ASTNodeBase {};
}

void checkSameType(Type T0, Type T1, const char *what) {
if (T0->getCanonicalType() == T1->getCanonicalType())
if (T0->isEqual(T1))
return;

Out << "different types for " << what << ": ";
Expand Down Expand Up @@ -2568,7 +2566,7 @@ struct ASTNodeBase {};
}

void checkSameOrSubType(Type T0, Type T1, const char *what) {
if (T0->getCanonicalType() == T1->getCanonicalType())
if (T0->isEqual(T1))
return;

// Protocol subtyping.
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/Availability.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ class AvailabilityInferenceTypeWalker : public TypeWalker {
AvailabilityInferenceTypeWalker(ASTContext &AC) : AC(AC) {}

Action walkToTypePre(Type ty) override {
if (auto *nominalDecl = ty->getCanonicalType()->getAnyNominal()) {
if (auto *nominalDecl = ty->getAnyNominal()) {
AvailabilityInfo.intersectWith(
AvailabilityInference::availableRange(nominalDecl, AC));
}
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/DiagnosticEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ static void formatDiagnosticArgument(StringRef Modifier,
showAKA = false;

// Don't show generic type parameters.
if (showAKA && type->getCanonicalType()->hasTypeParameter())
if (showAKA && type->hasTypeParameter())
showAKA = false;

if (showAKA)
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/GenericSignature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ Type GenericSignature::getRepresentative(Type type, ModuleDecl &mod) {
if (rep->isConcreteType()) return rep->getConcreteType();
if (pa == rep) {
assert(rep->getDependentType(getGenericParams(), /*allowUnresolved*/ false)
->getCanonicalType() == type->getCanonicalType());
->isEqual(type));
return type;
}
return rep->getDependentType(getGenericParams(), /*allowUnresolved*/ false);
Expand Down
3 changes: 1 addition & 2 deletions lib/AST/ProtocolConformance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,7 @@ SpecializedProtocolConformance::getTypeWitnessSubstAndDecl(
assert((conforms ||
specializedType->isTypeVariableOrMember() ||
specializedType->isTypeParameter() ||
specializedType->hasError() ||
specializedType->getCanonicalType()->hasError()) &&
specializedType->hasError()) &&
"Improperly checked substitution");
conformances.push_back(conforms ? *conforms
: ProtocolConformanceRef(proto));
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/Substitution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ bool Substitution::operator==(const Substitution &other) const {
// The archetypes may be missing, but we can compare them directly
// because archetypes are always canonical.
return
Replacement->getCanonicalType() == other.Replacement->getCanonicalType() &&
Replacement->isEqual(other.Replacement) &&
Conformance.equals(other.Conformance);
}

Expand Down
9 changes: 4 additions & 5 deletions lib/IDE/CodeCompletion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3708,18 +3708,17 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
// We can only say .foo where foo is a static member of the contextual
// type and has the same type (or if the member is a function, then the
// same result type) as the contextual type.
auto contextCanT = T->getCanonicalType();
FilteredDeclConsumer consumer(*this, [=](ValueDecl *VD, DeclVisibilityKind reason) {
if (!VD->hasInterfaceType()) {
TypeResolver->resolveDeclSignature(VD);
if (!VD->hasInterfaceType())
return false;
}

auto T = VD->getInterfaceType();
while (auto FT = T->getAs<AnyFunctionType>())
T = FT->getResult();
return T->getCanonicalType() == contextCanT;
auto declTy = VD->getInterfaceType();
while (auto FT = declTy->getAs<AnyFunctionType>())
declTy = FT->getResult();
return declTy->isEqual(T);
});

auto baseType = MetatypeType::get(T);
Expand Down
26 changes: 12 additions & 14 deletions lib/IDE/TypeReconstruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -945,10 +945,10 @@ static void VisitNodeConstructor(

const AnyFunctionType *type_func =
type_result._types.front()->getAs<AnyFunctionType>();
if (identifier_func->getResult()->getCanonicalType() ==
type_func->getResult()->getCanonicalType() &&
identifier_func->getInput()->getCanonicalType() ==
type_func->getInput()->getCanonicalType()) {
if (identifier_func->getResult()->isEqual(
type_func->getResult()) &&
identifier_func->getInput()->isEqual(
type_func->getInput())) {
result._module = kind_type_result._module;
result._decls.push_back(kind_type_result._decls[i]);
result._types.push_back(
Expand Down Expand Up @@ -1481,8 +1481,8 @@ static void VisitNodeSetterGetter(
const AnyFunctionType *type_func =
type_result._types.front()->getAs<AnyFunctionType>();

CanType type_result_type = type_func->getResult()->getCanonicalType();
CanType type_input_type = type_func->getInput()->getCanonicalType();
Type type_result_type = type_func->getResult();
Type type_input_type = type_func->getInput();

FuncDecl *identifier_func = nullptr;

Expand Down Expand Up @@ -1520,14 +1520,12 @@ static void VisitNodeSetterGetter(
const AnyFunctionType *identifier_uncurried_result =
identifier_func_type->getResult()->getAs<AnyFunctionType>();
if (identifier_uncurried_result) {
CanType identifier_result_type =
identifier_uncurried_result->getResult()
->getCanonicalType();
CanType identifier_input_type =
identifier_uncurried_result->getInput()
->getCanonicalType();
if (identifier_result_type == type_result_type &&
identifier_input_type == type_input_type) {
Type identifier_result_type =
identifier_uncurried_result->getResult();
Type identifier_input_type =
identifier_uncurried_result->getInput();
if (identifier_result_type->isEqual(type_result_type) &&
identifier_input_type->isEqual(type_input_type)) {
break;
}
}
Expand Down
11 changes: 3 additions & 8 deletions lib/SILOptimizer/IPO/UsePrespecialized.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,9 @@ bool UsePrespecialized::replaceByPrespecialized(SILFunction &F) {
if (!SpecType)
continue;

// Bail if any generic types parameters of the concrete type
// are unbound.
if (SpecType->hasArchetype())
continue;

// Bail if any generic types parameters of the concrete type
// are unbound.
if (hasUnboundGenericTypes(Subs))
// Bail any callee generic type parameters are dependent on the generic
// parameters of the caller.
if (SpecType->hasArchetype() || hasArchetypes(Subs))
continue;

// Create a name of the specialization.
Expand Down
2 changes: 1 addition & 1 deletion lib/SILOptimizer/Transforms/PerformanceInliner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ static Optional<bool> shouldInlineGeneric(FullApplySite AI) {
// If all substitutions are concrete, then there is no need to perform the
// generic inlining. Let the generic specializer create a specialized
// function and then decide if it is beneficial to inline it.
if (!hasUnboundGenericTypes(AI.getSubstitutions()))
if (!hasArchetypes(AI.getSubstitutions()))
return false;

SILFunction *Callee = AI.getReferencedFunction();
Expand Down
4 changes: 2 additions & 2 deletions lib/SILOptimizer/Utils/Generics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ ReabstractionInfo::ReabstractionInfo(SILFunction *OrigF,
->getSubstitutionMap(ParamSubs);

// We do not support partial specialization.
if (hasUnboundGenericTypes(InterfaceSubs.getMap())) {
if (hasTypeParameterTypes(InterfaceSubs)) {
DEBUG(llvm::dbgs() <<
" Cannot specialize with unbound interface substitutions.\n");
DEBUG(for (auto Sub : ParamSubs) {
Sub.dump();
});
return;
}
if (hasDynamicSelfTypes(InterfaceSubs.getMap())) {
if (hasDynamicSelfTypes(InterfaceSubs)) {
DEBUG(llvm::dbgs() << " Cannot specialize with dynamic self.\n");
return;
}
Expand Down
25 changes: 8 additions & 17 deletions lib/SILOptimizer/Utils/Local.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,36 +322,27 @@ void swift::replaceDeadApply(ApplySite Old, ValueBase *New) {
recursivelyDeleteTriviallyDeadInstructions(OldApply, true);
}

bool swift::hasUnboundGenericTypes(const TypeSubstitutionMap &SubsMap) {
bool swift::hasTypeParameterTypes(SubstitutionMap &SubsMap) {
// Check whether any of the substitutions are dependent.
for (auto &entry : SubsMap)
if (entry.second->getCanonicalType()->hasArchetype())
for (auto &entry : SubsMap.getMap())
if (entry.second->hasArchetype())
return true;

return false;
}

bool swift::hasUnboundGenericTypes(ArrayRef<Substitution> Subs) {
bool swift::hasArchetypes(ArrayRef<Substitution> Subs) {
// Check whether any of the substitutions are dependent.
for (auto &sub : Subs)
if (sub.getReplacement()->getCanonicalType()->hasArchetype())
if (sub.getReplacement()->hasArchetype())
return true;
return false;
}

bool swift::hasDynamicSelfTypes(const TypeSubstitutionMap &SubsMap) {
bool swift::hasDynamicSelfTypes(const SubstitutionMap &SubsMap) {
// Check whether any of the substitutions are refer to dynamic self.
for (auto &entry : SubsMap)
if (entry.second->getCanonicalType()->hasDynamicSelfType())
return true;

return false;
}

bool swift::hasDynamicSelfTypes(ArrayRef<Substitution> Subs) {
// Check whether any of the substitutions are refer to dynamic self.
for (auto &sub : Subs)
if (sub.getReplacement()->getCanonicalType()->hasDynamicSelfType())
for (auto &entry : SubsMap.getMap())
if (entry.second->hasDynamicSelfType())
return true;

return false;
Expand Down
21 changes: 9 additions & 12 deletions lib/Sema/CSApply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,8 @@ static bool shouldAccessStorageDirectly(Expr *base, VarDecl *member,
#endif

// Ctor or dtor are for immediate class, not a derived class.
if (AFD->getParent()->getDeclaredTypeOfContext()->getCanonicalType() !=
member->getDeclContext()->getDeclaredTypeOfContext()->getCanonicalType())
if (!AFD->getParent()->getDeclaredInterfaceType()->isEqual(
member->getDeclContext()->getDeclaredInterfaceType()))
return false;

return true;
Expand Down Expand Up @@ -247,8 +247,8 @@ getImplicitMemberReferenceAccessSemantics(Expr *base, VarDecl *member,
isa<ConstructorDecl>(AFD_DC) &&

// Ctor is for immediate class, not a derived class.
AFD_DC->getParent()->getDeclaredTypeOfContext()->getCanonicalType() ==
member->getDeclContext()->getDeclaredTypeOfContext()->getCanonicalType() &&
AFD_DC->getParent()->getDeclaredInterfaceType()->isEqual(
member->getDeclContext()->getDeclaredInterfaceType()) &&

// Is a "self.property" reference.
isa<DeclRefExpr>(base) &&
Expand Down Expand Up @@ -4704,21 +4704,18 @@ static unsigned getOptionalBindDepth(const BoundGenericType *bgt) {

unsigned innerDepth = 0;

if (auto wrappedBGT = dyn_cast<BoundGenericType>(tyarg->
getCanonicalType())) {
if (auto wrappedBGT = tyarg->getAs<BoundGenericType>())
innerDepth = getOptionalBindDepth(wrappedBGT);
}


return 1 + innerDepth;
}

return 0;
}

static Type getOptionalBaseType(const Type &type) {
static Type getOptionalBaseType(Type type) {

if (auto bgt = dyn_cast<BoundGenericType>(type->
getCanonicalType())) {
if (auto bgt = type->getAs<BoundGenericType>()) {
if (bgt->getDecl()->classifyAsOptionalType()) {
return getOptionalBaseType(bgt->getGenericArgs()[0]);
}
Expand Down Expand Up @@ -6102,7 +6099,7 @@ Expr *ExprRewriter::convertLiteral(Expr *literal,
return nullptr;

// If the argument type is in error, we're done.
if (argType->hasError() || argType->getCanonicalType()->hasError())
if (argType->hasError())
return nullptr;

// Convert the literal to the non-builtin argument type via the
Expand Down
13 changes: 5 additions & 8 deletions lib/Sema/CSDiag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2547,8 +2547,8 @@ diagnoseTypeMemberOnInstanceLookup(Type baseObjTy,
// If we are in a protocol extension of 'Proto' and we see
// 'Proto.static', suggest 'Self.static'
if (auto extensionContext = parent->getAsProtocolExtensionContext()) {
if (extensionContext->getDeclaredType()->getCanonicalType()
== metatypeTy->getInstanceType()->getCanonicalType()) {
if (extensionContext->getDeclaredType()->isEqual(
metatypeTy->getInstanceType())) {
Diag->fixItReplace(baseRange, "Self");
}
}
Expand Down Expand Up @@ -3562,8 +3562,7 @@ typeCheckArbitrarySubExprIndependently(Expr *subExpr, TCCOptions options) {
// in. Reset them to UnresolvedTypes for safe measures.
for (auto param : *CE->getParameters()) {
auto VD = param;
if (VD->getType()->hasTypeVariable() || VD->getType()->hasError() ||
VD->getType()->getCanonicalType()->hasError()) {
if (VD->getType()->hasTypeVariable() || VD->getType()->hasError()) {
VD->setType(CS->getASTContext().TheUnresolvedType);
VD->setInterfaceType(VD->getType());
}
Expand Down Expand Up @@ -4962,8 +4961,7 @@ static bool diagnoseSingleCandidateFailures(CalleeCandidateInfo &CCI,
CallArgParam &arg = args[0];
auto resTy = candidate.getResultType()->lookThroughAllAnyOptionalTypes();
auto rawTy = isRawRepresentable(resTy, CCI.CS);
if (rawTy && arg.Ty &&
resTy->getCanonicalType() == arg.Ty->getCanonicalType()) {
if (rawTy && arg.Ty && resTy->isEqual(arg.Ty)) {
auto getInnerExpr = [](Expr *E) -> Expr* {
ParenExpr *parenE = dyn_cast<ParenExpr>(E);
if (!parenE)
Expand Down Expand Up @@ -6408,8 +6406,7 @@ bool FailureDiagnosis::visitClosureExpr(ClosureExpr *CE) {
//
// Handle this by rewriting the arguments to UnresolvedType().
for (auto VD : *CE->getParameters()) {
if (VD->getType()->hasTypeVariable() || VD->getType()->hasError() ||
VD->getType()->getCanonicalType()->hasError()) {
if (VD->getType()->hasTypeVariable() || VD->getType()->hasError()) {
VD->setType(CS->getASTContext().TheUnresolvedType);
VD->setInterfaceType(VD->getType());
}
Expand Down
Loading