diff --git a/include/swift/AST/InFlightSubstitution.h b/include/swift/AST/InFlightSubstitution.h index bbfc9e00dae2b..6e497b2c51afc 100644 --- a/include/swift/AST/InFlightSubstitution.h +++ b/include/swift/AST/InFlightSubstitution.h @@ -23,21 +23,36 @@ #define SWIFT_AST_INFLIGHTSUBSTITUTION_H #include "swift/AST/SubstitutionMap.h" +#include "llvm/ADT/DenseMap.h" namespace swift { class SubstitutionMap; class InFlightSubstitution { - SubstOptions Options; + friend class SubstitutionMap; + TypeSubstitutionFn BaselineSubstType; LookupConformanceFn BaselineLookupConformance; + SubstOptions Options; RecursiveTypeProperties Props; + unsigned RemainingCount : 15; + unsigned InitLimit : 1; + unsigned RemainingDepth : 15; + unsigned LimitReached : 1; struct ActivePackExpansion { bool isSubstExpansion = false; unsigned expansionIndex = 0; }; - SmallVector ActivePackExpansions; + llvm::SmallVector ActivePackExpansions; + llvm::SmallDenseMap SubMaps; + + Type projectLaneFromPackType( + Type substType, unsigned level); + ProtocolConformanceRef projectLaneFromPackConformance( + PackConformance *substPackConf, unsigned level); + + bool checkLimits(Type ty); public: InFlightSubstitution(TypeSubstitutionFn substType, @@ -145,6 +160,10 @@ class InFlightSubstitution { /// Is the given type invariant to substitution? bool isInvariant(Type type) const; + + bool wasLimitReached() const { + return LimitReached; + } }; /// A helper classes that provides stable storage for the query diff --git a/include/swift/AST/SubstitutionMap.h b/include/swift/AST/SubstitutionMap.h index 1c1309789cafd..868d59ef265b7 100644 --- a/include/swift/AST/SubstitutionMap.h +++ b/include/swift/AST/SubstitutionMap.h @@ -217,7 +217,7 @@ class SubstitutionMap { /// Whether to dump the full substitution map, or just a minimal useful subset /// (on a single line). - enum class DumpStyle { Minimal, Full }; + enum class DumpStyle { Minimal, NoConformances, Full }; /// Dump the contents of this substitution map for debugging purposes. void dump(llvm::raw_ostream &out, DumpStyle style = DumpStyle::Full, unsigned indent = 0) const; diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index 2c5128b961961..db2a1e57bf06b 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -7077,24 +7077,16 @@ enum class OpaqueSubstitutionKind { /// archetypes with underlying types visible at a given resilience expansion /// to their underlying types. class ReplaceOpaqueTypesWithUnderlyingTypes { -public: - using SeenDecl = std::pair; private: ResilienceExpansion contextExpansion; llvm::PointerIntPair inContextAndIsWholeModule; - llvm::DenseSet *seenDecls; public: ReplaceOpaqueTypesWithUnderlyingTypes(const DeclContext *inContext, ResilienceExpansion contextExpansion, bool isWholeModuleContext) : contextExpansion(contextExpansion), - inContextAndIsWholeModule(inContext, isWholeModuleContext), - seenDecls(nullptr) {} - - ReplaceOpaqueTypesWithUnderlyingTypes( - const DeclContext *inContext, ResilienceExpansion contextExpansion, - bool isWholeModuleContext, llvm::DenseSet &seen); + inContextAndIsWholeModule(inContext, isWholeModuleContext) {} /// TypeSubstitutionFn Type operator()(SubstitutableType *maybeOpaqueType) const; diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index a0efc780144f1..dc08b29c6da04 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -612,6 +612,14 @@ namespace swift { /// rewrite system. bool EnableRequirementMachineOpaqueArchetypes = false; + /// Maximum nesting depth for type substitution operations, to prevent + /// runaway recursion. + unsigned MaxSubstitutionDepth = 50; + + /// Maximum step count for type substitution operations, to prevent + /// runaway recursion. + unsigned MaxSubstitutionCount = 2000; + /// Enable implicit lifetime dependence for ~Escapable return types. bool EnableExperimentalLifetimeDependenceInference = false; diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td index 1ca56c6cff83e..1b1b9c90029cf 100644 --- a/include/swift/Option/FrontendOptions.td +++ b/include/swift/Option/FrontendOptions.td @@ -474,6 +474,14 @@ def disable_requirement_machine_reuse : Flag<["-"], "disable-requirement-machine def enable_requirement_machine_opaque_archetypes : Flag<["-"], "enable-requirement-machine-opaque-archetypes">, HelpText<"Enable more correct opaque archetype support, which is off by default because it might fail to produce a convergent rewrite system">; +def max_substitution_depth : Joined<["-"], "max-substitution-depth=">, + Flags<[FrontendOption, HelpHidden, DoesNotAffectIncrementalBuild]>, + HelpText<"Set the maximum nesting depth for type substitution operations">; + +def max_substitution_count : Joined<["-"], "max-substitution-count=">, + Flags<[FrontendOption, HelpHidden, DoesNotAffectIncrementalBuild]>, + HelpText<"Set the maximum step count for type substitution operations">; + def dump_type_witness_systems : Flag<["-"], "dump-type-witness-systems">, HelpText<"Enables dumping type witness systems from associated type inference">; diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index c2a1c28b6f0a8..4a24df8718003 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -1255,13 +1255,19 @@ namespace { /// Print a substitution map as a child node. void printRec(SubstitutionMap map, Label label) { + printRec(map, SubstitutionMap::DumpStyle::Full, label); + } + + /// Print a substitution map as a child node. + void printRec(SubstitutionMap map, SubstitutionMap::DumpStyle style, + Label label) { SmallPtrSet Dumped; - printRec(map, Dumped, label); + printRec(map, style, Dumped, label); } /// Print a substitution map as a child node. - void printRec(SubstitutionMap map, VisitedConformances &visited, - Label label); + void printRec(SubstitutionMap map, SubstitutionMap::DumpStyle style, + VisitedConformances &visited, Label label); /// Print a substitution map as a child node. void printRec(const ProtocolConformanceRef &conf, @@ -5807,7 +5813,8 @@ class PrintConformance : public PrintBase { if (!shouldPrintDetails) break; - printRec(conf->getSubstitutionMap(), visited, + printRec(conf->getSubstitutionMap(), + SubstitutionMap::DumpStyle::Full, visited, Label::optional("substitutions")); if (auto condReqs = conf->getConditionalRequirementsIfAvailableOrCached(/*computeIfPossible=*/false)) { printList(*condReqs, [&](auto subReq, Label label) { @@ -5906,7 +5913,7 @@ class PrintConformance : public PrintBase { // A minimal dump doesn't need the details about the conformances, a lot of // that info can be inferred from the signature. - if (style == SubstitutionMap::DumpStyle::Minimal) + if (style != SubstitutionMap::DumpStyle::Full) return; auto conformances = map.getConformances(); @@ -5925,13 +5932,12 @@ class PrintConformance : public PrintBase { } }; -void PrintBase::printRec(SubstitutionMap map, VisitedConformances &visited, - Label label) { +void PrintBase::printRec(SubstitutionMap map, SubstitutionMap::DumpStyle style, + VisitedConformances &visited, Label label) { printRecArbitrary( [&](Label label) { PrintConformance(Writer, MemberLoading) - .visitSubstitutionMap(map, SubstitutionMap::DumpStyle::Full, - visited, label); + .visitSubstitutionMap(map, style, visited, label); }, label); } @@ -6354,7 +6360,9 @@ namespace { printArchetypeCommonRec(T); if (!T->getSubstitutions().empty()) { - printRec(T->getSubstitutions(), Label::optional("substitutions")); + printRec(T->getSubstitutions(), + SubstitutionMap::DumpStyle::NoConformances, + Label::optional("substitutions")); } printFoot(); diff --git a/lib/AST/SubstitutionMap.cpp b/lib/AST/SubstitutionMap.cpp index e4577daf28423..e592310f75606 100644 --- a/lib/AST/SubstitutionMap.cpp +++ b/lib/AST/SubstitutionMap.cpp @@ -325,6 +325,13 @@ SubstitutionMap SubstitutionMap::subst(TypeSubstitutionFn subs, SubstitutionMap SubstitutionMap::subst(InFlightSubstitution &IFS) const { if (empty()) return SubstitutionMap(); + // FIXME: Get this caching working with pack expansions as well. + if (IFS.ActivePackExpansions.empty()) { + auto found = IFS.SubMaps.find(*this); + if (found != IFS.SubMaps.end()) + return found->second; + } + SmallVector newSubs; for (Type type : getReplacementTypes()) { newSubs.push_back(type.subst(IFS)); @@ -345,7 +352,12 @@ SubstitutionMap SubstitutionMap::subst(InFlightSubstitution &IFS) const { } assert(oldConformances.empty()); - return SubstitutionMap(genericSig, newSubs, newConformances); + auto result = SubstitutionMap(genericSig, newSubs, newConformances); + + if (IFS.ActivePackExpansions.empty()) + (void) IFS.SubMaps.insert(std::make_pair(*this, result)); + + return result; } SubstitutionMap @@ -624,9 +636,23 @@ SubstitutionMap swift::substOpaqueTypesWithUnderlyingTypes( ReplaceOpaqueTypesWithUnderlyingTypes replacer( context.getContext(), context.getResilienceExpansion(), context.isWholeModuleContext()); - return subs.subst(replacer, replacer, - SubstFlags::SubstituteOpaqueArchetypes | - SubstFlags::PreservePackExpansionLevel); + InFlightSubstitution IFS(replacer, replacer, + SubstFlags::SubstituteOpaqueArchetypes | + SubstFlags::PreservePackExpansionLevel); + + auto substSubs = subs.subst(IFS); + + if (IFS.wasLimitReached()) { + ABORT([&](auto &out) { + out << "Possible non-terminating type substitution detected\n\n"; + out << "Original substitution map:\n"; + subs.dump(out, SubstitutionMap::DumpStyle::NoConformances); + out << "Substituted substitution map:\n"; + substSubs.dump(out, SubstitutionMap::DumpStyle::NoConformances); + }); + } + + return substSubs; } Type OuterSubstitutions::operator()(SubstitutableType *type) const { diff --git a/lib/AST/TypeSubstitution.cpp b/lib/AST/TypeSubstitution.cpp index 8f84ee2defacb..06adf129d0951 100644 --- a/lib/AST/TypeSubstitution.cpp +++ b/lib/AST/TypeSubstitution.cpp @@ -123,9 +123,15 @@ operator()(InFlightSubstitution &IFS, Type dependentType, InFlightSubstitution::InFlightSubstitution(TypeSubstitutionFn substType, LookupConformanceFn lookupConformance, SubstOptions options) - : Options(options), - BaselineSubstType(substType), - BaselineLookupConformance(lookupConformance) { + : BaselineSubstType(substType), + BaselineLookupConformance(lookupConformance), + Options(options) { + + InitLimit = 0; + LimitReached = 0; + RemainingDepth = 0; + RemainingCount = 0; + // FIXME: Don't substitute type parameters if one of the special flags is set. Props |= RecursiveTypeProperties::HasTypeParameter; @@ -185,22 +191,14 @@ void InFlightSubstitution::expandPackExpansionShape(Type origShape, ActivePackExpansions.pop_back(); } -Type InFlightSubstitution::substType(SubstitutableType *origType, - unsigned level) { - auto substType = BaselineSubstType(origType); - if (!substType) - return Type(); +Type InFlightSubstitution::projectLaneFromPackType(Type substType, + unsigned level) { + auto outerExpansions = ArrayRef(ActivePackExpansions).drop_back(level); + auto innerExpansions = ArrayRef(ActivePackExpansions).take_back(level); // FIXME: All the logic around 'level' is probably slightly wrong, and in // the unlikely event that it is correct, at the very least warrants a // detailed explanation. - - if (ActivePackExpansions.empty()) - return substType->increasePackElementLevel(level); - - auto outerExpansions = ArrayRef(ActivePackExpansions).drop_back(level); - auto innerExpansions = ArrayRef(ActivePackExpansions).take_back(level); - unsigned outerLevel = 0; if (!getOptions().contains(SubstFlags::PreservePackExpansionLevel)) { for (const auto &activeExpansion : outerExpansions) { @@ -241,17 +239,56 @@ Type InFlightSubstitution::substType(SubstitutableType *origType, } } -ProtocolConformanceRef -InFlightSubstitution::lookupConformance(Type dependentType, - ProtocolDecl *proto, - unsigned level) { - auto substConfRef = BaselineLookupConformance(*this, dependentType, proto); - if (!substConfRef || - ActivePackExpansions.empty() || - !substConfRef.isPack()) - return substConfRef; +/// Note that the type is just used to recover an ASTContext. +bool InFlightSubstitution::checkLimits(Type ty) { + if (!InitLimit) { + auto &ctx = ty->getASTContext(); + + InitLimit = 1; + RemainingCount = ctx.LangOpts.MaxSubstitutionCount; + RemainingDepth = ctx.LangOpts.MaxSubstitutionDepth; + return false; + } + + if (RemainingCount == 0 || RemainingDepth == 0) { + LimitReached = true; + return true; + } + return false; +} + +Type InFlightSubstitution::substType(SubstitutableType *origType, + unsigned level) { + auto substType = BaselineSubstType(origType); + if (!substType) + return Type(); + + if (!ActivePackExpansions.empty()) + substType = projectLaneFromPackType(substType, level); + else + substType = substType->increasePackElementLevel(level); + + // Opaque type replacement must iterate until fixed point. + if (shouldSubstituteOpaqueArchetypes() && + substType->hasOpaqueArchetype() && + !substType->isEqual(origType)) { + if (checkLimits(origType)) { + return ErrorType::get(substType); + } + + --RemainingCount; + --RemainingDepth; + substType = substType.subst(*this); + ++RemainingDepth; + } + + return substType; +} - auto substPackConf = substConfRef.getPack(); +ProtocolConformanceRef +InFlightSubstitution::projectLaneFromPackConformance( + PackConformance *substPackConf, + unsigned level) { auto substPackPatterns = substPackConf->getPatternConformances(); assert(level < ActivePackExpansions.size() && "too deep"); auto index = ActivePackExpansions[ActivePackExpansions.size() - level - 1] @@ -262,6 +299,32 @@ InFlightSubstitution::lookupConformance(Type dependentType, return substPackPatterns[index]; } +ProtocolConformanceRef +InFlightSubstitution::lookupConformance(Type dependentType, + ProtocolDecl *proto, + unsigned level) { + auto substConfRef = BaselineLookupConformance(*this, dependentType, proto); + if (!ActivePackExpansions.empty() && substConfRef.isPack()) { + substConfRef = projectLaneFromPackConformance( + substConfRef.getPack(), level); + } + + // Opaque type replacement must iterate until fixed point. + if (shouldSubstituteOpaqueArchetypes() && substConfRef && + substConfRef.getType()->hasOpaqueArchetype() && + !substConfRef.getType()->isEqual(dependentType)) { + if (checkLimits(dependentType)) { + return ProtocolConformanceRef::forInvalid(); + } + --RemainingCount; + --RemainingDepth; + substConfRef = substConfRef.subst(*this); + ++RemainingDepth; + } + + return substConfRef; +} + namespace { class TypeSubstituter : public TypeTransform { @@ -295,7 +358,7 @@ class TypeSubstituter : public TypeTransform { std::optional transformLocalArchetypeType(LocalArchetypeType *local, TypePosition pos); - // SubstitutionMap transformSubstitutionMap(SubstitutionMap subs); + SubstitutionMap transformSubstitutionMap(SubstitutionMap subs); CanType transformSILField(CanType fieldTy, TypePosition pos); }; @@ -411,13 +474,10 @@ Type TypeSubstituter::transformDependentMemberType(DependentMemberType *dependen return result; } -// FIXME: This exposes a scalability issue; see test/SILGen/opaque_result_type_slow.swift. -/* SubstitutionMap TypeSubstituter::transformSubstitutionMap(SubstitutionMap subs) { // FIXME: Take level into account? Move level down into IFS? return subs.subst(IFS); } -*/ CanType TypeSubstituter::transformSILField(CanType fieldTy, TypePosition pos) { // Type substitution does not walk into the SILBoxType's field types, because @@ -894,17 +954,6 @@ ReplaceOpaqueTypesWithUnderlyingTypes::shouldPerformSubstitution( return OpaqueSubstitutionKind::SubstituteNonResilientModule; } -static Type substOpaqueTypesWithUnderlyingTypesRec( - Type ty, const DeclContext *inContext, ResilienceExpansion contextExpansion, - bool isWholeModuleContext, - llvm::DenseSet &decls) { - ReplaceOpaqueTypesWithUnderlyingTypes replacer(inContext, contextExpansion, - isWholeModuleContext, decls); - return ty.subst(replacer, replacer, - SubstFlags::SubstituteOpaqueArchetypes | - SubstFlags::PreservePackExpansionLevel); -} - /// Checks that \p dc has access to \p ty for the purposes of an opaque /// substitution described by \p kind. /// @@ -961,13 +1010,6 @@ static bool canSubstituteTypeInto(Type ty, const DeclContext *dc, llvm_unreachable("invalid substitution kind"); } -ReplaceOpaqueTypesWithUnderlyingTypes::ReplaceOpaqueTypesWithUnderlyingTypes( - const DeclContext *inContext, ResilienceExpansion contextExpansion, - bool isWholeModuleContext, llvm::DenseSet &seen) - : contextExpansion(contextExpansion), - inContextAndIsWholeModule(inContext, isWholeModuleContext), - seenDecls(&seen) {} - Type ReplaceOpaqueTypesWithUnderlyingTypes:: operator()(SubstitutableType *maybeOpaqueType) const { auto *archetype = dyn_cast(maybeOpaqueType); @@ -1015,36 +1057,7 @@ operator()(SubstitutableType *maybeOpaqueType) const { // for its type arguments. We perform this substitution after checking for // visibility, since we do not want the result of the visibility check to // depend on the substitutions previously applied. - auto substTy = partialSubstTy.subst(outerSubs); - - // If the type changed, but still contains opaque types, recur. - if (!substTy->isEqual(maybeOpaqueType) && substTy->hasOpaqueArchetype()) { - SeenDecl seenKey(decl, outerSubs); - if (auto *alreadySeen = this->seenDecls) { - // Detect substitution loops. If we find one, just bounce the original - // type back to the caller. This substitution will fail at runtime - // instead. - if (!alreadySeen->insert(seenKey).second) { - return maybeOpaqueType; - } - - auto res = ::substOpaqueTypesWithUnderlyingTypesRec( - substTy, inContext, contextExpansion, isContextWholeModule, - *alreadySeen); - alreadySeen->erase(seenKey); - return res; - } else { - // We're the top of the stack for the recursion check. Allocate a set of - // opaque result type decls we've already seen for the rest of the check. - llvm::DenseSet seenDecls; - seenDecls.insert(seenKey); - return ::substOpaqueTypesWithUnderlyingTypesRec( - substTy, inContext, contextExpansion, isContextWholeModule, - seenDecls); - } - } - - return substTy; + return partialSubstTy.subst(outerSubs); } Type swift::substOpaqueTypesWithUnderlyingTypes(Type ty, @@ -1056,9 +1069,25 @@ Type swift::substOpaqueTypesWithUnderlyingTypes(Type ty, ReplaceOpaqueTypesWithUnderlyingTypes replacer( context.getContext(), context.getResilienceExpansion(), context.isWholeModuleContext()); - SubstOptions flags = (SubstFlags::SubstituteOpaqueArchetypes | - SubstFlags::PreservePackExpansionLevel); - return ty.subst(replacer, replacer, flags); + InFlightSubstitution IFS(replacer, replacer, + SubstFlags::SubstituteOpaqueArchetypes | + SubstFlags::PreservePackExpansionLevel); + + auto substTy = ty.subst(IFS); + + // FIXME: This should be a diagnostic at the source location of the innermost + // request or something. + if (IFS.wasLimitReached()) { + ABORT([&](auto &out) { + out << "Possible non-terminating type substitution detected\n\n"; + out << "Original type:\n"; + ty.dump(out); + out << "Substituted type:\n"; + substTy.dump(out); + }); + } + + return substTy; } CanType @@ -1068,24 +1097,29 @@ swift::substOpaqueTypesWithUnderlyingTypes(CanType ty, ->getCanonicalType(); } -static ProtocolConformanceRef substOpaqueTypesWithUnderlyingTypesRec( - ProtocolConformanceRef ref, const DeclContext *inContext, - ResilienceExpansion contextExpansion, bool isWholeModuleContext, - llvm::DenseSet &decls) { - ReplaceOpaqueTypesWithUnderlyingTypes replacer(inContext, contextExpansion, - isWholeModuleContext, decls); - return ref.subst(replacer, replacer, - SubstFlags::SubstituteOpaqueArchetypes | - SubstFlags::PreservePackExpansionLevel); -} - ProtocolConformanceRef swift::substOpaqueTypesWithUnderlyingTypes( ProtocolConformanceRef ref, TypeExpansionContext context) { ReplaceOpaqueTypesWithUnderlyingTypes replacer( context.getContext(), context.getResilienceExpansion(), context.isWholeModuleContext()); - return ref.subst(replacer, replacer, - SubstFlags::SubstituteOpaqueArchetypes); + InFlightSubstitution IFS(replacer, replacer, + SubstFlags::SubstituteOpaqueArchetypes); + + auto substRef = ref.subst(IFS); + + // FIXME: This should be a diagnostic at the source location of the innermost + // request or something. + if (IFS.wasLimitReached()) { + ABORT([&](auto &out) { + out << "Possible non-terminating conformance substitution detected\n\n"; + out << "Original conformance:\n"; + ref.dump(out); + out << "\nSubstituted conformance:\n"; + substRef.dump(out); + }); + } + + return substRef; } ProtocolConformanceRef ReplaceOpaqueTypesWithUnderlyingTypes:: @@ -1139,36 +1173,7 @@ operator()(InFlightSubstitution &IFS, Type maybeOpaqueType, auto partialSubstRef = subs->lookupConformance(archetype->getInterfaceType()->getCanonicalType(), protocol); - auto substRef = partialSubstRef.subst(outerSubs); - - // If the type still contains opaque types, recur. - if (substRef.getType()->hasOpaqueArchetype()) { - SeenDecl seenKey(decl, outerSubs); - - if (auto *alreadySeen = this->seenDecls) { - // Detect substitution loops. If we find one, just bounce the original - // type back to the caller. This substitution will fail at runtime - // instead. - if (!alreadySeen->insert(seenKey).second) { - return lookupConformance(maybeOpaqueType.subst(IFS), protocol); - } - - auto res = ::substOpaqueTypesWithUnderlyingTypesRec( - substRef, inContext, contextExpansion, isContextWholeModule, - *alreadySeen); - alreadySeen->erase(seenKey); - return res; - } else { - // We're the top of the stack for the recursion check. Allocate a set of - // opaque result type decls we've already seen for the rest of the check. - llvm::DenseSet seenDecls; - seenDecls.insert(seenKey); - return ::substOpaqueTypesWithUnderlyingTypesRec( - substRef, inContext, contextExpansion, isContextWholeModule, - seenDecls); - } - } - return substRef; + return partialSubstRef.subst(outerSubs); } Type ReplaceExistentialArchetypesWithConcreteTypes::getInterfaceType( diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 6b31e72876c2d..37ef6d6f9c3f7 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1137,21 +1137,28 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, Opts.WarnOnEditorPlaceholder |= Args.hasArg(OPT_warn_on_editor_placeholder); - if (auto A = Args.getLastArg(OPT_disable_typo_correction, - OPT_typo_correction_limit)) { - if (A->getOption().matches(OPT_disable_typo_correction)) - Opts.TypoCorrectionLimit = 0; - else { - unsigned limit; - if (StringRef(A->getValue()).getAsInteger(10, limit)) { - Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, - A->getAsString(Args), A->getValue()); - HadError = true; - } else { - Opts.TypoCorrectionLimit = limit; - } - } - } + auto setUnsignedIntegerArgument = + [&Args, &Diags, &HadError](options::ID optionID, unsigned &valueToSet) { + if (const Arg *A = Args.getLastArg(optionID)) { + unsigned attempt; + if (StringRef(A->getValue()).getAsInteger(/*radix*/ 10, attempt)) { + Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, + A->getAsString(Args), A->getValue()); + HadError = true; + } else { + valueToSet = attempt; + } + } + }; + + setUnsignedIntegerArgument(OPT_typo_correction_limit, + Opts.TypoCorrectionLimit); + + if (Args.hasArg(OPT_disable_typo_correction)) + Opts.TypoCorrectionLimit = 0; + + setUnsignedIntegerArgument(OPT_value_recursion_threshold, + Opts.MaxCircularityDepth); if (auto A = Args.getLastArg(OPT_enable_target_os_checking, OPT_disable_target_os_checking)) { @@ -1227,17 +1234,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, Opts.AvailabilityMacros.push_back(A->getValue()); } - if (const Arg *A = Args.getLastArg(OPT_value_recursion_threshold)) { - unsigned threshold; - if (StringRef(A->getValue()).getAsInteger(10, threshold)) { - Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, - A->getAsString(Args), A->getValue()); - HadError = true; - } else { - Opts.MaxCircularityDepth = threshold; - } - } - for (const Arg *A : Args.filtered(OPT_D)) { Opts.addCustomConditionalCompilationFlag(A->getValue()); } @@ -1737,71 +1733,18 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, if (const Arg *A = Args.getLastArg(OPT_debug_requirement_machine)) Opts.DebugRequirementMachine = A->getValue(); - if (const Arg *A = Args.getLastArg(OPT_requirement_machine_max_rule_count)) { - unsigned limit; - if (StringRef(A->getValue()).getAsInteger(10, limit)) { - Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, - A->getAsString(Args), A->getValue()); - HadError = true; - } else { - Opts.RequirementMachineMaxRuleCount = limit; - } - } - - if (const Arg *A = Args.getLastArg(OPT_requirement_machine_max_rule_length)) { - unsigned limit; - if (StringRef(A->getValue()).getAsInteger(10, limit)) { - Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, - A->getAsString(Args), A->getValue()); - HadError = true; - } else { - Opts.RequirementMachineMaxRuleLength = limit; - } - } - - if (const Arg *A = Args.getLastArg(OPT_requirement_machine_max_concrete_nesting)) { - unsigned limit; - if (StringRef(A->getValue()).getAsInteger(10, limit)) { - Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, - A->getAsString(Args), A->getValue()); - HadError = true; - } else { - Opts.RequirementMachineMaxConcreteNesting = limit; - } - } - - if (const Arg *A = Args.getLastArg(OPT_requirement_machine_max_concrete_size)) { - unsigned limit; - if (StringRef(A->getValue()).getAsInteger(10, limit)) { - Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, - A->getAsString(Args), A->getValue()); - HadError = true; - } else { - Opts.RequirementMachineMaxConcreteSize = limit; - } - } - - if (const Arg *A = Args.getLastArg(OPT_requirement_machine_max_type_differences)) { - unsigned limit; - if (StringRef(A->getValue()).getAsInteger(10, limit)) { - Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, - A->getAsString(Args), A->getValue()); - HadError = true; - } else { - Opts.RequirementMachineMaxTypeDifferences = limit; - } - } - - if (const Arg *A = Args.getLastArg(OPT_requirement_machine_max_split_concrete_equiv_class_attempts)) { - unsigned limit; - if (StringRef(A->getValue()).getAsInteger(10, limit)) { - Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, - A->getAsString(Args), A->getValue()); - HadError = true; - } else { - Opts.RequirementMachineMaxSplitConcreteEquivClassAttempts = limit; - } - } + setUnsignedIntegerArgument(OPT_requirement_machine_max_rule_count, + Opts.RequirementMachineMaxRuleCount); + setUnsignedIntegerArgument(OPT_requirement_machine_max_rule_length, + Opts.RequirementMachineMaxRuleLength); + setUnsignedIntegerArgument(OPT_requirement_machine_max_concrete_nesting, + Opts.RequirementMachineMaxConcreteNesting); + setUnsignedIntegerArgument(OPT_requirement_machine_max_concrete_size, + Opts.RequirementMachineMaxConcreteSize); + setUnsignedIntegerArgument(OPT_requirement_machine_max_type_differences, + Opts.RequirementMachineMaxTypeDifferences); + setUnsignedIntegerArgument(OPT_requirement_machine_max_split_concrete_equiv_class_attempts, + Opts.RequirementMachineMaxSplitConcreteEquivClassAttempts); if (Args.hasArg(OPT_disable_requirement_machine_concrete_contraction)) Opts.EnableRequirementMachineConcreteContraction = false; @@ -1815,6 +1758,11 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, if (Args.hasArg(OPT_enable_requirement_machine_opaque_archetypes)) Opts.EnableRequirementMachineOpaqueArchetypes = true; + setUnsignedIntegerArgument(OPT_max_substitution_depth, + Opts.MaxSubstitutionDepth); + setUnsignedIntegerArgument(OPT_max_substitution_count, + Opts.MaxSubstitutionCount); + if (Args.hasArg(OPT_enable_experimental_lifetime_dependence_inference)) Opts.EnableExperimentalLifetimeDependenceInference = true; if (Args.hasArg(OPT_disable_experimental_lifetime_dependence_inference)) @@ -1848,7 +1796,8 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, HadError = true; } - if (!FrontendOpts.InputsAndOutputs.isWholeModule() && FrontendOptions::doesActionGenerateSIL(FrontendOpts.RequestedAction)) { + if (!FrontendOpts.InputsAndOutputs.isWholeModule() && + FrontendOptions::doesActionGenerateSIL(FrontendOpts.RequestedAction)) { Diags.diagnose(SourceLoc(), diag::wmo_with_embedded); HadError = true; } diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index a6d86969ff3f7..44c1025583730 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -7515,17 +7515,15 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType, if (!substitutions.empty()) { // Compute the underlying type by replacing all opaque archetypes with // the fixed type of their opened type. - auto underlyingType = toType.subst( - [&](SubstitutableType *type) -> Type { - if (auto *opaqueType = type->getAs()) { + auto underlyingType = toType.transformRec( + [&](TypeBase *type) -> std::optional { + if (auto *opaqueType = dyn_cast(type)) { if (opaqueType->getDecl() == opaqueDecl) { return opaqueType->getInterfaceType().subst(substitutions); } } - return type; - }, - LookUpConformanceInModule(), - SubstFlags::SubstituteOpaqueArchetypes); + return std::nullopt; + }); // Coerce the result expression to the underlying type. // FIXME: Wrong locator? diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp index 1ad7722050e7f..1a168d8fc2c46 100644 --- a/lib/Sema/MiscDiagnostics.cpp +++ b/lib/Sema/MiscDiagnostics.cpp @@ -27,6 +27,7 @@ #include "swift/AST/DiagnosticsSema.h" #include "swift/AST/ExistentialLayout.h" #include "swift/AST/Expr.h" +#include "swift/AST/InFlightSubstitution.h" #include "swift/AST/NameLookup.h" #include "swift/AST/NameLookupRequests.h" #include "swift/AST/Pattern.h" @@ -3670,12 +3671,33 @@ class OpaqueUnderlyingTypeChecker : public ASTWalker { // The underlying type can't be defined recursively // in terms of the opaque type itself. - auto opaqueTypeInContext = Implementation->mapTypeIntoContext( - OpaqueDecl->getDeclaredInterfaceType()); for (auto genericParam : OpaqueDecl->getOpaqueGenericParams()) { auto underlyingType = Type(genericParam).subst(substitutions); - auto isSelfReferencing = underlyingType.findIf( - [&](Type t) -> bool { return t->isEqual(opaqueTypeInContext); }); + + // Look through underlying types of other opaque archetypes known to + // us. This is not something the type checker is allowed to do in + // general, since the intent is that the underlying type is completely + // hidden from view at the type system level. However, here we're + // trying to catch recursive underlying types before we proceed to + // SIL, so we specifically want to erase opaque archetypes just + // for the purpose of this check. + ReplaceOpaqueTypesWithUnderlyingTypes replacer( + OpaqueDecl->getDeclContext(), + ResilienceExpansion::Maximal, + /*isWholeModuleContext=*/false); + InFlightSubstitution IFS(replacer, replacer, + SubstFlags::SubstituteOpaqueArchetypes | + SubstFlags::PreservePackExpansionLevel); + auto simplifiedUnderlyingType = underlyingType.subst(IFS); + + auto isSelfReferencing = + (IFS.wasLimitReached() || + simplifiedUnderlyingType.findIf([&](Type t) -> bool { + if (auto *other = t->getAs()) { + return other->getDecl() == OpaqueDecl; + } + return false; + })); if (isSelfReferencing) { Ctx.Diags.diagnose(std::get<0>(candidate)->getLoc(), diff --git a/test/Generics/infinite_opaque_result_type.swift b/test/Generics/infinite_opaque_result_type.swift new file mode 100644 index 0000000000000..1ed8fac0cd32d --- /dev/null +++ b/test/Generics/infinite_opaque_result_type.swift @@ -0,0 +1,73 @@ +// RUN: %target-typecheck-verify-swift + +func concrete1() -> some Any { +// expected-error@-1 {{function declares an opaque return type, but has no return statements in its body from which to infer an underlying type}} + return concrete1() +} + +func concrete2() -> some Any { + return [concrete2()] // expected-error {{function opaque return type was inferred as '[some Any]', which defines the opaque type in terms of itself}} +} + + +func concrete1a() -> some Any { + return concrete1b() // expected-error {{function opaque return type was inferred as 'some Any', which defines the opaque type in terms of itself}} +} + +func concrete1b() -> some Any { + return concrete1a() +} + + +func concrete2a() -> some Any { + return [concrete2b()] // expected-error {{function opaque return type was inferred as '[some Any]', which defines the opaque type in terms of itself}} +} + +func concrete2b() -> some Any { + return [concrete2a()] +} + + +func generic1(_ t: T) -> some Any { +// expected-error@-1 {{function declares an opaque return type, but has no return statements in its body from which to infer an underlying type}} + return generic1(t) +} + +func generic2(_ t: T) -> some Any { + return [generic2(t)] // expected-error {{function opaque return type was inferred as '[some Any]', which defines the opaque type in terms of itself}} +} + + +func generic1a(_ t: T) -> some Any { + return generic1b(t) // expected-error {{function opaque return type was inferred as 'some Any', which defines the opaque type in terms of itself}} +} + +func generic1b(_ t: T) -> some Any { + return generic1a(t) +} + + +func generic2a(_ t: T) -> some Any { + return [generic2b(t)] // expected-error {{function opaque return type was inferred as '[some Any]', which defines the opaque type in terms of itself}} +} + +func generic2b(_ t: T) -> some Any { + return [generic2a(t)] +} + + +func generic3a(_ t: T) -> some Any { + return [generic3b(t)] // expected-error {{function opaque return type was inferred as '[some Any]', which defines the opaque type in terms of itself}} +} + +func generic3b(_ t: T) -> some Any { + return [generic3a([t])] +} + +func very_wide1() -> some Any { + return (very_wide2(), very_wide2()) // expected-error {{function opaque return type was inferred as '(some Any, some Any)', which defines the opaque type in terms of itself}} +} + +func very_wide2() -> some Any { + return (very_wide1(), very_wide1()) +} \ No newline at end of file diff --git a/test/type/opaque.swift b/test/type/opaque.swift index 87dbd5bcb08c9..66d5603a0eced 100644 --- a/test/type/opaque.swift +++ b/test/type/opaque.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -disable-availability-checking -typecheck -verify %s +// RUN: %target-swift-frontend -target %target-swift-5.1-abi-triple -typecheck -verify %s protocol P { func paul() @@ -205,13 +205,6 @@ struct MismatchedReturnTypesSubscript { } } -func jan() -> some P { - return [marcia(), marcia(), marcia()] -} -func marcia() -> some P { - return [marcia(), marcia(), marcia()] // expected-error{{defines the opaque type in terms of itself}} {{documentation-file=opaque-type-inference}} -} - protocol R { associatedtype S: P, Q // expected-note*{{}} diff --git a/validation-test/Sema/type_checker_perf/fast/cgfloat_double_math_mix.swift b/validation-test/Sema/type_checker_perf/fast/cgfloat_double_math_mix.swift new file mode 100644 index 0000000000000..5a29edf31ea49 --- /dev/null +++ b/validation-test/Sema/type_checker_perf/fast/cgfloat_double_math_mix.swift @@ -0,0 +1,107 @@ +// RUN: %target-typecheck-verify-swift -solver-scope-threshold=200 +// REQUIRES: objc_interop + +import Foundation + +func f0(_ d: Double, _ f: CGFloat) { _ = { _ = ((((d - 1.0) + (d + 1.0)) / ((1.0 / .pi.squareRoot()) / 1.0)) - ((f - (1.0 * f)) * ((1.0 + 1.0) + (1.0 - d)))) / ((1.0 + .pi) / (1.0 * ((1.0 * .pi.squareRoot()) / (1.0 / f)))) } } +func f1(_ d: Double, _ f: CGFloat) { _ = { _ = ((f * .pi) * (((f - f) - (1.0 + 1.0)) / f)) / ((.pi.squareRoot() / .pi.squareRoot()) / (((.pi / .pi.squareRoot()) + (1.0 - 1.0)) + d)) } } +func f2(_ d: Double, _ f: CGFloat) { _ = { _ = (((1.0 / 1.0) - 1.0) * (((.pi.squareRoot() - .pi.squareRoot()) / 1.0) / (.pi * (1.0 * .pi)))) - ((1.0 + d) + (((1.0 / 1.0) / (1.0 / .pi.squareRoot())) + 1.0)) } } +func f3(_ d: Double, _ f: CGFloat) { _ = { _ = ((((1.0 - d) / 1.0) * (1.0 + (1.0 / 1.0))) / ((1.0 * (1.0 + f)) + 1.0)) + ((((1.0 / .pi) * (d / .pi.squareRoot())) / (f / (.pi.squareRoot() + 1.0))) + (((d - .pi.squareRoot()) + (d + 1.0)) / (.pi.squareRoot() + (1.0 + .pi.squareRoot())))) } } +func f4(_ d: Double, _ f: CGFloat) { _ = { _ = ((1.0 - ((d / f) * 1.0)) - ((1.0 + (d / .pi)) - (1.0 - (1.0 - f)))) * ((((1.0 - f) - (1.0 + .pi)) * ((f * d) - (1.0 / .pi))) + (1.0 * ((.pi.squareRoot() * 1.0) + 1.0))) } } +func f5(_ d: Double, _ f: CGFloat) { _ = { _ = ((((d * 1.0) * .pi.squareRoot()) + ((.pi.squareRoot() + .pi) / 1.0)) - ((1.0 * (1.0 - 1.0)) / ((f * 1.0) - .pi))) * ((.pi.squareRoot() * 1.0) / (.pi / (.pi - (.pi.squareRoot() + .pi.squareRoot())))) } } +func f6(_ d: Double, _ f: CGFloat) { _ = { _ = ((1.0 / ((.pi - 1.0) - (.pi.squareRoot() - 1.0))) - (((.pi + 1.0) + .pi.squareRoot()) * (1.0 + .pi.squareRoot()))) * ((1.0 + .pi.squareRoot()) + (((.pi.squareRoot() - 1.0) + d) + f)) } } +func f7(_ d: Double, _ f: CGFloat) { _ = { _ = ((((1.0 * 1.0) * (d / f)) - 1.0) - (((.pi.squareRoot() + 1.0) - (.pi.squareRoot() / f)) * (f * (f * .pi)))) - ((((1.0 / 1.0) / (1.0 / 1.0)) / ((1.0 * .pi) * (d * .pi.squareRoot()))) * (.pi + .pi)) } } +func f8(_ d: Double, _ f: CGFloat) { _ = { _ = (((1.0 / (1.0 * .pi.squareRoot())) + ((f - 1.0) / .pi)) + ((d - f) + 1.0)) - ((1.0 - ((.pi / 1.0) / .pi.squareRoot())) / (.pi + ((1.0 + f) / (.pi * 1.0)))) } } +func f9(_ d: Double, _ f: CGFloat) { _ = { _ = (((1.0 / 1.0) * ((1.0 / 1.0) * (f * 1.0))) / (1.0 / 1.0)) * ((((1.0 - 1.0) + (1.0 - f)) - ((1.0 + .pi) + (f * d))) * (((1.0 + .pi.squareRoot()) / 1.0) / d)) } } +func f10(_ d: Double, _ f: CGFloat) { _ = { _ = ((((d - .pi.squareRoot()) + (1.0 - d)) + ((d - d) + .pi.squareRoot())) - (((1.0 / .pi) / d) - (1.0 / .pi.squareRoot()))) + ((((1.0 / f) + (d - 1.0)) - (1.0 - 1.0)) / (((d - 1.0) + (.pi.squareRoot() - d)) + ((1.0 + d) / 1.0))) } } +func f11(_ d: Double, _ f: CGFloat) { _ = { _ = ((1.0 / .pi.squareRoot()) / (((1.0 * .pi.squareRoot()) / (f * 1.0)) * 1.0)) + ((1.0 / ((1.0 / 1.0) - (d - 1.0))) * (((.pi.squareRoot() * d) + (1.0 * 1.0)) * 1.0)) } } +func f12(_ d: Double, _ f: CGFloat) { _ = { _ = ((((f - .pi) * .pi) / (1.0 + (1.0 - 1.0))) + ((.pi / (1.0 - 1.0)) + 1.0)) / ((((1.0 / f) / (1.0 / .pi.squareRoot())) - d) * ((d * (1.0 * .pi.squareRoot())) * ((f / .pi.squareRoot()) - (.pi + 1.0)))) } } +func f13(_ d: Double, _ f: CGFloat) { _ = { _ = ((((.pi * .pi.squareRoot()) / (1.0 / 1.0)) / ((d + 1.0) - (d - 1.0))) / ((f - f) * ((1.0 - 1.0) + (1.0 / d)))) * (((.pi + (1.0 * f)) * .pi) + ((1.0 - .pi) * d)) } } +func f14(_ d: Double, _ f: CGFloat) { _ = { _ = ((1.0 * ((.pi.squareRoot() - 1.0) / (1.0 + .pi))) / ((d / d) / ((1.0 / 1.0) + (.pi / 1.0)))) * ((1.0 * .pi.squareRoot()) + ((1.0 / 1.0) + ((1.0 - 1.0) * 1.0))) } } +func f15(_ d: Double, _ f: CGFloat) { _ = { _ = (((1.0 / (d / 1.0)) * .pi) - ((f - (.pi * .pi)) + (1.0 / (d - 1.0)))) + ((((1.0 + 1.0) * (1.0 + 1.0)) + d) + ((1.0 - .pi.squareRoot()) - .pi)) } } +func f16(_ d: Double, _ f: CGFloat) { _ = { _ = ((((.pi + .pi.squareRoot()) * (.pi.squareRoot() * 1.0)) + ((.pi.squareRoot() / .pi.squareRoot()) + (1.0 - d))) - (.pi / (1.0 / (1.0 + .pi)))) * (((.pi.squareRoot() / (f / 1.0)) - d) * ((f - (f * f)) - (1.0 * d))) } } +func f17(_ d: Double, _ f: CGFloat) { _ = { _ = ((((d + .pi) + (1.0 / f)) / (1.0 * (.pi / .pi))) * (f / (.pi + (1.0 - .pi.squareRoot())))) * ((((d + 1.0) * 1.0) - ((.pi / .pi) + (d + .pi))) * (((.pi.squareRoot() + f) - (1.0 - .pi)) / ((f - d) / 1.0))) } } +func f18(_ d: Double, _ f: CGFloat) { _ = { _ = ((.pi + 1.0) + (((f - 1.0) + (d + f)) - ((1.0 * 1.0) + (1.0 / .pi.squareRoot())))) / ((1.0 + ((.pi.squareRoot() * 1.0) + (1.0 - .pi.squareRoot()))) / (f + ((d * f) * (1.0 + 1.0)))) } } +func f19(_ d: Double, _ f: CGFloat) { _ = { _ = (((1.0 * (1.0 - .pi.squareRoot())) - ((1.0 * 1.0) / .pi)) - (1.0 + ((.pi.squareRoot() + 1.0) / (d * f)))) + (((1.0 + 1.0) - ((d - .pi.squareRoot()) * (1.0 + 1.0))) - (.pi - (1.0 + (1.0 + 1.0)))) } } +func f20(_ d: Double, _ f: CGFloat) { _ = { _ = ((.pi * (.pi / (1.0 - f))) + (((.pi.squareRoot() + 1.0) + .pi.squareRoot()) - ((.pi + d) - (1.0 + .pi.squareRoot())))) * ((((1.0 + f) / (1.0 * 1.0)) - 1.0) + (d + f)) } } +func f21(_ d: Double, _ f: CGFloat) { _ = { _ = ((((f - 1.0) + (.pi.squareRoot() * 1.0)) - ((f - 1.0) - (.pi.squareRoot() - 1.0))) + (((1.0 + .pi.squareRoot()) * 1.0) + 1.0)) / ((.pi * 1.0) - (.pi.squareRoot() * ((d + .pi.squareRoot()) / (1.0 * .pi.squareRoot())))) } } +func f22(_ d: Double, _ f: CGFloat) { _ = { _ = ((((1.0 * .pi.squareRoot()) - .pi.squareRoot()) - ((d + 1.0) * (f - 1.0))) / (f / ((f / 1.0) * d))) - ((d + 1.0) + (1.0 / ((d + f) + (1.0 / .pi)))) } } +func f23(_ d: Double, _ f: CGFloat) { _ = { _ = (((1.0 * (f - .pi.squareRoot())) * (1.0 / (.pi / f))) + (((.pi + .pi.squareRoot()) * (f - .pi.squareRoot())) + (d - (1.0 - 1.0)))) + ((.pi / d) - (.pi.squareRoot() - ((1.0 / 1.0) * .pi))) } } +func f24(_ d: Double, _ f: CGFloat) { _ = { _ = ((((f * 1.0) * (.pi.squareRoot() / d)) - 1.0) - ((1.0 + (d * 1.0)) * 1.0)) - (((.pi / .pi) * 1.0) + (.pi / ((.pi.squareRoot() / 1.0) + (d * 1.0)))) } } +func f25(_ d: Double, _ f: CGFloat) { _ = { _ = ((((f * f) / (1.0 - d)) + ((.pi.squareRoot() + .pi) * f)) / (1.0 * ((.pi / .pi.squareRoot()) * (f - .pi.squareRoot())))) / ((((1.0 + 1.0) + (f - d)) - .pi.squareRoot()) - ((d / (.pi * .pi)) + ((.pi.squareRoot() / .pi.squareRoot()) - (1.0 * .pi.squareRoot())))) } } +func f26(_ d: Double, _ f: CGFloat) { _ = { _ = ((((.pi - 1.0) / (1.0 * .pi.squareRoot())) / ((1.0 - 1.0) * (.pi - .pi))) - (.pi.squareRoot() - (1.0 - (1.0 * d)))) - ((((d + d) / f) + ((.pi.squareRoot() - 1.0) + (1.0 + .pi))) - (.pi.squareRoot() - .pi)) } } +func f27(_ d: Double, _ f: CGFloat) { _ = { _ = ((((1.0 * .pi) / d) * (.pi.squareRoot() / (.pi.squareRoot() - 1.0))) + (1.0 * ((1.0 + 1.0) + 1.0))) + ((((1.0 / 1.0) - 1.0) - ((1.0 + 1.0) * (.pi.squareRoot() / 1.0))) * (((1.0 - .pi.squareRoot()) + (f * 1.0)) + d)) } } +func f28(_ d: Double, _ f: CGFloat) { _ = { _ = ((f + .pi) + (((f + d) + (1.0 * .pi.squareRoot())) * 1.0)) - ((((.pi / 1.0) - (1.0 - .pi.squareRoot())) / (1.0 * (.pi.squareRoot() * f))) / (((1.0 * f) / (.pi + .pi.squareRoot())) * (1.0 - (1.0 * 1.0)))) } } +func f29(_ d: Double, _ f: CGFloat) { _ = { _ = ((((d / .pi) - f) - (1.0 + f)) * (1.0 / d)) * ((((.pi - 1.0) / (1.0 / 1.0)) - d) + (((d * .pi) + 1.0) - d)) } } +func f30(_ d: Double, _ f: CGFloat) { _ = { _ = ((((1.0 * d) * (f * .pi.squareRoot())) * d) / (((.pi * .pi) - (1.0 / 1.0)) * (1.0 - (d / d)))) / ((((1.0 / .pi) * (1.0 + d)) / ((.pi.squareRoot() + 1.0) / (1.0 + f))) * (((d * .pi) + (.pi * f)) + 1.0)) } } +func f31(_ d: Double, _ f: CGFloat) { _ = { _ = ((d / .pi.squareRoot()) / ((1.0 / (f + .pi.squareRoot())) * 1.0)) * (((1.0 * (1.0 - .pi.squareRoot())) / ((d / d) + .pi.squareRoot())) / (((1.0 + 1.0) - (1.0 / .pi)) - f)) } } +func f32(_ d: Double, _ f: CGFloat) { _ = { _ = (((.pi / (f * 1.0)) - ((1.0 - d) / .pi)) * (1.0 * ((.pi - .pi.squareRoot()) - (f * .pi.squareRoot())))) * ((((1.0 - .pi) - (.pi + f)) * ((1.0 - .pi.squareRoot()) / (.pi.squareRoot() / f))) + ((1.0 - (d / 1.0)) - ((1.0 + 1.0) - (f - 1.0)))) } } +func f33(_ d: Double, _ f: CGFloat) { _ = { _ = ((1.0 / ((1.0 / f) + (d + d))) + (((1.0 + d) - .pi) * .pi.squareRoot())) - (((.pi / (.pi * f)) + (f + (.pi - d))) + (((.pi * 1.0) + .pi.squareRoot()) + ((f - .pi) / (1.0 * .pi)))) } } +func f34(_ d: Double, _ f: CGFloat) { _ = { _ = ((.pi.squareRoot() + 1.0) / (((1.0 - d) + (.pi.squareRoot() - f)) / d)) + ((f / d) + (((.pi / f) * d) / ((f - d) + (1.0 / .pi.squareRoot())))) } } +func f35(_ d: Double, _ f: CGFloat) { _ = { _ = (((1.0 / (1.0 / 1.0)) * ((.pi.squareRoot() / f) / (1.0 * 1.0))) * (.pi.squareRoot() - ((.pi - 1.0) / d))) - ((1.0 - (.pi / 1.0)) - (.pi + (.pi - (.pi * f)))) } } +func f36(_ d: Double, _ f: CGFloat) { _ = { _ = (((1.0 / 1.0) - ((1.0 - .pi) * (d / .pi.squareRoot()))) / (((.pi / .pi) * (.pi.squareRoot() * .pi.squareRoot())) - ((f / .pi) * (f * 1.0)))) - ((1.0 + (f / (.pi - f))) / (1.0 * ((.pi.squareRoot() * .pi.squareRoot()) - (1.0 / .pi)))) } } +func f37(_ d: Double, _ f: CGFloat) { _ = { _ = ((((d + .pi.squareRoot()) / (.pi.squareRoot() - 1.0)) / ((f / 1.0) * (1.0 * 1.0))) - (((1.0 - 1.0) / 1.0) - ((d / .pi.squareRoot()) - 1.0))) - ((1.0 * .pi.squareRoot()) / (.pi.squareRoot() / (.pi - (1.0 / d)))) } } +func f38(_ d: Double, _ f: CGFloat) { _ = { _ = ((((.pi.squareRoot() - 1.0) * (1.0 * .pi)) - ((1.0 / f) / (.pi * .pi))) * (((1.0 + 1.0) - .pi.squareRoot()) - (1.0 / (.pi - .pi.squareRoot())))) * (((1.0 + (1.0 - d)) / ((1.0 + 1.0) - (.pi - f))) / (((.pi * .pi) / 1.0) * f)) } } +func f39(_ d: Double, _ f: CGFloat) { _ = { _ = ((((1.0 * 1.0) * d) + d) - (d / 1.0)) / ((((1.0 * .pi.squareRoot()) * 1.0) * (.pi * 1.0)) / ((.pi - .pi) * 1.0)) } } +func f40(_ d: Double, _ f: CGFloat) { _ = { _ = ((d - ((f - f) / .pi.squareRoot())) * (((.pi.squareRoot() * 1.0) + 1.0) + (1.0 - (1.0 + 1.0)))) / (((1.0 - (1.0 + .pi.squareRoot())) / 1.0) / (d - .pi.squareRoot())) } } +func f41(_ d: Double, _ f: CGFloat) { _ = { _ = ((d + ((1.0 - 1.0) + (.pi.squareRoot() / 1.0))) * ((d + (1.0 + d)) * (1.0 - (1.0 + 1.0)))) / ((((f - 1.0) + (.pi.squareRoot() - 1.0)) / ((f / f) - f)) * ((.pi.squareRoot() + (1.0 * f)) * ((1.0 + d) * (1.0 + .pi)))) } } +func f42(_ d: Double, _ f: CGFloat) { _ = { _ = ((((f * d) / (f - 1.0)) + (1.0 / (.pi + f))) * (((.pi.squareRoot() / f) * 1.0) / ((.pi.squareRoot() / .pi) + (f * 1.0)))) / ((1.0 - ((.pi / 1.0) * (f * 1.0))) - ((1.0 / (f / f)) / (d / (f / 1.0)))) } } +func f43(_ d: Double, _ f: CGFloat) { _ = { _ = ((d / .pi) * (1.0 * ((f / 1.0) + (f - f)))) - ((f - ((f + 1.0) * (1.0 / d))) / (((1.0 - d) + 1.0) / ((1.0 * .pi.squareRoot()) / 1.0))) } } +func f44(_ d: Double, _ f: CGFloat) { _ = { _ = ((((.pi.squareRoot() * 1.0) * (1.0 * .pi.squareRoot())) * ((1.0 - 1.0) / .pi)) - ((.pi.squareRoot() + (d * 1.0)) / ((1.0 - d) - (1.0 * d)))) - ((d + ((.pi - f) / (f - 1.0))) * (((.pi / d) / (d * .pi.squareRoot())) * .pi)) } } +func f45(_ d: Double, _ f: CGFloat) { _ = { _ = (((1.0 - 1.0) * d) - (((1.0 * f) * 1.0) * ((1.0 * .pi.squareRoot()) * 1.0))) - ((1.0 + ((1.0 + f) - (.pi.squareRoot() + f))) + (.pi * f)) } } +func f46(_ d: Double, _ f: CGFloat) { _ = { _ = ((((1.0 + 1.0) * d) * .pi.squareRoot()) / ((d / 1.0) - (1.0 / (.pi - .pi)))) * ((1.0 + .pi.squareRoot()) + (((.pi.squareRoot() + f) / 1.0) - 1.0)) } } +func f47(_ d: Double, _ f: CGFloat) { _ = { _ = (((f * (1.0 / .pi.squareRoot())) / .pi.squareRoot()) - (((.pi.squareRoot() / .pi.squareRoot()) / (d / 1.0)) + (f - (.pi + d)))) + ((((d + f) - (d / f)) / d) * ((.pi - 1.0) / 1.0)) } } +func f48(_ d: Double, _ f: CGFloat) { _ = { _ = ((1.0 * d) / (1.0 + (d / (.pi + .pi)))) - ((((d / .pi) - (.pi - .pi.squareRoot())) / ((1.0 / d) - (f + .pi.squareRoot()))) - ((.pi.squareRoot() / (f + 1.0)) * (.pi * (1.0 / d)))) } } +func f49(_ d: Double, _ f: CGFloat) { _ = { _ = (((1.0 - (.pi.squareRoot() + d)) * ((1.0 * f) - (.pi * .pi))) - ((1.0 * (d * 1.0)) + f)) * ((((1.0 - d) + (1.0 - .pi)) * ((1.0 * 1.0) - (.pi.squareRoot() / .pi.squareRoot()))) / (1.0 - 1.0)) } } +func f50(_ d: Double, _ f: CGFloat) { _ = { _ = ((d * (f + .pi.squareRoot())) - (((d * f) / (.pi + d)) / (.pi.squareRoot() - (.pi / .pi.squareRoot())))) - ((((f + 1.0) + 1.0) * f) * (((1.0 / 1.0) * (.pi / d)) * ((1.0 * f) / (1.0 / d)))) } } +func f51(_ d: Double, _ f: CGFloat) { _ = { _ = (((.pi.squareRoot() - (1.0 - d)) * (d - d)) / (((.pi * d) / (1.0 + 1.0)) / (.pi - 1.0))) / ((((1.0 - 1.0) / (.pi * f)) + (1.0 * 1.0)) - (((1.0 - 1.0) - d) - ((f / .pi.squareRoot()) / (1.0 + f)))) } } +func f52(_ d: Double, _ f: CGFloat) { _ = { _ = ((.pi - 1.0) / (((f / 1.0) - 1.0) - ((d * .pi) - .pi.squareRoot()))) * ((1.0 + (d + (1.0 + 1.0))) + (((f - .pi) * (.pi / 1.0)) + d)) } } +func f53(_ d: Double, _ f: CGFloat) { _ = { _ = ((((.pi * f) - (1.0 - 1.0)) * ((f + 1.0) + 1.0)) * (1.0 / d)) / (((d / (f * 1.0)) + ((1.0 * 1.0) + (d + 1.0))) - (((d * 1.0) - (1.0 - .pi.squareRoot())) / 1.0)) } } +func f54(_ d: Double, _ f: CGFloat) { _ = { _ = ((((.pi.squareRoot() + d) / (1.0 + .pi.squareRoot())) * ((.pi.squareRoot() / f) / (1.0 * 1.0))) - (((.pi.squareRoot() * f) - d) / ((1.0 - 1.0) - f))) * ((((.pi - 1.0) / (1.0 + d)) - (d + (1.0 - 1.0))) + (.pi + (1.0 + f))) } } +func f55(_ d: Double, _ f: CGFloat) { _ = { _ = (((1.0 + (1.0 + d)) / (f - (1.0 + d))) * (f / (.pi * (1.0 - 1.0)))) / ((((1.0 * .pi) / (d / f)) + ((1.0 / d) / (.pi.squareRoot() * .pi.squareRoot()))) / (1.0 + ((1.0 - 1.0) * (1.0 * 1.0)))) } } +func f56(_ d: Double, _ f: CGFloat) { _ = { _ = ((((.pi * d) * (d - f)) - ((.pi.squareRoot() / 1.0) + (.pi - .pi.squareRoot()))) * (((.pi - .pi.squareRoot()) - (1.0 + 1.0)) + f)) * ((1.0 + d) * (f / 1.0)) } } +func f57(_ d: Double, _ f: CGFloat) { _ = { _ = ((1.0 + 1.0) - ((1.0 - 1.0) + ((.pi + d) / (1.0 * .pi.squareRoot())))) + ((.pi.squareRoot() / ((.pi.squareRoot() - .pi.squareRoot()) * (.pi * 1.0))) - (1.0 * .pi.squareRoot())) } } +func f58(_ d: Double, _ f: CGFloat) { _ = { _ = ((((.pi * 1.0) - 1.0) * d) * (((f - .pi.squareRoot()) - (.pi / f)) / ((d * 1.0) / d))) / ((((1.0 / d) / (1.0 + .pi.squareRoot())) + (1.0 + (1.0 * 1.0))) + (.pi / ((d * f) - (1.0 - 1.0)))) } } +func f59(_ d: Double, _ f: CGFloat) { _ = { _ = ((((1.0 / .pi.squareRoot()) + (1.0 / 1.0)) + f) / ((d * 1.0) / (1.0 - (.pi.squareRoot() + 1.0)))) / ((((.pi.squareRoot() - d) * (.pi.squareRoot() - .pi.squareRoot())) - ((f / 1.0) - d)) + ((f - (d / .pi)) / (.pi - (1.0 / 1.0)))) } } +func f60(_ d: Double, _ f: CGFloat) { _ = { _ = ((((1.0 - 1.0) + (f * 1.0)) / (d / (f / 1.0))) - ((1.0 - (1.0 * 1.0)) / ((1.0 / f) + (1.0 + f)))) * ((((.pi.squareRoot() * 1.0) * (d * d)) - (1.0 * (.pi.squareRoot() + f))) + ((1.0 + (.pi.squareRoot() - .pi.squareRoot())) * 1.0)) } } +func f61(_ d: Double, _ f: CGFloat) { _ = { _ = (((1.0 + .pi.squareRoot()) * .pi.squareRoot()) + (.pi.squareRoot() + .pi.squareRoot())) * (((1.0 - (f - 1.0)) + d) / (d / d)) } } +func f62(_ d: Double, _ f: CGFloat) { _ = { _ = (((1.0 * 1.0) / .pi) / (.pi + 1.0)) + (((f / (1.0 - d)) / ((f / 1.0) + f)) / (d * 1.0)) } } +func f63(_ d: Double, _ f: CGFloat) { _ = { _ = ((1.0 + .pi.squareRoot()) * (((f * 1.0) / (d + f)) * ((1.0 + d) - (1.0 * f)))) * ((.pi.squareRoot() * d) * (((1.0 - 1.0) / (d + d)) + (.pi - .pi.squareRoot()))) } } +func f64(_ d: Double, _ f: CGFloat) { _ = { _ = (((1.0 + 1.0) + (.pi.squareRoot() * 1.0)) + (.pi.squareRoot() - ((1.0 - 1.0) * 1.0))) + ((((f + f) / (.pi.squareRoot() * 1.0)) - ((1.0 - 1.0) + f)) * (((.pi - d) * .pi) / 1.0)) } } +func f65(_ d: Double, _ f: CGFloat) { _ = { _ = (((1.0 / (.pi.squareRoot() - 1.0)) / ((1.0 / 1.0) + d)) - (1.0 + (1.0 - (.pi.squareRoot() / f)))) - ((d + ((.pi.squareRoot() * .pi.squareRoot()) / (.pi.squareRoot() + d))) + (((d * d) * (f - 1.0)) - ((f / 1.0) - (.pi - 1.0)))) } } +func f66(_ d: Double, _ f: CGFloat) { _ = { _ = ((((1.0 + d) / (1.0 - f)) + (1.0 + 1.0)) - (((d - .pi) - 1.0) * 1.0)) * ((((d - 1.0) + (1.0 + f)) / ((1.0 / d) + (.pi.squareRoot() + d))) * (.pi.squareRoot() - ((f - .pi.squareRoot()) - (.pi.squareRoot() + 1.0)))) } } +func f67(_ d: Double, _ f: CGFloat) { _ = { _ = ((((1.0 + 1.0) - 1.0) + ((.pi * 1.0) - (.pi + 1.0))) - (((1.0 + .pi.squareRoot()) + (f + .pi)) * (f - f))) + ((((1.0 / 1.0) * d) + .pi.squareRoot()) + ((1.0 / (1.0 / .pi)) - ((1.0 / 1.0) * .pi.squareRoot()))) } } +func f68(_ d: Double, _ f: CGFloat) { _ = { _ = ((((.pi / 1.0) + 1.0) - f) / (1.0 / ((1.0 - f) / (1.0 - d)))) + ((.pi.squareRoot() - .pi) - (1.0 / 1.0)) } } +func f69(_ d: Double, _ f: CGFloat) { _ = { _ = ((((f - f) - (.pi.squareRoot() * .pi)) / (1.0 * (.pi * 1.0))) / (((1.0 / f) / (d * 1.0)) * (.pi + f))) * (((d * (1.0 - 1.0)) - .pi) / (1.0 - 1.0)) } } +func f70(_ d: Double, _ f: CGFloat) { _ = { _ = ((.pi.squareRoot() - d) + (1.0 - ((1.0 / 1.0) / .pi))) * (((.pi + (1.0 - .pi)) + ((1.0 * d) * (d / 1.0))) - (1.0 / ((.pi.squareRoot() / .pi) * f))) } } +func f71(_ d: Double, _ f: CGFloat) { _ = { _ = ((.pi - (.pi + f)) + (.pi / 1.0)) + (((.pi.squareRoot() - (f * 1.0)) / ((1.0 / 1.0) / (1.0 + f))) / (((f + f) * (1.0 - f)) / ((.pi.squareRoot() + f) * (1.0 * d)))) } } +func f72(_ d: Double, _ f: CGFloat) { _ = { _ = (((1.0 - .pi) / ((1.0 + 1.0) - (f + 1.0))) - (((.pi * .pi.squareRoot()) / (f + 1.0)) * ((1.0 + 1.0) + f))) + ((((.pi.squareRoot() + f) - (1.0 * .pi)) * ((1.0 / .pi) + (1.0 * d))) / ((.pi - (.pi.squareRoot() + d)) * ((1.0 + 1.0) + (1.0 - d)))) } } +func f73(_ d: Double, _ f: CGFloat) { _ = { _ = ((((1.0 + d) / (1.0 * d)) - f) - (((1.0 + d) / (1.0 * f)) * ((.pi.squareRoot() / .pi.squareRoot()) + (1.0 * 1.0)))) - ((((d - 1.0) - (1.0 + f)) / ((d * 1.0) / (d + d))) - (((.pi.squareRoot() * 1.0) / (.pi.squareRoot() / 1.0)) / (1.0 + (.pi.squareRoot() - .pi)))) } } +func f74(_ d: Double, _ f: CGFloat) { _ = { _ = ((.pi.squareRoot() / 1.0) / (((.pi.squareRoot() - .pi) + (.pi + 1.0)) - ((1.0 + 1.0) * 1.0))) / ((.pi.squareRoot() / .pi.squareRoot()) / (((1.0 + .pi) - (1.0 / f)) / (1.0 + (.pi.squareRoot() - 1.0)))) } } +func f75(_ d: Double, _ f: CGFloat) { _ = { _ = ((((.pi.squareRoot() * 1.0) - 1.0) + f) / (f + 1.0)) - ((((.pi.squareRoot() / .pi) * 1.0) / f) / (f - 1.0)) } } +func f76(_ d: Double, _ f: CGFloat) { _ = { _ = ((.pi.squareRoot() / ((d * .pi) * (f + f))) * (((.pi.squareRoot() * .pi.squareRoot()) / (1.0 + 1.0)) * ((1.0 - d) + (d + .pi.squareRoot())))) - ((((.pi + 1.0) / (1.0 + d)) + ((1.0 + 1.0) * (f - d))) - (f + .pi)) } } +func f77(_ d: Double, _ f: CGFloat) { _ = { _ = (((.pi - (1.0 / .pi)) * ((.pi.squareRoot() - .pi.squareRoot()) - d)) - (1.0 + ((.pi + d) + 1.0))) + (((d * (.pi - f)) - ((.pi.squareRoot() - 1.0) + (d - .pi))) - (.pi / ((d + 1.0) * (f - f)))) } } +func f78(_ d: Double, _ f: CGFloat) { _ = { _ = (((.pi / (f / 1.0)) + ((f / f) / .pi.squareRoot())) / (.pi * (.pi.squareRoot() - (.pi.squareRoot() + 1.0)))) + ((((.pi + 1.0) * f) - 1.0) / (((.pi.squareRoot() - .pi) * (.pi.squareRoot() + f)) - f)) } } +func f79(_ d: Double, _ f: CGFloat) { _ = { _ = ((d / (1.0 - (1.0 - 1.0))) + ((1.0 * 1.0) * ((1.0 / .pi.squareRoot()) * (.pi.squareRoot() * 1.0)))) * ((.pi.squareRoot() / 1.0) / (((1.0 / 1.0) / (1.0 / 1.0)) + ((f - .pi) - d))) } } +func f80(_ d: Double, _ f: CGFloat) { _ = { _ = ((1.0 * ((1.0 - 1.0) / 1.0)) + (((f - 1.0) * (.pi.squareRoot() - .pi.squareRoot())) / ((.pi + 1.0) / (1.0 - 1.0)))) - ((((.pi - 1.0) / (1.0 / .pi)) / ((d - 1.0) + (.pi - 1.0))) / (1.0 + (1.0 + (d - 1.0)))) } } +func f81(_ d: Double, _ f: CGFloat) { _ = { _ = ((.pi.squareRoot() * f) / ((1.0 + d) + ((1.0 + 1.0) - (1.0 * .pi.squareRoot())))) / (((.pi / (1.0 * 1.0)) / .pi) - (d * ((.pi / f) / (.pi.squareRoot() / .pi)))) } } +func f82(_ d: Double, _ f: CGFloat) { _ = { _ = ((((.pi + .pi.squareRoot()) / (.pi.squareRoot() * .pi)) + ((.pi + 1.0) - .pi)) + (((1.0 / .pi.squareRoot()) + 1.0) / ((.pi + 1.0) + (f + 1.0)))) - ((((f - .pi.squareRoot()) * (1.0 - f)) * ((1.0 + 1.0) / (.pi.squareRoot() - 1.0))) + ((.pi.squareRoot() / .pi) + ((.pi + 1.0) - (1.0 - 1.0)))) } } +func f83(_ d: Double, _ f: CGFloat) { _ = { _ = ((1.0 + (d / (f + f))) + (1.0 / f)) - ((((1.0 + .pi) - .pi.squareRoot()) + ((1.0 / .pi) - d)) - (1.0 - (d * (1.0 - d)))) } } +func f84(_ d: Double, _ f: CGFloat) { _ = { _ = ((d * .pi.squareRoot()) * (((1.0 + 1.0) - 1.0) * .pi)) * ((.pi - f) - ((1.0 - (.pi + 1.0)) * (1.0 - (f / 1.0)))) } } +func f85(_ d: Double, _ f: CGFloat) { _ = { _ = ((1.0 - d) / (.pi.squareRoot() + (1.0 - (1.0 - .pi)))) * ((((.pi - 1.0) + d) + f) * ((f * 1.0) - (1.0 - (d / d)))) } } +func f86(_ d: Double, _ f: CGFloat) { _ = { _ = ((f * (1.0 - 1.0)) / (.pi - d)) / ((((1.0 / .pi) + 1.0) / (f + (.pi.squareRoot() - .pi.squareRoot()))) - (1.0 + ((1.0 / .pi) + (1.0 * .pi)))) } } +func f87(_ d: Double, _ f: CGFloat) { _ = { _ = ((((1.0 - 1.0) + (1.0 * f)) + (1.0 * (d * .pi.squareRoot()))) - ((1.0 / (.pi.squareRoot() - 1.0)) + (1.0 - (1.0 - .pi)))) - ((.pi.squareRoot() + ((1.0 + 1.0) - (.pi * 1.0))) / (((1.0 * .pi.squareRoot()) * (1.0 + .pi)) * f)) } } +func f88(_ d: Double, _ f: CGFloat) { _ = { _ = (((d / (f + 1.0)) - ((1.0 - .pi) / (d * d))) - (((d - d) / (1.0 - f)) * ((d + d) + (d + 1.0)))) / ((.pi.squareRoot() + ((1.0 * 1.0) + (.pi.squareRoot() + 1.0))) * (((1.0 + f) - (.pi.squareRoot() / .pi)) + ((1.0 + .pi.squareRoot()) * (d * d)))) } } +func f89(_ d: Double, _ f: CGFloat) { _ = { _ = ((((1.0 / 1.0) / .pi) * (1.0 * (.pi + .pi))) - ((.pi * .pi) / 1.0)) + (((f - d) - ((1.0 / 1.0) + 1.0)) / ((.pi - 1.0) + 1.0)) } } +func f90(_ d: Double, _ f: CGFloat) { _ = { _ = ((((.pi + .pi.squareRoot()) * (.pi.squareRoot() + .pi.squareRoot())) * (1.0 / (1.0 / f))) + (((1.0 + d) * (.pi.squareRoot() / f)) - ((d - d) / (f * 1.0)))) - ((((.pi.squareRoot() - 1.0) + (1.0 * f)) + ((1.0 + d) * (.pi.squareRoot() - 1.0))) * ((1.0 / (.pi.squareRoot() - 1.0)) / ((1.0 - .pi.squareRoot()) - (f * 1.0)))) } } +func f91(_ d: Double, _ f: CGFloat) { _ = { _ = ((.pi / ((.pi * 1.0) / (.pi.squareRoot() + 1.0))) * (((.pi + d) / 1.0) - (f - (1.0 / f)))) - ((1.0 / (.pi.squareRoot() - (.pi.squareRoot() * f))) - (1.0 - ((f - 1.0) / (.pi.squareRoot() + 1.0)))) } } +func f92(_ d: Double, _ f: CGFloat) { _ = { _ = (((.pi - (.pi.squareRoot() + d)) + f) * (f / .pi)) * ((((.pi.squareRoot() / .pi.squareRoot()) / (1.0 + 1.0)) * 1.0) + (((1.0 + 1.0) * 1.0) * ((.pi - f) / .pi.squareRoot()))) } } +func f93(_ d: Double, _ f: CGFloat) { _ = { _ = ((((d + .pi.squareRoot()) * (d - d)) - (.pi * .pi)) - (f + ((1.0 - d) * (1.0 * .pi.squareRoot())))) - ((d * ((d - d) - (.pi.squareRoot() / 1.0))) - (((.pi.squareRoot() + .pi) * 1.0) + 1.0)) } } +func f94(_ d: Double, _ f: CGFloat) { _ = { _ = ((1.0 * ((d * 1.0) / .pi.squareRoot())) + (1.0 * ((d / .pi.squareRoot()) + .pi.squareRoot()))) + ((((1.0 - .pi) + 1.0) / 1.0) / (((1.0 - 1.0) * (.pi.squareRoot() - .pi.squareRoot())) / ((1.0 - d) - 1.0))) } } +func f95(_ d: Double, _ f: CGFloat) { _ = { _ = (((f - (.pi.squareRoot() - 1.0)) * d) / (d + ((1.0 / 1.0) - 1.0))) * ((((.pi.squareRoot() * 1.0) / (1.0 + .pi)) - 1.0) + (d * ((1.0 * 1.0) * .pi.squareRoot()))) } } +func f96(_ d: Double, _ f: CGFloat) { _ = { _ = ((((f / 1.0) + (d / .pi.squareRoot())) - .pi) * (((1.0 / f) - (1.0 + 1.0)) / 1.0)) * (((.pi / (.pi + .pi.squareRoot())) - ((f * 1.0) - (1.0 + 1.0))) / (((.pi + 1.0) * 1.0) - 1.0)) } } +func f97(_ d: Double, _ f: CGFloat) { _ = { _ = ((.pi.squareRoot() * ((1.0 - 1.0) - (1.0 / d))) * (((d - .pi.squareRoot()) / (1.0 * .pi)) / .pi)) + (((.pi - 1.0) + 1.0) - (.pi - ((.pi * 1.0) * (1.0 - .pi.squareRoot())))) } } +func f98(_ d: Double, _ f: CGFloat) { _ = { _ = (((1.0 - 1.0) + ((1.0 + d) + f)) * (((1.0 + f) - (1.0 + .pi.squareRoot())) / ((1.0 - 1.0) * (1.0 + 1.0)))) / ((d * (1.0 + (1.0 / d))) * (((1.0 / .pi) / (.pi * 1.0)) / (d + .pi.squareRoot()))) } } +func f99(_ d: Double, _ f: CGFloat) { _ = { _ = (((.pi * (f * .pi.squareRoot())) * (d * 1.0)) / (((1.0 * 1.0) / (d + d)) - f)) - ((f + 1.0) * (((.pi.squareRoot() / .pi.squareRoot()) + (f * .pi.squareRoot())) / (1.0 + (1.0 + 1.0)))) } } +func f100(_ d: Double, _ f: CGFloat) { _ = { _ = (((f * (1.0 - 1.0)) + (d - (1.0 + .pi))) / (((.pi + 1.0) * (1.0 - 1.0)) / .pi.squareRoot())) + ((1.0 * ((1.0 * 1.0) / (d * 1.0))) / (1.0 + ((f * .pi.squareRoot()) * (1.0 + 1.0)))) } } + diff --git a/validation-test/compiler_crashers_2_fixed/rdar87121502.swift b/validation-test/compiler_crashers_2_fixed/rdar87121502.swift deleted file mode 100644 index 864080e26591d..0000000000000 --- a/validation-test/compiler_crashers_2_fixed/rdar87121502.swift +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %target-swift-frontend -emit-ir -target %target-cpu-apple-macosx10.15 %s -// REQUIRES: OS=macosx - -protocol P {} - -func one() -> some P { - return two() -} - -func two() -> some P { - return three() -} - -func three() -> some P { - return one() -}