diff --git a/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/InitializeStaticGlobals.swift b/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/InitializeStaticGlobals.swift index 6f181f1339d95..530a508f2fc2b 100644 --- a/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/InitializeStaticGlobals.swift +++ b/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/InitializeStaticGlobals.swift @@ -80,11 +80,8 @@ private indirect enum GlobalInitValue { // For example, a struct or vector which is initialized by storing its elements. case aggregate([GlobalInitValue]) - // An enum case without a payload of an address-only enum. - case enumCase(caseIndex: Int) - - // An enum case which is not a SIL "constant", e.g. because it's address-only - case enumCaseWithPayload(caseIndex: Int, payload: GlobalInitValue) + // An enum with a payload which is not a SIL "constant". + case enumCase(caseIndex: Int, payload: GlobalInitValue) init?(of globalInitFunction: Function, _ context: FunctionPassContext) { self = .undefined @@ -136,26 +133,10 @@ private indirect enum GlobalInitValue { self = builder.initValue } - enum InitValue { - // The common case - case value(Value) - - // For payload-less cases of address-only enums. Such cases are initialized purely with an `inject_enum_addr`, - // and we don't have a `Value` which represents the resulting enum(-case). - case enumCaseWithoutPayload(InjectEnumAddrInst) - - var parentFunction: Function { - switch self { - case .value(let value): return value.parentFunction - case .enumCaseWithoutPayload(let iea): return iea.parentFunction - } - } - } - // Sets an element in the constant tree. // Returns true if this was successful. One reason for being not successful is if a certain // element is set twice, i.e. does not have a single defined value. - mutating func setElement(to value: InitValue, at path: SmallProjectionPath, type: Type) -> Bool { + mutating func setElement(to value: Value, at path: SmallProjectionPath, type: Type) -> Bool { let (kind, index, subPath) = path.pop() switch kind { case .root: @@ -163,17 +144,9 @@ private indirect enum GlobalInitValue { // The element was set twice. return false } - switch value { - case .value(let value): - self = .constant(value) - case .enumCaseWithoutPayload: - fatalError("should have been handled in the .enumCase of the SmallProjectionPath below") - } + self = .constant(value) return true - case .enumCase: - return setEnumCase(to: value, at: subPath, index: index, type: type) - case .structField: guard let structFields = type.getNominalFields(in: value.parentFunction) else { return false @@ -213,7 +186,7 @@ private indirect enum GlobalInitValue { } private mutating func setField( - to value: InitValue, at path: SmallProjectionPath, + to value: Value, at path: SmallProjectionPath, index: Int, type: Type, numFields: Int ) -> Bool { if case .undefined = self { @@ -232,43 +205,6 @@ private indirect enum GlobalInitValue { return false } - private mutating func setEnumCase(to value: InitValue, at path: SmallProjectionPath, index: Int, type: Type) -> Bool { - switch value { - - case .enumCaseWithoutPayload(let iea): - guard case .undefined = self else { - // The enum was set twice. - return false - } - assert(index == iea.caseIndex) - self = .enumCase(caseIndex: index) - - case .value: - guard let payloadType = type.getEnumCases(in: value.parentFunction)!.getPayloadType(ofCaseIndex: index) else { - return false - } - switch self { - case .undefined: - // It's the first time we set the payload or a sub-field of it. - var payload = GlobalInitValue.undefined - if !payload.setElement(to: value, at: path, type: payloadType) { - return false - } - self = .enumCaseWithPayload(caseIndex: index, payload: payload) - case .enumCaseWithPayload(let existingIndex, var payload) where index == existingIndex: - // Some sub-field of the enum-payload was already set. - self = .undefined // avoid copy-on-write - if !payload.setElement(to: value, at: path, type: payloadType) { - return false - } - self = .enumCaseWithPayload(caseIndex: index, payload: payload) - default: - return false - } - } - return true - } - /// Creates SIL for this global init value in the initializer of the `global`. func materialize(into global: GlobalVariable, from function: Function, _ context: FunctionPassContext) { var cloner = Cloner(cloneToGlobal: global, context) @@ -312,11 +248,8 @@ private indirect enum GlobalInitValue { } return builder.createVector(type: type, arguments: elementValues) - case .enumCase(let caseIndex): - return builder.createEnum(caseIndex: caseIndex, payload: nil, enumType: type) - - case .enumCaseWithPayload(let caseIndex, let payload): - let payloadType = type.getEnumCases(in: function)!.getPayloadType(ofCaseIndex: caseIndex)! + case .enumCase(let caseIndex, let payload): + let payloadType = type.getEnumCases(in: function)!.first(where: { $0.index == caseIndex })!.payload! let payloadValue = payload.materializeRecursively(type: payloadType, &cloner, builder, function) return builder.createEnum(caseIndex: caseIndex, payload: payloadValue, enumType: type) } @@ -339,7 +272,7 @@ private indirect enum GlobalInitValue { _ context: FunctionPassContext ) { switch self { - case .undefined, .enumCase: + case .undefined: break case .constant(let value): if value.containsLoad(context) { @@ -348,7 +281,7 @@ private indirect enum GlobalInitValue { self = .aggregate((value as! Instruction).operands.lazy.map { .constant($0.value) }) resolveLoadsRecursively(from: &stackValues, &resolvedAllocStacks, context) case let ei as EnumInst: - self = .enumCaseWithPayload(caseIndex: ei.caseIndex, payload: .constant(ei.payload!)) + self = .enumCase(caseIndex: ei.caseIndex, payload: .constant(ei.payload!)) resolveLoadsRecursively(from: &stackValues, &resolvedAllocStacks, context) case let li as LoadInst: guard let allocStack = li.address as? AllocStackInst, @@ -373,9 +306,10 @@ private indirect enum GlobalInitValue { newFields[i].resolveLoadsRecursively(from: &stackValues, &resolvedAllocStacks, context) } self = .aggregate(newFields) - case .enumCaseWithPayload(let caseIndex, var payload): - payload.resolveLoadsRecursively(from: &stackValues, &resolvedAllocStacks, context) - self = .enumCaseWithPayload(caseIndex: caseIndex, payload: payload) + case .enumCase(let caseIndex, let payload): + var newPayload = payload + newPayload.resolveLoadsRecursively(from: &stackValues, &resolvedAllocStacks, context) + self = .enumCase(caseIndex: caseIndex, payload: newPayload) } } @@ -387,9 +321,7 @@ private indirect enum GlobalInitValue { return value.isValidGlobalInitValue(context) case .aggregate(let fields): return fields.allSatisfy { $0.isValid(context) } - case .enumCase: - return true - case .enumCaseWithPayload(_, let payload): + case .enumCase(_, let payload): return payload.isValid(context) } } @@ -429,7 +361,7 @@ private struct InitValueBuilder: AddressDefUseWalker { let accessPath = store.destination.lookThroughRawLayoutAddress.constantAccessPath switch accessPath.base { case .global, .stack: - if !initValue.setElement(to: .value(store.source), at: accessPath.projectionPath, type: originalAddress.type) { + if !initValue.setElement(to: store.source, at: accessPath.projectionPath, type: originalAddress.type) { return .abortWalk } return .continueWalk @@ -444,35 +376,13 @@ private struct InitValueBuilder: AddressDefUseWalker { return .abortWalk } // The `nonConstAccessPath` now contains a single `.anyIndexedElement`. - if !initValue.setElement(to: .value(store.source), at: nonConstAccessPath.projectionPath, type: originalAddress.type) { + if !initValue.setElement(to: store.source, at: nonConstAccessPath.projectionPath, type: originalAddress.type) { return .abortWalk } return .continueWalk default: fatalError("could not compute access path") } - case let injectEnum as InjectEnumAddrInst: - if injectEnum.element.hasAssociatedValues { - if !injectEnum.operand.value.type.isLoadable(in: injectEnum.parentFunction) { - // TODO: we don't support non-loadable enum cases with payload yet, because IRGen support is missing. - // e.g. `var global: Atomic? = Atomic(0)` - // FixedTypeInfo (= used for non-loadable types) is missing the ability to pack a payload into an enum. - return .abortWalk - } - return .continueWalk - } - let accessPath = injectEnum.enum.getAccessPath(fromInitialPath: SmallProjectionPath(.enumCase, - index: injectEnum.caseIndex)) - switch accessPath.base { - case .global, .stack: - if !initValue.setElement(to: .enumCaseWithoutPayload(injectEnum), at: accessPath.projectionPath, type: originalAddress.type) { - return .abortWalk - } - return .continueWalk - default: - return .abortWalk - } - case is LoadInst, is DeallocStackInst: return .continueWalk case let bi as BuiltinInst: @@ -567,8 +477,6 @@ private extension Function { return false case let store as StoreInst: return !store.destination.lookThroughRawLayoutAddress.isAddressOfStack(orGlobal: global) - case let injectEnum as InjectEnumAddrInst: - return !injectEnum.enum.isAddressOfStack(orGlobal: global) case let bi as BuiltinInst where bi.id == .PrepareInitialization: return false default: @@ -625,9 +533,3 @@ private extension Value { return self } } - -private extension EnumCases { - func getPayloadType(ofCaseIndex caseIndex: Int) -> Type? { - return first(where: { $0.index == caseIndex })!.payload - } -} diff --git a/docs/RequestEvaluator.md b/docs/RequestEvaluator.md index 01e09b4309294..e1ce190e9bbfb 100644 --- a/docs/RequestEvaluator.md +++ b/docs/RequestEvaluator.md @@ -66,9 +66,8 @@ To define a request as a dependency source, it must implement an accessor for th ## Open Projects -The request-evaluator is relatively new to the Swift compiler, having been introduced in mid-2018. There are a number of improvements that can be made to the evaluator itself and how it is used in the compiler: +There are a number of improvements that can be made to the evaluator itself and how it is used in the compiler: -* The evaluator uses a `DenseMap` as its cache: we can almost certainly do better with per-request-kind caches that don't depend on so much type erasure. * Explore how best to cache data structures in the evaluator. For example, caching `std::vector` or `std::string` implies that we'll make copies of the underlying data structure each time we access the data. Could we automatically intern the data into an allocation arena owned by the evaluator, and vend `ArrayRef` and `StringRef` to clients instead? * Cycle diagnostics are far too complicated and produce very poor results. Consider replacing the current `diagnoseCycle`/`noteCycleStep` scheme with a single method that produces summary information (e.g., a short summary string + source location information) and provides richer diagnostics from that string. * The `isCached()` check to determine whether a specific instance of a request is worth caching may be at the wrong level, because one generally has to duplicate effort (or worse, code!) to make the decision in `isCached()`. Consider whether the `evaluator()` function could return something special to say "produce this value without caching" vs. the normal "produce this value with caching". diff --git a/include/swift/AST/ASTContext.h b/include/swift/AST/ASTContext.h index 8e582043fad25..6de9ab2c47e90 100644 --- a/include/swift/AST/ASTContext.h +++ b/include/swift/AST/ASTContext.h @@ -1626,6 +1626,10 @@ class ASTContext final { AvailabilityDomain getTargetAvailabilityDomain() const; }; +inline SourceLoc extractNearestSourceLoc(const ASTContext *ctx) { + return SourceLoc(); +} + } // end namespace swift #endif diff --git a/include/swift/AST/ASTDemangler.h b/include/swift/AST/ASTDemangler.h index 3218d5ed448b2..58bcf68281a23 100644 --- a/include/swift/AST/ASTDemangler.h +++ b/include/swift/AST/ASTDemangler.h @@ -158,6 +158,8 @@ class ASTBuilder { Type createBoundGenericType(GenericTypeDecl *decl, ArrayRef args); + OpaqueTypeDecl *resolveOpaqueTypeDecl(NodePointer opaqueDescriptor); + Type resolveOpaqueType(NodePointer opaqueDescriptor, ArrayRef> args, unsigned ordinal); diff --git a/include/swift/AST/Attr.h b/include/swift/AST/Attr.h index fc94b967ac3cf..3d010447b27f3 100644 --- a/include/swift/AST/Attr.h +++ b/include/swift/AST/Attr.h @@ -2344,6 +2344,8 @@ class CustomAttr final : public DeclAttribute { bool isEquivalent(const CustomAttr *other, Decl *attachedTo) const; + void printCustomAttr(ASTPrinter &Printer, const PrintOptions &Options) const; + private: friend class CustomAttrNominalRequest; void resetTypeInformation(TypeExpr *repr); diff --git a/include/swift/AST/DiagnosticsFrontend.def b/include/swift/AST/DiagnosticsFrontend.def index b9b2625c79a4c..71d808d191e7a 100644 --- a/include/swift/AST/DiagnosticsFrontend.def +++ b/include/swift/AST/DiagnosticsFrontend.def @@ -565,9 +565,6 @@ WARNING(module_incompatible_with_skip_function_bodies,none, "-experimental-skip-*-function-bodies* flags; they have " "been automatically disabled", (StringRef)) -WARNING(access_notes_file_io_error,none, - "ignored access notes file at '%0' because it cannot be read: %1", - (StringRef, StringRef)) WARNING(error_in_access_notes_file,none, "ignored access notes file because it cannot be parsed: %0", (StringRef)) diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index d1c289b390953..d7ffcbd2cdd0c 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -7856,6 +7856,10 @@ ERROR(atomics_ordering_must_be_constant, none, #define WHICH_ACCESS_NOTE(reason) "specified by access note for %" #reason +WARNING(access_notes_file_io_error,none, + "ignored access notes file at '%0' because it cannot be read: %1", + (StringRef, StringRef)) + REMARK(attr_added_by_access_note, none, "implicitly added '%1' to this %kindonly2, as " WHICH_ACCESS_NOTE(0), (StringRef, StringRef, const ValueDecl *)) diff --git a/include/swift/AST/Evaluator.h b/include/swift/AST/Evaluator.h index aeedf3ba2b297..e15f887f81a5a 100644 --- a/include/swift/AST/Evaluator.h +++ b/include/swift/AST/Evaluator.h @@ -22,6 +22,7 @@ #include "swift/AST/EvaluatorDependencies.h" #include "swift/AST/RequestCache.h" #include "swift/Basic/AnyValue.h" +#include "swift/Basic/Assertions.h" #include "swift/Basic/Debug.h" #include "swift/Basic/LangOptions.h" #include "swift/Basic/Statistic.h" @@ -208,6 +209,7 @@ class Evaluator { void enumerateReferencesInFile( const SourceFile *SF, evaluator::DependencyRecorder::ReferenceEnumerator f) const { + ASSERT(recorder.isRecordingEnabled() && "Dep recording should be enabled"); return recorder.enumerateReferencesInFile(SF, f); } @@ -414,6 +416,8 @@ class Evaluator { typename std::enable_if::type * = nullptr> void handleDependencySinkRequest(const Request &r, const typename Request::OutputType &o) { + if (!recorder.isRecordingEnabled()) + return; evaluator::DependencyCollector collector(recorder); r.writeDependencySink(collector, o); } @@ -425,6 +429,8 @@ class Evaluator { template ::type * = nullptr> void handleDependencySourceRequest(const Request &r) { + if (!recorder.isRecordingEnabled()) + return; auto source = r.readDependencySource(recorder); if (!source.isNull() && source.get()->isPrimary()) { recorder.handleDependencySourceRequest(r, source.get()); diff --git a/include/swift/AST/EvaluatorDependencies.h b/include/swift/AST/EvaluatorDependencies.h index 89fc27441c888..91fcf8cd9d1b1 100644 --- a/include/swift/AST/EvaluatorDependencies.h +++ b/include/swift/AST/EvaluatorDependencies.h @@ -94,6 +94,9 @@ class DependencyRecorder { public: DependencyRecorder(bool shouldRecord) : shouldRecord(shouldRecord) {} + /// Whether dependency recording is enabled. + bool isRecordingEnabled() const { return shouldRecord; } + /// Push a new empty set onto the activeRequestReferences stack. template void beginRequest(); diff --git a/include/swift/AST/Module.h b/include/swift/AST/Module.h index bbdf9acc4c691..9c78b062eb3f5 100644 --- a/include/swift/AST/Module.h +++ b/include/swift/AST/Module.h @@ -345,8 +345,6 @@ class ModuleDecl /// \see EntryPointInfoTy EntryPointInfoTy EntryPointInfo; - AccessNotesFile accessNotes; - /// Used by the debugger to bypass resilient access to fields. bool BypassResilience = false; @@ -415,8 +413,9 @@ class ModuleDecl /// imports. ImplicitImportList getImplicitImports() const; - AccessNotesFile &getAccessNotes() { return accessNotes; } - const AccessNotesFile &getAccessNotes() const { return accessNotes; } + /// Retrieve the access notes to apply for the module, or \c nullptr if there + /// are no access notes. + const AccessNotesFile *getAccessNotes() const; /// Return whether the module was imported with resilience disabled. The /// debugger does this to access private fields. diff --git a/include/swift/AST/TypeCheckRequests.h b/include/swift/AST/TypeCheckRequests.h index c4c47aa5a5333..00c3fcdfc3325 100644 --- a/include/swift/AST/TypeCheckRequests.h +++ b/include/swift/AST/TypeCheckRequests.h @@ -4089,6 +4089,31 @@ class PrimarySourceFilesRequest bool isCached() const { return true; } }; +/// Load the access notes to apply for the main module. +/// +/// Note this is keyed on the ASTContext instead of the ModuleDecl to avoid +/// needing to re-load the access notes in cases where we have multiple main +/// modules, e.g when doing cached top-level code completion. +/// +/// FIXME: This isn't really a type-checking request, if we ever split off a +/// zone for more general requests, this should be moved there. +class LoadAccessNotesRequest + : public SimpleRequest { +public: + using SimpleRequest::SimpleRequest; + +private: + friend SimpleRequest; + + const AccessNotesFile *evaluate(Evaluator &evaluator, ASTContext *ctx) const; + +public: + // Cached. + bool isCached() const { return true; } +}; + /// Kinds of types for CustomAttr. enum class CustomAttrTypeKind { /// The type is required to not be expressed in terms of diff --git a/include/swift/AST/TypeCheckerTypeIDZone.def b/include/swift/AST/TypeCheckerTypeIDZone.def index 090b6a9bd79e6..dbb8e382756a0 100644 --- a/include/swift/AST/TypeCheckerTypeIDZone.def +++ b/include/swift/AST/TypeCheckerTypeIDZone.def @@ -275,6 +275,8 @@ SWIFT_REQUEST(TypeChecker, PatternBindingCheckedAndContextualizedInitRequest, SeparatelyCached, NoLocationInfo) SWIFT_REQUEST(TypeChecker, PrimarySourceFilesRequest, ArrayRef(ModuleDecl *), Cached, NoLocationInfo) +SWIFT_REQUEST(TypeChecker, LoadAccessNotesRequest, + const AccessNotesFile *(ASTContext *), Cached, NoLocationInfo) SWIFT_REQUEST(TypeChecker, PropertyWrapperAuxiliaryVariablesRequest, PropertyWrapperAuxiliaryVariables(VarDecl *), SeparatelyCached | SplitCached, diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index 2e8e49ad79113..cfd593e18112f 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -493,6 +493,9 @@ namespace swift { std::shared_ptr OptimizationRemarkPassedPattern; std::shared_ptr OptimizationRemarkMissedPattern; + /// The path to load access notes from. + std::string AccessNotesPath; + /// How should we emit diagnostics about access notes? AccessNoteDiagnosticBehavior AccessNoteBehavior = AccessNoteDiagnosticBehavior::RemarkOnFailureOrSuccess; diff --git a/include/swift/Frontend/Frontend.h b/include/swift/Frontend/Frontend.h index 00c348ea070b2..9459134f6b8f5 100644 --- a/include/swift/Frontend/Frontend.h +++ b/include/swift/Frontend/Frontend.h @@ -790,11 +790,6 @@ class CompilerInstance { /// Parses and type-checks all input files. void performSema(); - /// Loads any access notes for the main module. - /// - /// FIXME: This should be requestified. - void loadAccessNotesIfNeeded(); - /// Parses and performs import resolution on all input files. /// /// This is similar to a parse-only invocation, but module imports will also diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h index 2400309f9eff8..eee71255c1392 100644 --- a/include/swift/Frontend/FrontendOptions.h +++ b/include/swift/Frontend/FrontendOptions.h @@ -107,9 +107,6 @@ class FrontendOptions { /// The path to which we should store indexing data, if any. std::string IndexStorePath; - /// The path to load access notes from. - std::string AccessNotesPath; - /// The path to look in when loading a module interface file, to see if a /// binary module has already been built for use by the compiler. std::string PrebuiltModuleCachePath; diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h index 4d6c58ae69240..a930617945f5c 100644 --- a/include/swift/Parse/Parser.h +++ b/include/swift/Parse/Parser.h @@ -574,7 +574,11 @@ class Parser { /// the '(' by a space. /// /// If the next token is not '(' or it's on a new line, return false. - bool consumeIfAttributeLParen(); + bool consumeIfAttributeLParen(bool isCustomAttr = false); + + /// Check if the current token is '(' and it looks like a start of an + /// attribute argument list. + bool isAtAttributeLParen(bool isCustomAttr = false); bool consumeIfNotAtStartOfLine(tok K) { if (Tok.isAtStartOfLine()) return false; @@ -1147,7 +1151,6 @@ class Parser { SourceLoc AtEndLoc, bool isFromClangAttribute = false); - bool isCustomAttributeArgument(); bool canParseCustomAttribute(); /// Parse a custom attribute after the initial '@'. diff --git a/lib/APIDigester/ModuleAnalyzerNodes.cpp b/lib/APIDigester/ModuleAnalyzerNodes.cpp index c794e7b322dcb..8ede7cfb0cbd7 100644 --- a/lib/APIDigester/ModuleAnalyzerNodes.cpp +++ b/lib/APIDigester/ModuleAnalyzerNodes.cpp @@ -1988,7 +1988,7 @@ SwiftDeclCollector::addConformancesToTypeDecl(SDKNodeDeclType *Root, } else { // Avoid adding the same conformance twice. SmallPtrSet Seen; - for (auto &Conf: NTD->getAllConformances()) { + for (auto &Conf: NTD->getAllConformances(/*sorted=*/true)) { if (!Ctx.shouldIgnore(Conf->getProtocol()) && !Seen.count(Conf)) Root->addConformance(constructConformanceNode(Conf)); Seen.insert(Conf); diff --git a/lib/AST/ASTDemangler.cpp b/lib/AST/ASTDemangler.cpp index b7900ee2723da..65e846435d357 100644 --- a/lib/AST/ASTDemangler.cpp +++ b/lib/AST/ASTDemangler.cpp @@ -332,8 +332,7 @@ Type ASTBuilder::createTypeAliasType(GenericTypeDecl *decl, Type parent) { static SubstitutionMap createSubstitutionMapFromGenericArgs(GenericSignature genericSig, - ArrayRef args, - LookupConformanceFn lookupConformance) { + ArrayRef args) { if (!genericSig) return SubstitutionMap(); @@ -341,15 +340,7 @@ createSubstitutionMapFromGenericArgs(GenericSignature genericSig, return SubstitutionMap(); return SubstitutionMap::get( - genericSig, - [&](SubstitutableType *t) -> Type { - auto *gp = cast(t); - unsigned ordinal = genericSig->getGenericParamOrdinal(gp); - if (ordinal < args.size()) - return args[ordinal]; - return Type(); - }, - lookupConformance); + genericSig, args, LookUpConformanceInModule()); } Type ASTBuilder::createBoundGenericType(GenericTypeDecl *decl, @@ -364,8 +355,7 @@ Type ASTBuilder::createBoundGenericType(GenericTypeDecl *decl, // Build a SubstitutionMap. auto genericSig = nominalDecl->getGenericSignature(); - auto subs = createSubstitutionMapFromGenericArgs( - genericSig, args, LookUpConformanceInModule()); + auto subs = createSubstitutionMapFromGenericArgs(genericSig, args); if (!subs) return Type(); auto origType = nominalDecl->getDeclaredInterfaceType(); @@ -375,48 +365,53 @@ Type ASTBuilder::createBoundGenericType(GenericTypeDecl *decl, return origType.subst(subs); } -Type ASTBuilder::resolveOpaqueType(NodePointer opaqueDescriptor, - ArrayRef> args, - unsigned ordinal) { - if (opaqueDescriptor->getKind() == Node::Kind::OpaqueReturnTypeOf) { - auto definingDecl = opaqueDescriptor->getChild(0); - auto definingGlobal = Factory.createNode(Node::Kind::Global); - definingGlobal->addChild(definingDecl, Factory); - auto mangling = mangleNode(definingGlobal, ManglingFlavor); - if (!mangling.isSuccess()) - return Type(); - auto mangledName = mangling.result(); +OpaqueTypeDecl *ASTBuilder::resolveOpaqueTypeDecl(NodePointer opaqueDescriptor) { + if (opaqueDescriptor->getKind() != Node::Kind::OpaqueReturnTypeOf) + return nullptr; - auto moduleNode = findModuleNode(definingDecl); - if (!moduleNode) - return Type(); + auto definingDecl = opaqueDescriptor->getChild(0); + auto definingGlobal = Factory.createNode(Node::Kind::Global); + definingGlobal->addChild(definingDecl, Factory); + auto mangling = mangleNode(definingGlobal, ManglingFlavor); + if (!mangling.isSuccess()) + return nullptr; + auto mangledName = mangling.result(); - ModuleDecl *scratch; - auto potentialParentModules = findPotentialModules(moduleNode, scratch); - if (potentialParentModules.empty()) - return Type(); + auto moduleNode = findModuleNode(definingDecl); + if (!moduleNode) + return nullptr; - OpaqueTypeDecl *opaqueDecl = nullptr; - for (auto module : potentialParentModules) - if (auto decl = module->lookupOpaqueResultType(mangledName)) - opaqueDecl = decl; + ModuleDecl *scratch; + auto potentialParentModules = findPotentialModules(moduleNode, scratch); + if (potentialParentModules.empty()) + return nullptr; - if (!opaqueDecl) - return Type(); - SmallVector allArgs; - for (auto argSet : args) { - allArgs.append(argSet.begin(), argSet.end()); - } + for (auto module : potentialParentModules) + if (auto decl = module->lookupOpaqueResultType(mangledName)) + return decl; + + return nullptr; +} + +Type ASTBuilder::resolveOpaqueType(NodePointer opaqueDescriptor, + ArrayRef> args, + unsigned ordinal) { + OpaqueTypeDecl *opaqueDecl = resolveOpaqueTypeDecl(opaqueDescriptor); + if (!opaqueDecl) + return Type(); - SubstitutionMap subs = createSubstitutionMapFromGenericArgs( - opaqueDecl->getGenericSignature(), allArgs, - LookUpConformanceInModule()); - Type interfaceType = opaqueDecl->getOpaqueGenericParams()[ordinal]; - return OpaqueTypeArchetypeType::get(opaqueDecl, interfaceType, subs); + SmallVector allArgs; + for (auto argSet : args) { + allArgs.append(argSet.begin(), argSet.end()); } - - // TODO: named opaque types - return Type(); + + if (ordinal >= opaqueDecl->getOpaqueGenericParams().size()) + return Type(); + + SubstitutionMap subs = createSubstitutionMapFromGenericArgs( + opaqueDecl->getGenericSignature(), allArgs); + Type interfaceType = opaqueDecl->getOpaqueGenericParams()[ordinal]; + return OpaqueTypeArchetypeType::get(opaqueDecl, interfaceType, subs); } Type ASTBuilder::createBoundGenericType(GenericTypeDecl *decl, @@ -1143,8 +1138,7 @@ Type ASTBuilder::createSILBoxTypeWithLayout( SubstitutionMap substs; if (signature) substs = createSubstitutionMapFromGenericArgs( - signature, replacements, - LookUpConformanceInModule()); + signature, replacements); return SILBoxType::get(Ctx, layout, substs); } diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index d23bcd445deec..a0bcf90e07d4b 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -1103,6 +1103,8 @@ class PrintAST : public ASTVisitor { void printRequirement(const InverseRequirement &inverse, bool forInherited); + void printArgumentList(ArgumentList *args, bool forSubscript = false); + private: bool shouldPrint(const Decl *D, bool Notify = false); bool shouldPrintPattern(const Pattern *P); @@ -1138,8 +1140,6 @@ class PrintAST : public ASTVisitor { void printFunctionParameters(AbstractFunctionDecl *AFD); void printArgument(const Argument &arg); - - void printArgumentList(ArgumentList *args, bool forSubscript = false); void printAvailabilitySpec(AvailabilitySpec *spec); @@ -4843,6 +4843,19 @@ void PrintAST::visitMacroExpansionDecl(MacroExpansionDecl *decl) { Printer << ')'; } +void CustomAttr::printCustomAttr(ASTPrinter &Printer, const PrintOptions &Options) const { + Printer.callPrintNamePre(PrintNameContext::Attribute); + Printer << "@"; + if (auto type = getType()) + type.print(Printer, Options); + else + getTypeRepr()->print(Printer, Options); + Printer.printNamePost(PrintNameContext::Attribute); + if (hasArgs() && Options.PrintExprs) { + PrintAST(Printer, Options).printArgumentList(argList); + } +} + void PrintAST::visitIntegerLiteralExpr(IntegerLiteralExpr *expr) { Printer << expr->getDigitsText(); } @@ -7515,10 +7528,37 @@ class TypePrinter : public TypeVisitorgetASTContext(), - genericSig.getGenericParams(), - T->getSubstitutions().getReplacementTypes()); + auto &ctx = decl->getASTContext(); + auto params = genericSig.getGenericParams(); + auto args = T->getSubstitutions().getReplacementTypes(); + + // Use the new "nested" syntax if there is at least one parameter pack, + // because that case didn't round trip at all before anyway. Otherwise, + // use the old "flat" syntax, even when the owner declaration is in a + // nested generic context, because we want the generated swiftinterface + // to continue to work on old compilers. + if (genericSig->hasParameterPack()) { + bool first = true; + + while (!params.empty()) { + if (!first) { Printer << ".__"; } + first = false; + + unsigned end = 1; + unsigned depth = params.front()->getDepth(); + while (end < params.size() && params[end]->getDepth() == depth) { + ++end; + } + + printGenericArgs(ctx, params.take_front(end), args.take_front(end)); + params = params.slice(end); + args = args.slice(end); + } + } else { + printGenericArgs(ctx, params, args); + } } + return; } case PrintOptions::OpaqueReturnTypePrintingMode::Description: { diff --git a/lib/AST/Attr.cpp b/lib/AST/Attr.cpp index 0e0daf7154bfa..412d4b659b8d6 100644 --- a/lib/AST/Attr.cpp +++ b/lib/AST/Attr.cpp @@ -1453,14 +1453,8 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options, } case DeclAttrKind::Custom: { - Printer.callPrintNamePre(PrintNameContext::Attribute); - Printer << "@"; auto *attr = cast(this); - if (auto type = attr->getType()) - type.print(Printer, Options); - else - attr->getTypeRepr()->print(Printer, Options); - Printer.printNamePost(PrintNameContext::Attribute); + attr->printCustomAttr(Printer, Options); break; } diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp index ed35eca070ffe..d4098f394a284 100644 --- a/lib/AST/Module.cpp +++ b/lib/AST/Module.cpp @@ -823,6 +823,16 @@ ImplicitImportList ModuleDecl::getImplicitImports() const { {}); } +const AccessNotesFile *ModuleDecl::getAccessNotes() const { + // Only the main module has access notes. + if (!isMainModule()) + return nullptr; + + auto &ctx = getASTContext(); + return evaluateOrDefault(ctx.evaluator, LoadAccessNotesRequest{&ctx}, + nullptr); +} + SourceFile *ModuleDecl::getSourceFileContainingLocation(SourceLoc loc) { if (loc.isInvalid()) return nullptr; diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index 3b4c076227277..2115f6b6dc398 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -9421,6 +9421,8 @@ void ClangImporter::Implementation::addOptionSetTypealiases( selfType); } +#define SIW_DBG(x) DEBUG_WITH_TYPE("safe-interop-wrappers", llvm::dbgs() << x) + void ClangImporter::Implementation::swiftify(AbstractFunctionDecl *MappedDecl) { if (!SwiftContext.LangOpts.hasFeature(Feature::SafeInteropWrappers)) return; @@ -9428,6 +9430,7 @@ void ClangImporter::Implementation::swiftify(AbstractFunctionDecl *MappedDecl) { dyn_cast_or_null(MappedDecl->getClangDecl()); if (!ClangDecl) return; + SIW_DBG("Checking " << *ClangDecl << " for bounds and lifetime info\n"); // FIXME: for private macro generated functions we do not serialize the // SILFunction's body anywhere triggering assertions. @@ -9483,11 +9486,13 @@ void ClangImporter::Implementation::swiftify(AbstractFunctionDecl *MappedDecl) { auto *CAT = ClangDecl->getReturnType()->getAs(); if (SwiftifiableCAT(getClangASTContext(), CAT, swiftReturnTy)) { printer.printCountedBy(CAT, SwiftifyInfoPrinter::RETURN_VALUE_INDEX); + SIW_DBG(" Found bounds info '" << clang::QualType(CAT, 0) << "' on return value\n"); attachMacro = true; } bool returnHasLifetimeInfo = false; if (SwiftDeclConverter::getImplicitObjectParamAnnotation< clang::LifetimeBoundAttr>(ClangDecl)) { + SIW_DBG(" Found lifetimebound attribute on implicit 'this'\n"); printer.printLifetimeboundReturn(SwiftifyInfoPrinter::SELF_PARAM_INDEX, true); returnHasLifetimeInfo = true; @@ -9500,6 +9505,8 @@ void ClangImporter::Implementation::swiftify(AbstractFunctionDecl *MappedDecl) { auto *CAT = clangParamTy->getAs(); if (SwiftifiableCAT(getClangASTContext(), CAT, swiftParamTy)) { printer.printCountedBy(CAT, index); + SIW_DBG(" Found bounds info '" << clangParamTy + << "' on parameter '" << *clangParam << "'\n"); attachMacro = paramHasBoundsInfo = true; } bool paramIsStdSpan = registerStdSpanTypeMapping( @@ -9508,10 +9515,13 @@ void ClangImporter::Implementation::swiftify(AbstractFunctionDecl *MappedDecl) { bool paramHasLifetimeInfo = false; if (clangParam->hasAttr()) { + SIW_DBG(" Found noescape attribute on parameter '" << *clangParam << "'\n"); printer.printNonEscaping(index); paramHasLifetimeInfo = true; } if (clangParam->hasAttr()) { + SIW_DBG(" Found lifetimebound attribute on parameter '" + << *clangParam << "'\n"); // If this parameter has bounds info we will tranform it into a Span, // so then it will no longer be Escapable. bool willBeEscapable = swiftParamTy->isEscapable() && !paramHasBoundsInfo; @@ -9519,17 +9529,23 @@ void ClangImporter::Implementation::swiftify(AbstractFunctionDecl *MappedDecl) { paramHasLifetimeInfo = true; returnHasLifetimeInfo = true; } - if (paramIsStdSpan && paramHasLifetimeInfo) + if (paramIsStdSpan && paramHasLifetimeInfo) { + SIW_DBG(" Found both std::span and lifetime info " + "for parameter '" << *clangParam << "'\n"); attachMacro = true; + } } - if (returnIsStdSpan && returnHasLifetimeInfo) + if (returnIsStdSpan && returnHasLifetimeInfo) { + SIW_DBG(" Found both std::span and lifetime info for return value\n"); attachMacro = true; + } printer.printAvailability(); printer.printTypeMapping(typeMapping); } if (attachMacro) { + SIW_DBG("Attaching safe interop macro: " << MacroString << "\n"); if (clang::RawComment *raw = getClangASTContext().getRawCommentForDeclNoCache(ClangDecl)) { // swift::RawDocCommentAttr doesn't contain its text directly, but instead @@ -9549,6 +9565,7 @@ void ClangImporter::Implementation::swiftify(AbstractFunctionDecl *MappedDecl) { } } } +#undef SIW_DBG static bool isUsingMacroName(clang::SourceManager &SM, clang::SourceLocation loc, diff --git a/lib/ClangImporter/ImportMacro.cpp b/lib/ClangImporter/ImportMacro.cpp index a932ba05cc55e..ada666b6b8612 100644 --- a/lib/ClangImporter/ImportMacro.cpp +++ b/lib/ClangImporter/ImportMacro.cpp @@ -333,12 +333,16 @@ getIntegerConstantForMacroToken(ClangImporter::Implementation &impl, } // Macro identifier. - // TODO: for some reason when in C++ mode, "hasMacroDefinition" is often - // false: rdar://110071334 - } else if (token.is(clang::tok::identifier) && - token.getIdentifierInfo()->hasMacroDefinition()) { + } else if (token.is(clang::tok::identifier)) { auto rawID = token.getIdentifierInfo(); + + // When importing in (Objective-)C++ language mode, sometimes a macro might + // have an outdated identifier info, which would cause Clang preprocessor to + // assume that it does not have a definition. + if (rawID->isOutOfDate()) + (void)impl.getClangPreprocessor().getLeafModuleMacros(rawID); + auto definition = impl.getClangPreprocessor().getMacroDefinition(rawID); if (!definition) return std::nullopt; diff --git a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp index 79dc8da457bd8..ecbcfbd3d44d1 100644 --- a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp +++ b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp @@ -372,9 +372,6 @@ bool ArgsToFrontendOptionsConverter::convert( if (!computeModuleAliases()) return true; - if (const Arg *A = Args.getLastArg(OPT_access_notes_path)) - Opts.AccessNotesPath = A->getValue(); - if (const Arg *A = Args.getLastArg(OPT_serialize_debugging_options, OPT_no_serialize_debugging_options)) { Opts.SerializeOptionsForDebugging = diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 8b8f4b419cba3..8116eaa657799 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1423,6 +1423,9 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, Opts.OptimizationRemarkMissedPattern = generateOptimizationRemarkRegex(Diags, Args, A); + if (const Arg *A = Args.getLastArg(OPT_access_notes_path)) + Opts.AccessNotesPath = A->getValue(); + if (Arg *A = Args.getLastArg(OPT_Raccess_note)) { auto value = llvm::StringSwitch>( diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index f6d287241c281..5ce141e45a407 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -308,6 +308,16 @@ void CompilerInstance::recordPrimaryInputBuffer(unsigned BufID) { PrimaryBufferIDs.insert(BufID); } +static bool shouldEnableRequestReferenceTracking(const CompilerInstance &CI) { + // Enable request reference dependency tracking when we're either writing + // dependencies for incremental mode, verifying dependencies, or collecting + // stats. + auto &opts = CI.getInvocation().getFrontendOptions(); + return opts.InputsAndOutputs.hasReferenceDependenciesFilePath() || + opts.EnableIncrementalDependencyVerifier || + !opts.StatsOutputDir.empty(); +} + bool CompilerInstance::setUpASTContextIfNeeded() { if (FrontendOptions::doesActionBuildModuleFromInterface( Invocation.getFrontendOptions().RequestedAction) && @@ -318,10 +328,8 @@ bool CompilerInstance::setUpASTContextIfNeeded() { return false; } - // For the time being, we only need to record dependencies in batch mode - // and single file builds. - Invocation.getLangOptions().RecordRequestReferences - = !isWholeModuleCompilation(); + Invocation.getLangOptions().RecordRequestReferences = + shouldEnableRequestReferenceTracking(*this); Context.reset(ASTContext::get( Invocation.getLangOptions(), Invocation.getTypeCheckerOptions(), @@ -1556,28 +1564,6 @@ void CompilerInstance::setMainModule(ModuleDecl *newMod) { Context->MainModule = newMod; } -void CompilerInstance::loadAccessNotesIfNeeded() { - if (Invocation.getFrontendOptions().AccessNotesPath.empty()) - return; - - auto *mainModule = getMainModule(); - - auto accessNotesPath = Invocation.getFrontendOptions().AccessNotesPath; - - auto bufferOrError = - swift::vfs::getFileOrSTDIN(getFileSystem(), accessNotesPath); - if (bufferOrError) { - int sourceID = SourceMgr.addNewSourceBuffer(std::move(bufferOrError.get())); - auto buffer = SourceMgr.getLLVMSourceMgr().getMemoryBuffer(sourceID); - - if (auto accessNotesFile = AccessNotesFile::load(*Context, buffer)) - mainModule->getAccessNotes() = *accessNotesFile; - } else { - Diagnostics.diagnose(SourceLoc(), diag::access_notes_file_io_error, - accessNotesPath, bufferOrError.getError().message()); - } -} - bool CompilerInstance::performParseAndResolveImportsOnly() { FrontendStatsTracer tracer(getStatsReporter(), "parse-and-resolve-imports"); @@ -1585,9 +1571,6 @@ bool CompilerInstance::performParseAndResolveImportsOnly() { // lazily evaluate instead. Once the below computations are requestified we // ought to be able to remove this function. - // Load access notes. - loadAccessNotesIfNeeded(); - // Resolve imports for all the source files in the module. auto *mainModule = getMainModule(); performImportResolution(mainModule); diff --git a/lib/IDETool/IDEInspectionInstance.cpp b/lib/IDETool/IDEInspectionInstance.cpp index 107f7974f4d55..d54070998be36 100644 --- a/lib/IDETool/IDEInspectionInstance.cpp +++ b/lib/IDETool/IDEInspectionInstance.cpp @@ -517,7 +517,6 @@ void IDEInspectionInstance::performNewOperation( CI->getASTContext().CancellationFlag = CancellationFlag; registerIDERequestFunctions(CI->getASTContext().evaluator); - CI->loadAccessNotesIfNeeded(); performImportResolution(CI->getMainModule()); bool DidFindIDEInspectionTarget = CI->getIDEInspectionFile() diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp index a28d1cac7b37a..71305d2382ce1 100644 --- a/lib/IRGen/GenDecl.cpp +++ b/lib/IRGen/GenDecl.cpp @@ -1065,7 +1065,7 @@ void IRGenModule::SetCStringLiteralSection(llvm::GlobalVariable *GV, GV->setSection("__TEXT,__objc_methtype,cstring_literals"); return; case ObjCLabelType::PropertyName: - GV->setSection("__TEXT,__cstring,cstring_literals"); + GV->setSection("__TEXT,__objc_methname,cstring_literals"); return; } case llvm::Triple::ELF: diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp index f7a2d0225348e..029edac50bd8a 100644 --- a/lib/IRGen/GenMeta.cpp +++ b/lib/IRGen/GenMeta.cpp @@ -581,8 +581,7 @@ namespace { void addGenericParameters() { GenericSignature sig = asImpl().getGenericSignature(); auto metadata = - irgen::addGenericParameters(IGM, B, - asImpl().getGenericSignature(), + irgen::addGenericParameters(IGM, B, sig, /*implicit=*/false); assert(metadata.NumParams == metadata.NumParamsEmitted && "We can't use implicit GenericParamDescriptors here"); diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 4db0c4542905a..df30a796c4d30 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -877,7 +877,7 @@ bool Parser::parseSpecializeAttribute( assert(ClosingBrace == tok::r_paren || ClosingBrace == tok::r_square); SourceLoc lParenLoc; - if (Tok.is(tok::l_paren)) { + if (isAtAttributeLParen()) { lParenLoc = consumeAttributeLParen(); } else { // SIL parsing is positioned at _specialize when entering this and parses @@ -2261,7 +2261,7 @@ Parser::parseMacroRoleAttribute( break; } - if (!Tok.isFollowingLParen()) { + if (!isAtAttributeLParen()) { diagnose(Tok, diag::attr_expected_lparen, attrName, false); return makeParserError(); } @@ -2503,7 +2503,7 @@ static std::optional parseSingleAttrOptionImpl( }; bool isDeclModifier = DeclAttribute::isDeclModifier(DK); - if (!P.Tok.isFollowingLParen()) { + if (!P.isAtAttributeLParen()) { if (allowOmitted) return Identifier(); @@ -2883,7 +2883,7 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes, .Case("public", AccessLevel::Public) .Case("open", AccessLevel::Open); - if (!Tok.isFollowingLParen()) { + if (!isAtAttributeLParen()) { // Normal access control attribute. AttrRange = Loc; @@ -3467,7 +3467,7 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes, } case DeclAttrKind::PrivateImport: { // Parse the leading '('. - if (!Tok.isFollowingLParen()) { + if (!isAtAttributeLParen()) { diagnose(Loc, diag::attr_expected_lparen, AttrName, DeclAttribute::isDeclModifier(DK)); return makeParserSuccess(); @@ -3516,7 +3516,7 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes, } case DeclAttrKind::ObjC: { // Unnamed @objc attribute. - if (!Tok.isFollowingLParen()) { + if (!isAtAttributeLParen()) { auto attr = ObjCAttr::createUnnamed(Context, AtLoc, Loc); Attributes.add(attr); break; @@ -3584,7 +3584,7 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes, case DeclAttrKind::DynamicReplacement: { // Parse the leading '('. - if (!Tok.isFollowingLParen()) { + if (!isAtAttributeLParen()) { diagnose(Loc, diag::attr_expected_lparen, AttrName, DeclAttribute::isDeclModifier(DK)); return makeParserSuccess(); @@ -3635,7 +3635,7 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes, case DeclAttrKind::TypeEraser: { // Parse leading '(' - if (!Tok.isFollowingLParen()) { + if (!isAtAttributeLParen()) { diagnose(Loc, diag::attr_expected_lparen, AttrName, DeclAttribute::isDeclModifier(DK)); return makeParserSuccess(); @@ -3665,7 +3665,7 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes, case DeclAttrKind::Specialize: case DeclAttrKind::Specialized: { - if (!Tok.isFollowingLParen()) { + if (!isAtAttributeLParen()) { diagnose(Loc, diag::attr_expected_lparen, AttrName, DeclAttribute::isDeclModifier(DK)); return makeParserSuccess(); @@ -3894,7 +3894,7 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes, break; } case DeclAttrKind::RawLayout: { - if (!Tok.isFollowingLParen()) { + if (!isAtAttributeLParen()) { diagnose(Loc, diag::attr_expected_lparen, AttrName, DeclAttribute::isDeclModifier(DK)); return makeParserSuccess(); @@ -4164,27 +4164,11 @@ bool Parser::parseVersionTuple(llvm::VersionTuple &Version, return false; } -bool Parser::isCustomAttributeArgument() { - BacktrackingScope backtrack(*this); - if (skipSingle().hasCodeCompletion()) - return true; - - // If we have any keyword, identifier, or token that follows a function - // type's parameter list, this is a parameter list and not an attribute. - // Alternatively, we might have a token that illustrates we're not going to - // get anything following the attribute, which means the parentheses describe - // what follows the attribute. - return !Tok.isAny( - tok::arrow, tok::kw_throw, tok::kw_throws, tok::kw_rethrows, - tok::r_paren, tok::r_brace, tok::r_square, tok::r_angle) && - !Tok.isContextualKeyword("async") && !Tok.isContextualKeyword("reasync") ; -} - bool Parser::canParseCustomAttribute() { if (!canParseType()) return false; - if (Tok.isFollowingLParen() && isCustomAttributeArgument()) + if (isAtAttributeLParen(/*isCustomAttribute=*/true)) skipSingle(); return true; @@ -4196,7 +4180,7 @@ ParserResult Parser::parseCustomAttribute(SourceLoc atLoc) { // Parse a custom attribute. auto type = parseType(diag::expected_type, ParseTypeReason::CustomAttribute); if (type.hasCodeCompletion() || type.isNull()) { - if (Tok.isFollowingLParen() && isCustomAttributeArgument()) + if (isAtAttributeLParen(/*isCustomAttribute=*/true)) skipSingle(); return ParserResult(ParserStatus(type)); @@ -4208,7 +4192,11 @@ ParserResult Parser::parseCustomAttribute(SourceLoc atLoc) { ParserStatus status; ArgumentList *argList = nullptr; CustomAttributeInitializer *initContext = nullptr; - if (Tok.isFollowingLParen() && isCustomAttributeArgument()) { + if (isAtAttributeLParen(/*isCustomAttribute=*/true)) { + if (getEndOfPreviousLoc() != Tok.getLoc()) { + diagnose(getEndOfPreviousLoc(), diag::attr_extra_whitespace_before_lparen) + .warnUntilSwiftVersion(6); + } // If we have no local context to parse the initial value into, create // one for the attribute. std::optional initParser; @@ -4217,10 +4205,6 @@ ParserResult Parser::parseCustomAttribute(SourceLoc atLoc) { initContext = CustomAttributeInitializer::create(CurDeclContext); initParser.emplace(*this, initContext); } - if (getEndOfPreviousLoc() != Tok.getLoc()) { - diagnose(getEndOfPreviousLoc(), diag::attr_extra_whitespace_before_lparen) - .warnUntilSwiftVersion(6); - } auto result = parseArgumentList(tok::l_paren, tok::r_paren, /*isExprBasic*/ true, /*allowTrailingClosure*/ false); @@ -4378,7 +4362,7 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes, SourceLoc attrLoc = consumeToken(); // @warn_unused_result with no arguments. - if (!Tok.isFollowingLParen()) { + if (!isAtAttributeLParen()) { diagnose(AtLoc, diag::attr_warn_unused_result_removed) .fixItRemove(SourceRange(AtLoc, attrLoc)); @@ -4462,7 +4446,7 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes, // Recover by eating @foo(...) when foo is not known. consumeToken(); - if (Tok.isFollowingLParen()) + if (isAtAttributeLParen()) skipSingle(); return makeParserError(); @@ -4745,15 +4729,8 @@ ParserStatus Parser::parseTypeAttribute(TypeOrCustomAttr &result, // Recover by eating @foo(...) when foo is not known. consumeToken(); - if (Tok.is(tok::l_paren) && getEndOfPreviousLoc() == Tok.getLoc()) { - CancellableBacktrackingScope backtrack(*this); + if (isAtAttributeLParen(/*isCustomAttr=*/true)) skipSingle(); - // If we found '->', or 'throws' after paren, it's likely a parameter - // of function type. - if (Tok.isNot(tok::arrow, tok::kw_throws, tok::kw_rethrows, - tok::kw_throw)) - backtrack.cancelBacktrack(); - } return makeParserError(); } @@ -4814,7 +4791,7 @@ ParserStatus Parser::parseTypeAttribute(TypeOrCustomAttr &result, case TypeAttrKind::Isolated: { SourceLoc lpLoc = Tok.getLoc(), kindLoc, rpLoc; - if (!consumeIfNotAtStartOfLine(tok::l_paren)) { + if (!consumeIfAttributeLParen()) { if (!justChecking) { diagnose(Tok, diag::attr_isolated_expected_lparen); // TODO: should we suggest removing the `@`? @@ -4862,7 +4839,7 @@ ParserStatus Parser::parseTypeAttribute(TypeOrCustomAttr &result, case TypeAttrKind::Opened: { // Parse the opened existential ID string in parens SourceLoc beginLoc = Tok.getLoc(), idLoc, endLoc; - if (!consumeAttributeLParen()) { + if (!consumeIfAttributeLParen()) { if (!justChecking) diagnose(Tok, diag::opened_attribute_expected_lparen); return makeParserError(); @@ -5069,7 +5046,7 @@ ParserResult Parser::parseLifetimeEntry(SourceLoc loc) { return std::nullopt; }; - if (!Tok.isFollowingLParen()) { + if (!isAtAttributeLParen()) { diagnose(loc, diag::expected_lparen_after_lifetime_dependence); status.setIsParseError(); return status; @@ -5777,6 +5754,7 @@ static bool consumeIfParenthesizedNonisolated(Parser &P) { } static void skipAttribute(Parser &P) { + P.consumeToken(tok::at_sign); // Consider unexpected tokens to be incomplete attributes. // Parse the attribute name, which can be qualified, have @@ -5793,12 +5771,8 @@ static void skipAttribute(Parser &P) { } while (P.consumeIf(tok::period)); // Skip an argument clause after the attribute name. - if (P.consumeIf(tok::l_paren)) { - while (P.Tok.isNot(tok::r_brace, tok::eof, tok::pound_endif)) { - if (P.consumeIf(tok::r_paren)) break; - P.skipSingle(); - } - } + if (P.isAtAttributeLParen()) + P.skipSingle(); } bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes, @@ -5842,7 +5816,7 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes, // in positions like generic argument lists. if (Tok.is(tok::at_sign)) { BacktrackingScope backtrack(*this); - while (consumeIf(tok::at_sign)) + while (Tok.is(tok::at_sign)) skipAttribute(*this); // If this attribute is the last element in the block, diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 390a7bf367177..35208bdca0393 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -230,7 +230,7 @@ static bool isAtStartOfSwitchCase(Parser &parser, parser.consumeToken(tok::at_sign); parser.consumeToken(tok::identifier); - if (parser.Tok.is(tok::l_paren)) + if (parser.isAtAttributeLParen()) parser.skipSingle(); } @@ -404,7 +404,10 @@ ParserStatus Parser::parseBraceItems(SmallVectorImpl &Entries, ParserStatus Status = parseLineDirective(false); BraceItemsStatus |= Status; NeedParseErrorRecovery = Status.isErrorOrHasCompletion(); - } else if (isStartOfSwiftDecl()) { + } else if (isStartOfSwiftDecl() || + // Force parsing '@' as a declaration, as there's no + // valid expression or statement starting with an attribute. + (Tok.is(tok::at_sign) && peekToken().is(tok::identifier))) { SmallVector TmpDecls; ParserStatus DeclResult = parseDecl(IsAtStartOfLineOrPreviousHadSemi, @@ -2711,7 +2714,7 @@ ParserResult Parser::parseStmtCase(bool IsActive) { } consumeToken(tok::identifier); - if (Tok.is(tok::l_paren)) { + if (isAtAttributeLParen()) { diagnose(Tok, diag::unexpected_lparen_in_attribute, "unknown"); skipSingle(); } @@ -2722,7 +2725,7 @@ ParserResult Parser::parseStmtCase(bool IsActive) { diagnose(Tok, diag::unknown_attr_name, Tok.getText()); consumeToken(tok::identifier); - if (Tok.is(tok::l_paren)) + if (isAtAttributeLParen()) skipSingle(); } } diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 50c41d312067e..11bb865563b98 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -612,14 +612,49 @@ SourceLoc Parser::consumeAttributeLParen() { return consumeToken(tok::l_paren); } -bool Parser::consumeIfAttributeLParen() { - if (!Tok.isFollowingLParen()) { +bool Parser::consumeIfAttributeLParen(bool isCustomAttr) { + if (!isAtAttributeLParen(isCustomAttr)) return false; - } - consumeAttributeLParen(); + (void)consumeAttributeLParen(); return true; } +bool Parser::isAtAttributeLParen(bool isCustomAttr) { + if (!Tok.isFollowingLParen()) + return false; + + if (Context.isSwiftVersionAtLeast(6)) { + // No-space '(' are always arguments. + if (getEndOfPreviousLoc() == Tok.getLoc()) + return true; + + // Otherwise it's an error, but for recovery, parse it as an argument list + // if it's obvious. + BacktrackingScope backtrack(*this); + skipSingle(); + return Tok.is(tok::at_sign) || isStartOfSwiftDecl(); + } else { + // In <=5, builtin attributes only checks 'isFollowingLParen()'. + if (!isCustomAttr) + return true; + + BacktrackingScope backtrack(*this); + if (skipSingle().hasCodeCompletion()) + return true; + + // If we have any keyword, identifier, or token that follows a function + // type's parameter list, this is a parameter list and not an attribute. + // Alternatively, we might have a token that illustrates we're not going to + // get anything following the attribute, which means the parentheses + // describe what follows the attribute. + return (!Tok.isAny(tok::arrow, tok::kw_throw, tok::kw_throws, + tok::kw_rethrows, tok::r_paren, tok::r_brace, + tok::r_square, tok::r_angle) && + !Tok.isContextualKeyword("async") && + !Tok.isContextualKeyword("reasync")); + } +} + SourceLoc Parser::consumeStartingCharacterOfCurrentToken(tok Kind, size_t Len) { // Consumes prefix of token and returns its location. // (like '?', '<', '>' or '!' immediately followed by '<') diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt index 96d8839268e29..196d1291e2cd0 100644 --- a/lib/Sema/CMakeLists.txt +++ b/lib/Sema/CMakeLists.txt @@ -51,6 +51,7 @@ add_swift_host_library(swiftSema STATIC SyntacticElementTarget.cpp TypeOfReference.cpp TypeCheckAccess.cpp + TypeCheckAccessNotes.cpp TypeCheckAttr.cpp TypeCheckAttrABI.cpp TypeCheckAvailability.cpp diff --git a/lib/Sema/TypeCheckAccessNotes.cpp b/lib/Sema/TypeCheckAccessNotes.cpp new file mode 100644 index 0000000000000..07b35cc17209c --- /dev/null +++ b/lib/Sema/TypeCheckAccessNotes.cpp @@ -0,0 +1,254 @@ +//===--- TypeCheckAccessNotes.cpp - Type Checking for Access Notes --------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2025 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file implements the implicit attribute transform caused by access notes. +// +//===----------------------------------------------------------------------===// + +#include "TypeCheckDecl.h" +#include "TypeCheckObjC.h" +#include "TypeChecker.h" +#include "swift/AST/ASTContext.h" +#include "swift/AST/ASTPrinter.h" +#include "swift/AST/Decl.h" +#include "swift/AST/Module.h" +#include "swift/AST/SourceFile.h" +#include "swift/AST/TypeCheckRequests.h" +#include "swift/Basic/LLVM.h" + +using namespace swift; + +static StringRef prettyPrintAttrs(const ValueDecl *VD, + ArrayRef attrs, + SmallVectorImpl &out) { + llvm::raw_svector_ostream os(out); + StreamPrinter printer(os); + + PrintOptions opts = PrintOptions::printDeclarations(); + VD->getAttrs().print(printer, opts, attrs, VD); + return StringRef(out.begin(), out.size()).drop_back(); +} + +static void diagnoseChangesByAccessNote( + ValueDecl *VD, ArrayRef attrs, + Diag diagID, + Diag fixItID, + llvm::function_ref addFixIts) { + if (!VD->getASTContext().LangOpts.shouldRemarkOnAccessNoteSuccess() || + attrs.empty()) + return; + + // Generate string containing all attributes. + SmallString<64> attrString; + auto attrText = prettyPrintAttrs(VD, attrs, attrString); + + SourceLoc fixItLoc; + + auto reason = VD->getModuleContext()->getAccessNotes()->Reason; + auto diag = VD->diagnose(diagID, reason, attrText, VD); + for (auto attr : attrs) { + diag.highlight(attr->getRangeWithAt()); + if (fixItLoc.isInvalid()) + fixItLoc = attr->getRangeWithAt().Start; + } + + if (!fixItLoc) + fixItLoc = VD->getAttributeInsertionLoc(true); + + addFixIts(VD->getASTContext().Diags.diagnose(fixItLoc, fixItID, attrText), + attrString); +} + +template +static void addOrRemoveAttr(ValueDecl *VD, const AccessNotesFile ¬es, + std::optional expected, + SmallVectorImpl &removedAttrs, + llvm::function_ref willCreate) { + if (!expected) + return; + + auto attr = VD->getAttrs().getAttribute(); + if (*expected == (attr != nullptr)) + return; + + if (*expected) { + attr = willCreate(); + attr->setAddedByAccessNote(); + VD->getAttrs().add(attr); + + // Arrange for us to emit a remark about this attribute after type checking + // has ensured it's valid. + if (auto SF = VD->getDeclContext()->getParentSourceFile()) + SF->AttrsAddedByAccessNotes[VD].push_back(attr); + } else { + removedAttrs.push_back(attr); + VD->getAttrs().removeAttribute(attr); + } +} + +InFlightDiagnostic swift::softenIfAccessNote(const Decl *D, + const DeclAttribute *attr, + InFlightDiagnostic &diag) { + const ValueDecl *VD = dyn_cast(D); + if (!VD || !attr || !attr->getAddedByAccessNote()) + return std::move(diag); + + SmallString<32> attrString; + auto attrText = prettyPrintAttrs(VD, llvm::ArrayRef(attr), attrString); + + ASTContext &ctx = D->getASTContext(); + auto behavior = ctx.LangOpts.getAccessNoteFailureLimit(); + return std::move(diag.wrapIn(diag::wrap_invalid_attr_added_by_access_note, + D->getModuleContext()->getAccessNotes()->Reason, + ctx.AllocateCopy(attrText), VD) + .limitBehavior(behavior)); +} + +static void applyAccessNote(ValueDecl *VD, const AccessNote ¬e, + const AccessNotesFile ¬es) { + ASTContext &ctx = VD->getASTContext(); + SmallVector removedAttrs; + + addOrRemoveAttr(VD, notes, note.ObjC, removedAttrs, [&] { + return ObjCAttr::create(ctx, note.ObjCName, false); + }); + + addOrRemoveAttr(VD, notes, note.Dynamic, removedAttrs, + [&] { return new (ctx) DynamicAttr(true); }); + + // FIXME: If we ever have more attributes, we'll need to sort removedAttrs by + // SourceLoc. As it is, attrs are always before modifiers, so we're okay now. + + diagnoseChangesByAccessNote(VD, removedAttrs, + diag::attr_removed_by_access_note, + diag::fixit_attr_removed_by_access_note, + [&](InFlightDiagnostic diag, StringRef code) { + for (auto attr : llvm::reverse(removedAttrs)) + diag.fixItRemove(attr->getRangeWithAt()); + }); + + if (note.ObjCName) { + auto newName = note.ObjCName.value(); + + // addOrRemoveAttr above guarantees there's an ObjCAttr on this decl. + auto attr = VD->getAttrs().getAttribute(); + assert(attr && "ObjCName set, but ObjCAttr not true or did not apply???"); + + if (!attr->hasName()) { + // There was already an @objc attribute with no selector. Set it. + attr->setName(newName, true); + + if (!ctx.LangOpts.shouldRemarkOnAccessNoteSuccess()) + return; + + VD->diagnose(diag::attr_objc_name_changed_by_access_note, notes.Reason, + VD, newName); + + auto fixIt = + VD->diagnose(diag::fixit_attr_objc_name_changed_by_access_note); + fixDeclarationObjCName(fixIt, VD, ObjCSelector(), newName); + } else if (attr->getName() != newName) { + // There was already an @objc + auto behavior = ctx.LangOpts.getAccessNoteFailureLimit(); + + VD->diagnose(diag::attr_objc_name_conflicts_with_access_note, + notes.Reason, VD, attr->getName().value(), newName) + .highlight(attr->getRangeWithAt()) + .limitBehavior(behavior); + } + } +} + +void TypeChecker::applyAccessNote(ValueDecl *VD) { + (void)evaluateOrDefault(VD->getASTContext().evaluator, + ApplyAccessNoteRequest{VD}, {}); +} + +void swift::diagnoseAttrsAddedByAccessNote(SourceFile &SF) { + if (!SF.getASTContext().LangOpts.shouldRemarkOnAccessNoteSuccess()) + return; + + for (auto declAndAttrs : SF.AttrsAddedByAccessNotes) { + auto D = declAndAttrs.getFirst(); + SmallVector sortedAttrs; + llvm::append_range(sortedAttrs, declAndAttrs.getSecond()); + + // Filter out invalid attributes. + sortedAttrs.erase(llvm::remove_if(sortedAttrs, + [](DeclAttribute *attr) { + assert(attr->getAddedByAccessNote()); + return attr->isInvalid(); + }), + sortedAttrs.end()); + if (sortedAttrs.empty()) + continue; + + // Sort attributes by name. + llvm::sort(sortedAttrs, [](DeclAttribute *first, DeclAttribute *second) { + return first->getAttrName() < second->getAttrName(); + }); + sortedAttrs.erase(std::unique(sortedAttrs.begin(), sortedAttrs.end()), + sortedAttrs.end()); + + diagnoseChangesByAccessNote( + D, sortedAttrs, diag::attr_added_by_access_note, + diag::fixit_attr_added_by_access_note, + [=](InFlightDiagnostic diag, StringRef code) { + diag.fixItInsert(D->getAttributeInsertionLoc(/*isModifier=*/true), + code); + }); + } +} + +const AccessNotesFile * +LoadAccessNotesRequest::evaluate(Evaluator &evaluator, ASTContext *_ctx) const { + auto &ctx = *_ctx; + auto &accessNotesPath = ctx.LangOpts.AccessNotesPath; + if (accessNotesPath.empty()) + return nullptr; + + auto &SM = ctx.SourceMgr; + auto &FS = *SM.getFileSystem(); + auto bufferOrError = swift::vfs::getFileOrSTDIN(FS, accessNotesPath); + if (!bufferOrError) { + ctx.Diags.diagnose(SourceLoc(), diag::access_notes_file_io_error, + accessNotesPath, bufferOrError.getError().message()); + return nullptr; + } + + int sourceID = SM.addNewSourceBuffer(std::move(bufferOrError.get())); + auto buffer = SM.getLLVMSourceMgr().getMemoryBuffer(sourceID); + + auto accessNotesFile = AccessNotesFile::load(ctx, buffer); + if (!accessNotesFile) + return nullptr; + + auto *result = + ctx.AllocateObjectCopy(std::move(*accessNotesFile)); + ctx.addDestructorCleanup(*result); + return result; +} + +evaluator::SideEffect ApplyAccessNoteRequest::evaluate(Evaluator &evaluator, + ValueDecl *VD) const { + // Access notes don't apply to ABI-only attributes. + if (!ABIRoleInfo(VD).providesAPI()) + return {}; + + auto *notes = VD->getModuleContext()->getAccessNotes(); + if (!notes) + return {}; + + if (auto note = notes->lookup(VD)) + applyAccessNote(VD, *note.get(), *notes); + return {}; +} diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index b7d47438bf9ea..a719d67f280de 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -2003,196 +2003,6 @@ void TypeChecker::diagnoseDuplicateCaptureVars(CaptureListExpr *expr) { diagnoseDuplicateDecls(captureListVars); } -static StringRef prettyPrintAttrs(const ValueDecl *VD, - ArrayRef attrs, - SmallVectorImpl &out) { - llvm::raw_svector_ostream os(out); - StreamPrinter printer(os); - - PrintOptions opts = PrintOptions::printDeclarations(); - VD->getAttrs().print(printer, opts, attrs, VD); - return StringRef(out.begin(), out.size()).drop_back(); -} - -static void diagnoseChangesByAccessNote( - ValueDecl *VD, ArrayRef attrs, - Diag diagID, - Diag fixItID, - llvm::function_ref addFixIts) { - if (!VD->getASTContext().LangOpts.shouldRemarkOnAccessNoteSuccess() || - attrs.empty()) - return; - - // Generate string containing all attributes. - SmallString<64> attrString; - auto attrText = prettyPrintAttrs(VD, attrs, attrString); - - SourceLoc fixItLoc; - - auto reason = VD->getModuleContext()->getAccessNotes().Reason; - auto diag = VD->diagnose(diagID, reason, attrText, VD); - for (auto attr : attrs) { - diag.highlight(attr->getRangeWithAt()); - if (fixItLoc.isInvalid()) - fixItLoc = attr->getRangeWithAt().Start; - } - - if (!fixItLoc) - fixItLoc = VD->getAttributeInsertionLoc(true); - - addFixIts(VD->getASTContext().Diags.diagnose(fixItLoc, fixItID, attrText), - attrString); -} - -template -static void addOrRemoveAttr(ValueDecl *VD, const AccessNotesFile ¬es, - std::optional expected, - SmallVectorImpl &removedAttrs, - llvm::function_ref willCreate) { - if (!expected) return; - - auto attr = VD->getAttrs().getAttribute(); - if (*expected == (attr != nullptr)) return; - - if (*expected) { - attr = willCreate(); - attr->setAddedByAccessNote(); - VD->getAttrs().add(attr); - - // Arrange for us to emit a remark about this attribute after type checking - // has ensured it's valid. - if (auto SF = VD->getDeclContext()->getParentSourceFile()) - SF->AttrsAddedByAccessNotes[VD].push_back(attr); - } else { - removedAttrs.push_back(attr); - VD->getAttrs().removeAttribute(attr); - } -} - -InFlightDiagnostic -swift::softenIfAccessNote(const Decl *D, const DeclAttribute *attr, - InFlightDiagnostic &diag) { - const ValueDecl *VD = dyn_cast(D); - if (!VD || !attr || !attr->getAddedByAccessNote()) - return std::move(diag); - - SmallString<32> attrString; - auto attrText = prettyPrintAttrs(VD, llvm::ArrayRef(attr), attrString); - - ASTContext &ctx = D->getASTContext(); - auto behavior = ctx.LangOpts.getAccessNoteFailureLimit(); - return std::move(diag.wrapIn(diag::wrap_invalid_attr_added_by_access_note, - D->getModuleContext()->getAccessNotes().Reason, - ctx.AllocateCopy(attrText), VD) - .limitBehavior(behavior)); -} - -static void applyAccessNote(ValueDecl *VD, const AccessNote ¬e, - const AccessNotesFile ¬es) { - ASTContext &ctx = VD->getASTContext(); - SmallVector removedAttrs; - - addOrRemoveAttr(VD, notes, note.ObjC, removedAttrs, [&]{ - return ObjCAttr::create(ctx, note.ObjCName, false); - }); - - addOrRemoveAttr(VD, notes, note.Dynamic, removedAttrs, [&]{ - return new (ctx) DynamicAttr(true); - }); - - // FIXME: If we ever have more attributes, we'll need to sort removedAttrs by - // SourceLoc. As it is, attrs are always before modifiers, so we're okay now. - - diagnoseChangesByAccessNote(VD, removedAttrs, - diag::attr_removed_by_access_note, - diag::fixit_attr_removed_by_access_note, - [&](InFlightDiagnostic diag, StringRef code) { - for (auto attr : llvm::reverse(removedAttrs)) - diag.fixItRemove(attr->getRangeWithAt()); - }); - - if (note.ObjCName) { - auto newName = note.ObjCName.value(); - - // addOrRemoveAttr above guarantees there's an ObjCAttr on this decl. - auto attr = VD->getAttrs().getAttribute(); - assert(attr && "ObjCName set, but ObjCAttr not true or did not apply???"); - - if (!attr->hasName()) { - // There was already an @objc attribute with no selector. Set it. - attr->setName(newName, true); - - if (!ctx.LangOpts.shouldRemarkOnAccessNoteSuccess()) - return; - - VD->diagnose(diag::attr_objc_name_changed_by_access_note, notes.Reason, - VD, newName); - - auto fixIt = - VD->diagnose(diag::fixit_attr_objc_name_changed_by_access_note); - fixDeclarationObjCName(fixIt, VD, ObjCSelector(), newName); - } - else if (attr->getName() != newName) { - // There was already an @objc - auto behavior = ctx.LangOpts.getAccessNoteFailureLimit(); - - VD->diagnose(diag::attr_objc_name_conflicts_with_access_note, - notes.Reason, VD, attr->getName().value(), newName) - .highlight(attr->getRangeWithAt()) - .limitBehavior(behavior); - } - } -} - -void TypeChecker::applyAccessNote(ValueDecl *VD) { - (void)evaluateOrDefault(VD->getASTContext().evaluator, - ApplyAccessNoteRequest{VD}, {}); -} - -void swift::diagnoseAttrsAddedByAccessNote(SourceFile &SF) { - if (!SF.getASTContext().LangOpts.shouldRemarkOnAccessNoteSuccess()) - return; - - for (auto declAndAttrs : SF.AttrsAddedByAccessNotes) { - auto D = declAndAttrs.getFirst(); - SmallVector sortedAttrs; - llvm::append_range(sortedAttrs, declAndAttrs.getSecond()); - - // Filter out invalid attributes. - sortedAttrs.erase( - llvm::remove_if(sortedAttrs, [](DeclAttribute *attr) { - assert(attr->getAddedByAccessNote()); - return attr->isInvalid(); - }), sortedAttrs.end()); - if (sortedAttrs.empty()) continue; - - // Sort attributes by name. - llvm::sort(sortedAttrs, [](DeclAttribute * first, DeclAttribute * second) { - return first->getAttrName() < second->getAttrName(); - }); - sortedAttrs.erase(std::unique(sortedAttrs.begin(), sortedAttrs.end()), - sortedAttrs.end()); - - diagnoseChangesByAccessNote(D, sortedAttrs, diag::attr_added_by_access_note, - diag::fixit_attr_added_by_access_note, - [=](InFlightDiagnostic diag, StringRef code) { - diag.fixItInsert(D->getAttributeInsertionLoc(/*isModifier=*/true), code); - }); - } -} - -evaluator::SideEffect -ApplyAccessNoteRequest::evaluate(Evaluator &evaluator, ValueDecl *VD) const { - // Access notes don't apply to ABI-only attributes. - if (!ABIRoleInfo(VD).providesAPI()) - return {}; - - AccessNotesFile ¬es = VD->getModuleContext()->getAccessNotes(); - if (auto note = notes.lookup(VD)) - applyAccessNote(VD, *note.get(), notes); - return {}; -} - static void diagnoseWrittenPlaceholderTypes(ASTContext &Ctx, const Pattern *P, Expr *init) { diff --git a/lib/Sema/TypeCheckMacros.cpp b/lib/Sema/TypeCheckMacros.cpp index fce5fb3762bb3..bac848bc387be 100644 --- a/lib/Sema/TypeCheckMacros.cpp +++ b/lib/Sema/TypeCheckMacros.cpp @@ -52,6 +52,8 @@ #include "swift/Subsystems.h" #include "llvm/Config/config.h" +#define DEBUG_TYPE "macros" + using namespace swift; /// Translate an argument provided as a string literal into an identifier, @@ -1201,6 +1203,11 @@ evaluateFreestandingMacro(FreestandingMacroExpansion *expansion, PrettyStackTraceFreestandingMacroExpansion debugStack( "expanding freestanding macro", expansion); + LLVM_DEBUG( + llvm::dbgs() << "\nexpanding macro:\n"; + macro->print(llvm::dbgs(), PrintOptions::printEverything()); + llvm::dbgs() << "\n"; + ); // Builtin macros are handled via ASTGen. auto *astGenSourceFile = sourceFile->getExportedSourceFile(); @@ -1527,6 +1534,18 @@ static SourceFile *evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, auto *astGenAttrSourceFile = attrSourceFile->getExportedSourceFile(); if (!astGenAttrSourceFile) return nullptr; + LLVM_DEBUG( + StreamPrinter P(llvm::dbgs()); + llvm::dbgs() << "\nexpanding macro:\n"; + attr->print(P, PrintOptions::printEverything(), attachedTo); + llvm::dbgs() << "\nattached to:\n"; + attachedTo->print(P, PrintOptions::printEverything()); + if (parentDecl) { + llvm::dbgs() << "\nwith parent:\n"; + parentDecl->print(P, PrintOptions::printEverything()); + } + llvm::dbgs() << "\n"; + ); auto *astGenDeclSourceFile = declSourceFile->getExportedSourceFile(); if (!astGenDeclSourceFile) @@ -1677,6 +1696,14 @@ static SourceFile *evaluateAttachedMacro(MacroDecl *macro, #if SWIFT_BUILD_SWIFT_SYNTAX PrettyStackTraceExpr debugStack( ctx, "expanding attached macro", attachedTo); + LLVM_DEBUG( + StreamPrinter P(llvm::dbgs()); + llvm::dbgs() << "\nexpanding macro:\n"; + attr->print(P, PrintOptions::printEverything(), nullptr); + llvm::dbgs() << "\nattached to:\n"; + attachedTo->print(P, PrintOptions::printEverything()); + llvm::dbgs() << "\n"; + ); auto *astGenAttrSourceFile = attrSourceFile->getExportedSourceFile(); if (!astGenAttrSourceFile) diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index 2c52026a55f56..6737c25fcbf64 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -827,6 +827,130 @@ namespace { }; } +/// Returns true on error. +static bool resolveGenericArguments(ValueDecl *decl, + const GenericContext *genCtx, + const TypeResolution &resolution, + SILTypeResolutionContext *silContext, + DeclRefTypeRepr *repr, + SmallVectorImpl &args) { + auto options = resolution.getOptions(); + auto &ctx = decl->getASTContext(); + + auto genericParams = genCtx->getGenericParams(); + auto hasParameterPack = llvm::any_of(*genericParams, [](auto *paramDecl) { + return paramDecl->isParameterPack(); + }); + auto hasValueParam = llvm::any_of(*genericParams, [](auto *paramDecl) { + return paramDecl->isValue(); + }); + + // If the type declares at least one parameter pack, allow pack expansions + // anywhere in the argument list. We'll use the PackMatcher to ensure that + // everything lines up. Otherwise, don't allow pack expansions to appear + // at all. + auto argOptions = options.withoutContext().withContext( + hasParameterPack + ? TypeResolverContext::VariadicGenericArgument + : TypeResolverContext::ScalarGenericArgument); + if (hasValueParam) + argOptions = argOptions.withContext(TypeResolverContext::ValueGenericArgument); + auto genericResolution = resolution.withOptions(argOptions); + + // In SIL mode, Optional interprets T as a SIL type. + if (options.contains(TypeResolutionFlags::SILType)) { + if (auto nominal = dyn_cast(genCtx)) { + if (nominal->isOptionalDecl()) { + genericResolution = resolution; + } + } + } + + auto genericArgs = repr->getGenericArgs(); + auto loc = repr->getNameLoc().getBaseNameLoc(); + + // Resolve the types of the generic arguments. + for (auto tyR : genericArgs) { + // Propagate failure. + Type substTy = genericResolution.resolveType(tyR, silContext); + if (!substTy || substTy->hasError()) + return true; + + args.push_back(substTy); + } + + // Make sure we have the right number of generic arguments. + if (!hasParameterPack) { + // For generic types without type parameter packs, we require + // the number of declared generic parameters match the number of + // arguments. + if (genericArgs.size() != genericParams->size()) { + if (!options.contains(TypeResolutionFlags::SilenceErrors)) { + diagnoseInvalidGenericArguments( + loc, decl, genericArgs.size(), genericParams->size(), + /*hasParameterPack=*/false, repr->getAngleBrackets()); + } + return true; + } + + return false; + } + + // For generic types with type parameter packs, we only require + // that the number of arguments is enough to saturate the number of + // regular generic parameters. The parameter pack will absorb + // zero or arguments. + SmallVector params; + for (auto paramDecl : genericParams->getParams()) { + auto paramType = paramDecl->getDeclaredInterfaceType(); + params.push_back(paramDecl->isParameterPack() + ? PackExpansionType::get(paramType, paramType) + : paramType); + } + + PackMatcher matcher(params, args, ctx); + if (matcher.match() || matcher.pairs.size() != params.size()) { + if (!options.contains(TypeResolutionFlags::SilenceErrors)) { + diagnoseInvalidGenericArguments( + loc, decl, genericArgs.size(), genericParams->size(), + /*hasParameterPack=*/true, repr->getAngleBrackets()); + } + return true; + } + + args.clear(); + for (unsigned i : indices(params)) { + auto found = std::find_if(matcher.pairs.begin(), + matcher.pairs.end(), + [&](const MatchedPair &pair) -> bool { + return pair.lhsIdx == i; + }); + assert(found != matcher.pairs.end()); + + auto arg = found->rhs; + + // PackMatcher will always produce a PackExpansionType as the + // arg for a pack parameter, if necessary by wrapping a PackType + // in one. (It's a weird representation.) Look for that pattern + // and unwrap the pack. Otherwise, we must have matched with a + // single component which happened to be an expansion; wrap that + // in a PackType. In either case, we always want arg to end up + // a PackType. + if (auto *expansionType = arg->getAs()) { + auto pattern = expansionType->getPatternType(); + if (auto pack = pattern->getAs()) { + arg = pack; + } else { + arg = PackType::get(ctx, {expansionType}); + } + } + + args.push_back(arg); + } + + return false; +} + /// Apply generic arguments to the given type. /// /// If the type is itself not generic, this does nothing. @@ -1005,112 +1129,10 @@ static Type applyGenericArguments(Type type, auto *unboundType = type->castTo(); auto *decl = unboundType->getDecl(); - auto genericParams = decl->getGenericParams(); - auto hasParameterPack = llvm::any_of(*genericParams, [](auto *paramDecl) { - return paramDecl->isParameterPack(); - }); - auto hasValueParam = llvm::any_of(*genericParams, [](auto *paramDecl) { - return paramDecl->isValue(); - }); - - // If the type declares at least one parameter pack, allow pack expansions - // anywhere in the argument list. We'll use the PackMatcher to ensure that - // everything lines up. Otherwise, don't allow pack expansions to appear - // at all. - auto argOptions = options.withoutContext().withContext( - hasParameterPack - ? TypeResolverContext::VariadicGenericArgument - : TypeResolverContext::ScalarGenericArgument); - if (hasValueParam) - argOptions = argOptions.withContext(TypeResolverContext::ValueGenericArgument); - auto genericResolution = resolution.withOptions(argOptions); - - // In SIL mode, Optional interprets T as a SIL type. - if (options.contains(TypeResolutionFlags::SILType)) { - if (auto nominal = dyn_cast(decl)) { - if (nominal->isOptionalDecl()) { - genericResolution = resolution; - } - } - } - // Resolve the types of the generic arguments. SmallVector args; - for (auto tyR : genericArgs) { - // Propagate failure. - Type substTy = genericResolution.resolveType(tyR, silContext); - if (!substTy || substTy->hasError()) - return ErrorType::get(ctx); - - args.push_back(substTy); - } - - // Make sure we have the right number of generic arguments. - if (!hasParameterPack) { - // For generic types without type parameter packs, we require - // the number of declared generic parameters match the number of - // arguments. - if (genericArgs.size() != genericParams->size()) { - if (!options.contains(TypeResolutionFlags::SilenceErrors)) { - diagnoseInvalidGenericArguments( - loc, decl, genericArgs.size(), genericParams->size(), - /*hasParameterPack=*/false, repr->getAngleBrackets()); - } - return ErrorType::get(ctx); - } - } else { - // For generic types with type parameter packs, we only require - // that the number of arguments is enough to saturate the number of - // regular generic parameters. The parameter pack will absorb - // zero or arguments. - SmallVector params; - for (auto paramDecl : genericParams->getParams()) { - auto paramType = paramDecl->getDeclaredInterfaceType(); - params.push_back(paramDecl->isParameterPack() - ? PackExpansionType::get(paramType, paramType) - : paramType); - } - - PackMatcher matcher(params, args, ctx); - if (matcher.match() || matcher.pairs.size() != params.size()) { - if (!options.contains(TypeResolutionFlags::SilenceErrors)) { - diagnoseInvalidGenericArguments( - loc, decl, genericArgs.size(), genericParams->size(), - /*hasParameterPack=*/true, repr->getAngleBrackets()); - } - return ErrorType::get(ctx); - } - - args.clear(); - for (unsigned i : indices(params)) { - auto found = std::find_if(matcher.pairs.begin(), - matcher.pairs.end(), - [&](const MatchedPair &pair) -> bool { - return pair.lhsIdx == i; - }); - assert(found != matcher.pairs.end()); - - auto arg = found->rhs; - - // PackMatcher will always produce a PackExpansionType as the - // arg for a pack parameter, if necessary by wrapping a PackType - // in one. (It's a weird representation.) Look for that pattern - // and unwrap the pack. Otherwise, we must have matched with a - // single component which happened to be an expansion; wrap that - // in a PackType. In either case, we always want arg to end up - // a PackType. - if (auto *expansionType = arg->getAs()) { - auto pattern = expansionType->getPatternType(); - if (auto pack = pattern->getAs()) { - arg = pack; - } else { - arg = PackType::get(ctx, {expansionType}); - } - } - - args.push_back(arg); - } - } + if (resolveGenericArguments(decl, decl, resolution, silContext, repr, args)) + return ErrorType::get(ctx); // Construct the substituted type. const auto result = resolution.applyUnboundGenericArguments( @@ -1130,6 +1152,7 @@ static Type applyGenericArguments(Type type, if (auto clangDecl = decl->getClangDecl()) { if (auto classTemplateDecl = dyn_cast(clangDecl)) { + // FIXME: Why does this resolve the types twice? SmallVector typesOfGenericArgs; for (auto typeRepr : genericArgs) { typesOfGenericArgs.push_back(resolution.resolveType(typeRepr)); @@ -3994,25 +4017,12 @@ TypeResolver::resolveASTFunctionTypeParams(TupleTypeRepr *inputRepr, return elements; } +/// Implement the special @_opaqueReturnTypeOf attribute syntax in +/// module interface files. NeverNullType TypeResolver::resolveOpaqueReturnType(TypeRepr *repr, StringRef mangledName, unsigned ordinal, TypeResolutionOptions options) { - // The type representation should be an unqualified identifier. We don't - // really use the identifier for anything, but we do resolve any generic - // arguments to instantiate the possibly-generic opaque type. - SmallVector TypeArgsBuf; - if (auto *unqualIdentRepr = dyn_cast(repr)) { - for (auto argRepr : unqualIdentRepr->getGenericArgs()) { - auto argTy = resolveType(argRepr, options); - // If we cannot resolve the generic parameter, propagate the error out. - if (argTy->hasError()) { - return ErrorType::get(getASTContext()); - } - TypeArgsBuf.push_back(argTy); - } - } - // Use type reconstruction to summon the opaque type decl. Demangler demangle; auto definingDeclNode = demangle.demangleSymbol(mangledName); @@ -4026,14 +4036,98 @@ TypeResolver::resolveOpaqueReturnType(TypeRepr *repr, StringRef mangledName, auto opaqueNode = builder.getNodeFactory().createNode(Node::Kind::OpaqueReturnTypeOf); opaqueNode->addChild(definingDeclNode, builder.getNodeFactory()); - - auto TypeArgs = ArrayRef(TypeArgsBuf); - auto ty = builder.resolveOpaqueType(opaqueNode, TypeArgs, ordinal); - if (!ty || ty->hasError()) { + auto *opaqueDecl = builder.resolveOpaqueTypeDecl(opaqueNode); + + auto *ownerDecl = opaqueDecl->getNamingDecl(); + if (!ownerDecl) { diagnose(repr->getLoc(), diag::no_opaque_return_type_of); return ErrorType::get(getASTContext()); } - return ty; + + auto genericSig = ownerDecl->getInnermostDeclContext() + ->getGenericSignatureOfContext(); + + SubstitutionMap subs; + if (genericSig) { + SmallVector args; + + // The type representation should either be a single identifier, or a + // series of member references. We don't use the identifiers for + // anything, but we do resolve the generic arguments at each level + // to instantiate the possibly-generic opaque type. + if (isa(repr) && + !genericSig->hasParameterPack()) { + // When there are no parameter packs and we just have a single + // unqualified identifier, we fall back to the legacy behavior, + // which collects the generic arguments for all levels of nesting + // in a flat list. + // + // This matches the old behavior of the ASTPrinter. + auto *unqualIdentRepr = cast(repr); + + for (auto argRepr : unqualIdentRepr->getGenericArgs()) { + auto argTy = resolveType(argRepr, options); + // If we cannot resolve the generic parameter, propagate the error out. + if (argTy->hasError()) { + return ErrorType::get(getASTContext()); + } + args.push_back(argTy); + } + + if (args.size() != genericSig.getGenericParams().size()) { + diagnose(repr->getLoc(), diag::no_opaque_return_type_of); + return ErrorType::get(getASTContext()); + } + } else { + // Correct handling of nested types. We interpret a qualified + // TypeRepr with a generic argument list at each level, like + // __.__. + SmallVector, 2> nestedArgs; + + auto *dc = ownerDecl->getInnermostDeclContext(); + while (!dc->isModuleScopeContext()) { + if (dc->isInnermostContextGeneric()) { + if (repr == nullptr || !isa(repr)) { + diagnose(repr->getLoc(), diag::no_opaque_return_type_of); + return ErrorType::get(getASTContext()); + } + + auto *identRepr = cast(repr); + nestedArgs.emplace_back(); + + auto *decl = dyn_cast(dc->getAsDecl()); + if (decl == nullptr) + decl = dc->getSelfNominalTypeDecl(); + ASSERT(decl); + + resolveGenericArguments(decl, + decl->getAsGenericContext(), + resolution, + silContext, + identRepr, + nestedArgs.back()); + repr = identRepr->getBase(); + } + + dc = dc->getParent(); + } + + for (auto &subArgs : llvm::reverse(nestedArgs)) { + args.append(subArgs.begin(), subArgs.end()); + } + } + + subs = SubstitutionMap::get(genericSig, args, + LookUpConformanceInModule()); + } + + if (ordinal >= opaqueDecl->getOpaqueGenericParams().size()) { + diagnose(repr->getLoc(), diag::no_opaque_return_type_of); + return ErrorType::get(getASTContext()); + } + + Type interfaceType = opaqueDecl->getOpaqueGenericParams()[ordinal]; + return OpaqueTypeArchetypeType::get(opaqueDecl, interfaceType, subs); } NeverNullType TypeResolver::resolveASTFunctionType( diff --git a/stdlib/public/runtime/Float16Support.cpp b/stdlib/public/runtime/Float16Support.cpp index dfa9c9876ded6..5f1125edf3c2a 100644 --- a/stdlib/public/runtime/Float16Support.cpp +++ b/stdlib/public/runtime/Float16Support.cpp @@ -71,11 +71,11 @@ static _Float16 fromEncoding(unsigned short s) { // but who knows what could go wrong, and they're tiny functions. # include -SWIFT_RUNTIME_EXPORT float __gnu_h2f_ieee(short h) { +SWIFT_RUNTIME_EXPORT float __gnu_h2f_ieee(unsigned short h) { return _mm_cvtss_f32(_mm_cvtph_ps(_mm_set_epi64x(0,h))); } -SWIFT_RUNTIME_EXPORT short __gnu_f2h_ieee(float f) { +SWIFT_RUNTIME_EXPORT unsigned short __gnu_f2h_ieee(float f) { return (unsigned short)_mm_cvtsi128_si32( _mm_cvtps_ph(_mm_set_ss(f), _MM_FROUND_CUR_DIRECTION) ); diff --git a/test/ClangImporter/macros.swift b/test/ClangImporter/macros.swift index 6a9f07be9f54c..a25354d17cb1b 100644 --- a/test/ClangImporter/macros.swift +++ b/test/ClangImporter/macros.swift @@ -1,7 +1,5 @@ // RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-objc-interop -typecheck -verify %s - -// Most of these don't pass: rdar://110071334 -// %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-experimental-cxx-interop -enable-objc-interop -typecheck -verify %s +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -cxx-interoperability-mode=default -enable-objc-interop -typecheck -verify %s @_exported import macros diff --git a/test/Driver/createCompilerInvocation.swift b/test/Driver/createCompilerInvocation.swift index 1f9bec4fe9c3a..6786aef7546c1 100644 --- a/test/Driver/createCompilerInvocation.swift +++ b/test/Driver/createCompilerInvocation.swift @@ -40,3 +40,10 @@ // NOOUTPUT_ARGS-DAG: -typecheck // NOOUTPUT_ARGS-DAG: -module-name // NOOUTPUT_ARGS: Frontend Arguments END + +// Make sure that '-incremental' is ignored, we don't want SourceKit to run with +// reference dependency tracking enabled. The legacy driver simply doesn't +// implement incremental compilation, but make sure when we switch to the new +// driver this doesn't start failing. +// RUN: %swift-ide-test_plain -test-createCompilerInvocation -incremental %S/Input/main.swift | %FileCheck --check-prefix INCREMENTAL %s +// INCREMENTAL-NOT: emit-reference-dependencies diff --git a/test/Interop/Cxx/objc-correctness/darwin-macros.swift b/test/Interop/Cxx/objc-correctness/darwin-macros.swift new file mode 100644 index 0000000000000..77f52a632f32d --- /dev/null +++ b/test/Interop/Cxx/objc-correctness/darwin-macros.swift @@ -0,0 +1,7 @@ +// RUN: %target-swift-frontend -cxx-interoperability-mode=default -typecheck -verify -I %S/Inputs %s + +// REQUIRES: OS=macosx + +import Darwin + +let _ = COPYFILE_ALL diff --git a/test/Interop/SwiftToCxx/stdlib/string/string-to-nsstring.mm b/test/Interop/SwiftToCxx/stdlib/string/string-to-nsstring.mm index 6448e65c2231b..ebea414cf2ad3 100644 --- a/test/Interop/SwiftToCxx/stdlib/string/string-to-nsstring.mm +++ b/test/Interop/SwiftToCxx/stdlib/string/string-to-nsstring.mm @@ -76,5 +76,27 @@ int main() { assert(std::string(swiftStr) == "👨‍💻👩‍💻åäö"); } + { + NSString* arabic_ns = @"طاب يومك"; + auto swift_arabic = String::init(arabic_ns); + auto std_arabic = (std::string)swift_arabic; + assert(std_arabic == "طاب يومك"); + + NSString* mixed_ns = @"Hello مرحبا World"; + auto swift_mixed = String::init(mixed_ns); + auto std_mixed = (std::string)swift_mixed; + assert(std_mixed == "Hello مرحبا World"); + + NSString* hebrew_ns = @"שלום עולם"; + auto swift_hebrew = String::init(hebrew_ns); + auto std_hebrew = (std::string)swift_hebrew; + assert(std_hebrew == "שלום עולם"); + + NSString* chinese_ns = @"你好世界"; + auto swift_chinese = String::init(chinese_ns); + auto std_chinese = (std::string)swift_chinese; + assert(std_chinese == "你好世界"); + } + return 0; } diff --git a/test/Macros/macro_self.swift b/test/Macros/macro_self.swift index 47b278568314c..e866740304161 100644 --- a/test/Macros/macro_self.swift +++ b/test/Macros/macro_self.swift @@ -1,12 +1,14 @@ // RUN: %target-swift-frontend -parse %s -verify -@freestanding(expression) // expected-error {{expected expression}} +@freestanding(expression) macro self() = #externalMacro(module: "MacroDefinition", type: "InvalidMacro") +// expected-error@-1 {{expected declaration}} func sync() {} -@freestanding(expression) // expected-error {{expected expression}} +@freestanding(expression) macro Self() = #externalMacro(module: "MacroDefinition", type: "InvalidMacro") +// expected-error@-1 {{expected declaration}} func testSelfAsFreestandingMacro() { _ = #self diff --git a/test/ModuleInterface/invalid-opaque-result-types.swift b/test/ModuleInterface/invalid-opaque-result-types.swift index fffc5dc985ade..40a13fca65840 100644 --- a/test/ModuleInterface/invalid-opaque-result-types.swift +++ b/test/ModuleInterface/invalid-opaque-result-types.swift @@ -17,7 +17,6 @@ // // RUN: not %target-swift-frontend -typecheck %s -I %t 2>&1 | %FileCheck %s -// CHECK: cannot find type 'InvalidParameter' in scope // CHECK: unable to resolve type for _opaqueReturnTypeOf attribute // CHECK: failed to build module 'InvalidOpaqueResultType' for importation import InvalidOpaqueResultType diff --git a/test/ModuleInterface/variadic-opaque-result-types.swift b/test/ModuleInterface/variadic-opaque-result-types.swift new file mode 100644 index 0000000000000..7874a76d9b426 --- /dev/null +++ b/test/ModuleInterface/variadic-opaque-result-types.swift @@ -0,0 +1,122 @@ +// RUN: %empty-directory(%t) +// RUN: %target-swift-emit-module-interface(%t/VariadicOpaqueResultTypes.swiftinterface) %s -module-name VariadicOpaqueResultTypes -target %target-swift-5.9-abi-triple +// RUN: %target-swift-typecheck-module-from-interface(%t/VariadicOpaqueResultTypes.swiftinterface) -module-name VariadicOpaqueResultTypes +// RUN: %FileCheck %s < %t/VariadicOpaqueResultTypes.swiftinterface + + +/// +/// First, make sure pack expansions can appear in the generic argument list of an opaque return type. +/// + +public struct I1: IteratorProtocol { + public mutating func next() -> (some Any)? { return 3 } +} + +// CHECK: public struct I1 : Swift.IteratorProtocol { +// CHECK: public mutating func next() -> (some Any)? +// CHECK: public typealias Element = @_opaqueReturnTypeOf("$s25VariadicOpaqueResultTypes2I1V4nextQrSgyF", 0) __ +// CHECK: } + + +public struct S1: Sequence { + public func makeIterator() -> some IteratorProtocol { + return I1() + } +} + +// CHECK: public struct S1 : Swift.Sequence { +// CHECK: public func makeIterator() -> some Swift.IteratorProtocol +// CHECK: public typealias Element = (@_opaqueReturnTypeOf("$s25VariadicOpaqueResultTypes2S1V12makeIteratorQryF", 0) __).Element +// CHECK: public typealias Iterator = @_opaqueReturnTypeOf("$s25VariadicOpaqueResultTypes2S1V12makeIteratorQryF", 0) __ +// CHECK: } + + +public struct Scalar { + public struct I2: IteratorProtocol { + public mutating func next() -> (some Any)? { return 3 } + } +} + + +/// +/// Now, test nested types. The next example uses the old "flat" syntax, because parameter packs are not involved. +/// + + +// CHECK: public struct Scalar { +// CHECK: public struct I2 : Swift.IteratorProtocol { +// CHECK: public mutating func next() -> (some Any)? +// CHECK: public typealias Element = @_opaqueReturnTypeOf("$s25VariadicOpaqueResultTypes6ScalarV2I2V4nextQrSgyF", 0) __ +// CHECK: } +// CHECK: } + + +public struct S2: Sequence { + public func makeIterator() -> Scalar.I2 { + return .init() + } +} + +// CHECK: public struct S2 : Swift.Sequence { +// CHECK: public func makeIterator() -> VariadicOpaqueResultTypes.Scalar.I2 +// CHECK: public typealias Element = @_opaqueReturnTypeOf("$s25VariadicOpaqueResultTypes6ScalarV2I2V4nextQrSgyF", 0) __ +// CHECK: public typealias Iterator = VariadicOpaqueResultTypes.Scalar.I2 +// CHECK: } + + +/// +/// The remaining examples use the new nested syntax. +/// + +// CHECK: public struct Variadic { +public struct Variadic { + public struct I3: IteratorProtocol { + public mutating func next() -> (some Any)? { return 3 } + } + + // CHECK: public struct I3 : Swift.IteratorProtocol { + // CHECK: public mutating func next() -> (some Any)? + // CHECK: public typealias Element = @_opaqueReturnTypeOf("$s25VariadicOpaqueResultTypes0A0V2I3V4nextQrSgyF", 0) __.__ + // CHECK: } + + public struct Middle { + public struct Inner { + public struct I4: IteratorProtocol { + public mutating func next() -> (some Any)? { return 3 } + } + } + } + + // CHECK: public struct Middle { + // CHECK: public struct Inner { + // CHECK: public struct I4 : Swift.IteratorProtocol { + // CHECK: public mutating func next() -> (some Any)? + // CHECK: public typealias Element = @_opaqueReturnTypeOf("$s25VariadicOpaqueResultTypes0A0V6MiddleV5InnerV2I4V4nextQrSgyF", 0) __.__ + // CHECK: } + // CHECK: } + // CHECK: } +} +// CHECK: } + +// CHECK: public struct S3 : Swift.Sequence { +// CHECK: public func makeIterator() -> VariadicOpaqueResultTypes.Variadic.I3 +// CHECK: public typealias Element = @_opaqueReturnTypeOf("$s25VariadicOpaqueResultTypes0A0V2I3V4nextQrSgyF", 0) __.__ +// CHECK: public typealias Iterator = VariadicOpaqueResultTypes.Variadic.I3 +// CHECK: } +public struct S3: Sequence { + public func makeIterator() -> Variadic.I3 { + return .init() + } +} + +// CHECK: public struct S4 : Swift.Sequence { +// CHECK: public func makeIterator() -> VariadicOpaqueResultTypes.Variadic.Middle.Inner.I4 +// CHECK: public typealias Element = @_opaqueReturnTypeOf("$s25VariadicOpaqueResultTypes0A0V6MiddleV5InnerV2I4V4nextQrSgyF", 0) __.__ +// CHECK: public typealias Iterator = VariadicOpaqueResultTypes.Variadic.Middle.Inner.I4 +// CHECK: } +public struct S4: Sequence { + public func makeIterator() -> Variadic.Middle.Inner.I4 { + return .init() + } +} + diff --git a/test/NameLookup/Inputs/MemberImportVisibility/members_A.swift b/test/NameLookup/Inputs/MemberImportVisibility/members_A.swift index ccbaa997ceac9..1788d9aa02287 100644 --- a/test/NameLookup/Inputs/MemberImportVisibility/members_A.swift +++ b/test/NameLookup/Inputs/MemberImportVisibility/members_A.swift @@ -8,7 +8,9 @@ public struct Y { } extension Y: P where T: P { } -public struct Z: P { } +public struct Z: P { + public init() {} +} infix operator <<< infix operator >>> @@ -25,6 +27,7 @@ extension X { public static func <<<(a: Self, b: Self) -> Self { a } public struct NestedInA {} + public protocol ProtoNestedInA {} } extension Y { @@ -33,6 +36,10 @@ extension Y { public static func <<<(a: Self, b: Self) -> Self { a } } +extension P where Self == Z { + public static var zInA: Z { Z() } +} + public enum EnumInA { case caseInA } diff --git a/test/NameLookup/Inputs/MemberImportVisibility/members_B.swift b/test/NameLookup/Inputs/MemberImportVisibility/members_B.swift index 3b638b2641c5c..d27dcfdf72e89 100644 --- a/test/NameLookup/Inputs/MemberImportVisibility/members_B.swift +++ b/test/NameLookup/Inputs/MemberImportVisibility/members_B.swift @@ -15,6 +15,7 @@ extension X { public struct NestedInB {} package struct NestedInB_package {} + public protocol ProtoNestedInB {} } // Members with the same names are also declared in C. @@ -22,6 +23,8 @@ extension X { public init(_ x: Int) { self.init() } public func ambiguous() -> Int { return 1 } public func ambiguousDisfavored() -> Int { return 1 } + public var ambiguousProp: Bool { return false } + public struct AmbiguousNestedType { } } extension Y { @@ -30,6 +33,11 @@ extension Y { public static func >>>(a: Self, b: Self) -> Self { b } } +extension P where Self == Z { + public static var zInB: Z { Z() } + public static var zAmbiguous: Z { Z() } +} + public enum EnumInB { case caseInB } diff --git a/test/NameLookup/Inputs/MemberImportVisibility/members_C.swift b/test/NameLookup/Inputs/MemberImportVisibility/members_C.swift index a6784d7254d30..c80eb9abb895a 100644 --- a/test/NameLookup/Inputs/MemberImportVisibility/members_C.swift +++ b/test/NameLookup/Inputs/MemberImportVisibility/members_C.swift @@ -13,6 +13,7 @@ extension X { public static func <>(a: Self, b: Self) -> Self { a } public struct NestedInC {} + public protocol ProtoNestedInC {} } // Members with the same names are also declared in B. @@ -20,6 +21,8 @@ extension X { public init(_ x: Bool) { self.init() } public func ambiguous() -> Bool { return false } @_disfavoredOverload public func ambiguousDisfavored() -> Bool { return false } + public var ambiguousProp: Bool { return true } + public struct AmbiguousNestedType { } } extension Y { @@ -28,6 +31,11 @@ extension Y { public static func <>(a: Self, b: Self) -> Self { a } } +extension P where Self == Z { + public static var zInC: Z { Z() } + public static var zAmbiguous: Z { Z() } +} + public enum EnumInC { case caseInC } diff --git a/test/NameLookup/member_import_visibility.swift b/test/NameLookup/member_import_visibility.swift index 3c5b5411846a6..0f58fd75ece6d 100644 --- a/test/NameLookup/member_import_visibility.swift +++ b/test/NameLookup/member_import_visibility.swift @@ -9,7 +9,7 @@ // REQUIRES: swift_feature_MemberImportVisibility import members_C -// expected-member-visibility-note 20{{add import of module 'members_B'}}{{1-1=internal import members_B\n}} +// expected-member-visibility-note 28{{add import of module 'members_B'}}{{1-1=internal import members_B\n}} func testExtensionMembers(x: X, y: Y) { @@ -66,27 +66,39 @@ func testOperatorMembers(x: X, y: Y) { _ = y <> y } +struct GenericType { } + extension X { - var testProperties: (Bool, Bool, Bool, Bool) { - return ( - propXinA, - propXinB, // expected-member-visibility-error{{property 'propXinB' is not available due to missing import of defining module 'members_B'}} - propXinB_package, // expected-member-visibility-error{{property 'propXinB_package' is not available due to missing import of defining module 'members_B}} - propXinC - ) - } + var testPropertyInA: Bool { propXinA } + var testPropertyInB: Bool { propXinB } // expected-member-visibility-error {{property 'propXinB' is not available due to missing import of defining module 'members_B'}} + var testPropertyInB_package: Bool { propXinB_package } // expected-member-visibility-error{{property 'propXinB_package' is not available due to missing import of defining module 'members_B}} + var testPropertyInC: Bool { propXinC } + + // This is not diagnosed in either mode (the property from the nearest scope is always preferred + var testAmbiguousProp: Bool { ambiguousProp } - func testNestedTypes() { + func testTypeExpressions() { _ = NestedInA.self _ = NestedInB.self // expected-member-visibility-error{{struct 'NestedInB' is not available due to missing import of defining module 'members_B'}} _ = NestedInB_package.self // expected-member-visibility-error{{struct 'NestedInB_package' is not available due to missing import of defining module 'members_B'}} + _ = (NestedInB).self // expected-member-visibility-error{{struct 'NestedInB' is not available due to missing import of defining module 'members_B'}} + _ = (NestedInA, NestedInB, NestedInC).self // expected-member-visibility-error{{struct 'NestedInB' is not available due to missing import of defining module 'members_B'}} + _ = GenericType.self // expected-member-visibility-error{{struct 'NestedInB' is not available due to missing import of defining module 'members_B'}} _ = NestedInC.self + _ = AmbiguousNestedType.self } - var nestedInA: NestedInA { fatalError() } - var nestedInB: NestedInB { fatalError() } // expected-member-visibility-error{{struct 'NestedInB' is not available due to missing import of defining module 'members_B'}} - var nestedInB_package: NestedInB_package { fatalError() } // expected-member-visibility-error{{struct 'NestedInB_package' is not available due to missing import of defining module 'members_B'}} - var nestedInC: NestedInC { fatalError() } + var hasNestedInAType: NestedInA { fatalError() } + var hasNestedInBType: NestedInB { fatalError() } // expected-member-visibility-error{{struct 'NestedInB' is not available due to missing import of defining module 'members_B'}} + var hasNestedInB_packageType: NestedInB_package { fatalError() } // expected-member-visibility-error{{struct 'NestedInB_package' is not available due to missing import of defining module 'members_B'}} + var hasNestedInBTrivialTupleType: (NestedInB) { fatalError() } // expected-member-visibility-error{{struct 'NestedInB' is not available due to missing import of defining module 'members_B'}} + var hasTupleTypeContainingNestedInB: (NestedInA, NestedInB, NestedInC) { fatalError() } // expected-member-visibility-error{{struct 'NestedInB' is not available due to missing import of defining module 'members_B'}} + var hasNestedInBAsGenericTypeParameter: GenericType { fatalError() } // expected-member-visibility-error{{struct 'NestedInB' is not available due to missing import of defining module 'members_B'}} + var hasNestedInCType: NestedInC { fatalError() } + + func hasNestedInAInGenericReqs(_ t: T) where T: ProtoNestedInA { } + func hasNestedInBInGenericReqs(_ t: T) where T: ProtoNestedInB { } // expected-member-visibility-error{{protocol 'ProtoNestedInB' is not available due to missing import of defining module 'members_B'}} + func hasNestedInCInGenericReqs(_ t: T) where T: ProtoNestedInC { } } extension X.NestedInA {} @@ -94,7 +106,7 @@ extension X.NestedInB {} // expected-member-visibility-error{{struct 'NestedInB' extension X.NestedInB_package {} // expected-member-visibility-error{{struct 'NestedInB_package' is not available due to missing import of defining module 'members_B'}} extension X.NestedInC {} -func testTopLevelTypes() { +func testTypeExpressionsReferencingTopLevelTypes() { _ = EnumInA.self _ = EnumInB.self // expected-error{{cannot find 'EnumInB' in scope}} _ = EnumInB_package.self // expected-error{{cannot find 'EnumInB_package' in scope}} @@ -107,7 +119,8 @@ class DerivedFromClassInC: DerivedClassInC { override func methodInC() {} } -struct ConformsToProtocolInA: ProtocolInA {} // expected-member-visibility-error{{type 'ConformsToProtocolInA' does not conform to protocol 'ProtocolInA'}} expected-member-visibility-note {{add stubs for conformance}} +// FIXME: Visibility of defaultedRequirementInB() should be diagnosed (rdar://154237873) +struct ConformsToProtocolInA: ProtocolInA {} // expected-member-visibility-error{{type 'ConformsToProtocolInA' does not conform to protocol 'ProtocolInA'}} expected-member-visibility-note {{add stubs for conformance}}{{44-44=\n func defaultedRequirementInB() {\n <#code#>\n \}\n}} func testInheritedMethods( a: BaseClassInA, @@ -128,3 +141,11 @@ func testInheritedMethods( b.overriddenMethod() // expected-member-visibility-error{{instance method 'overriddenMethod()' is not available due to missing import of defining module 'members_B'}} c.overriddenMethod() } + +func testLeadingDotSyntax() { + func takesP(_: T) { } + takesP(.zInA) + takesP(.zInB) // expected-member-visibility-error{{static property 'zInB' is not available due to missing import of defining module 'members_B'}} + takesP(.zInC) + takesP(.zAmbiguous) +} diff --git a/test/Parse/attribute_spacing_swift6.swift b/test/Parse/attribute_spacing_swift6.swift new file mode 100644 index 0000000000000..b791feb475c0c --- /dev/null +++ b/test/Parse/attribute_spacing_swift6.swift @@ -0,0 +1,47 @@ +// RUN: %target-typecheck-verify-swift -swift-version 6 + +@ MainActor // expected-error {{extraneous whitespace between '@' and attribute name}} +class Foo { + func funcWithEscapingClosure(_ x: @ escaping () -> Int) {} // expected-error {{extraneous whitespace between '@' and attribute name}} +} + +@available (*, deprecated) // expected-error {{extraneous whitespace between attribute name and '('}} +func deprecated() {} + +@propertyWrapper +struct MyPropertyWrapper { + var wrappedValue: Int = 1 + + init(param: Int) {} +} + +struct PropertyWrapperTest { + @MyPropertyWrapper (param: 2) // expected-error {{extraneous whitespace between attribute name and '('}} + var x: Int + + @MyPropertyWrapper + (param: 2) // expected-error {{expected 'var' keyword in property declaration}} expected-error {{property declaration does not bind any variables}} expected-error {{expected pattern}} + var y: Int +} + +let closure1 = { @MainActor (a, b) in +// expected-error@-1 {{cannot infer type of closure parameter 'a' without a type annotation}} +// expected-error@-2 {{cannot infer type of closure parameter 'b' without a type annotation}} +} + +let closure2 = { @MainActor + (a: Int, b: Int) in + let _: Int = a +} + +// expected-error@+1 {{extraneous whitespace between '@' and attribute name}} +@ +MainActor +func mainActorFunc() {} + + +@inline // expected-error {{expected '(' in 'inline' attribute}} +(never) func neverInline() {} // expected-error {{expected declaration}} + +@objc +(whatever) func whateverObjC() {} // expected-error {{expected declaration}} diff --git a/test/Parse/fixed_infinite_loops.swift b/test/Parse/fixed_infinite_loops.swift index 711559b4c718b..c0745ac22e12a 100644 --- a/test/Parse/fixed_infinite_loops.swift +++ b/test/Parse/fixed_infinite_loops.swift @@ -1,10 +1,10 @@ // RUN: %target-swift-frontend -parse -verify %s func test1() { - @s // expected-error {{expected statement}} - return + @s + return // expected-error {{expected declaration}} } func test2() { - @unknown // expected-error {{expected statement}} - return + @unknown // expected-error {{unknown attribute 'unknown'}} + return // expected-error {{expected declaration}} } diff --git a/test/Parse/using.swift b/test/Parse/using.swift index 520a856e450c8..277447765652f 100644 --- a/test/Parse/using.swift +++ b/test/Parse/using.swift @@ -68,6 +68,5 @@ struct S { do { @objc using @MainActor - // expected-error@-1 {{expected expression}} - // expected-error@-2 {{declaration is only valid at file scope}} + // expected-error@-1 {{declaration is only valid at file scope}} } diff --git a/test/SILOptimizer/init_static_globals.sil b/test/SILOptimizer/init_static_globals.sil index e1fb97a717bd9..7b84fd441d37e 100644 --- a/test/SILOptimizer/init_static_globals.sil +++ b/test/SILOptimizer/init_static_globals.sil @@ -168,21 +168,6 @@ sil_global [let] @graw2: $Raw // CHECK-LABEL: sil_global [let] @grawArray : $RawArray{{$}} sil_global [let] @grawArray: $RawArray -// CHECK-LABEL: sil_global [let] @gIndirectNone : $Optional = { -// CHECK-NEXT: %initval = enum $Optional, #Optional.none!enumelt -// CHECK-NEXT: } -sil_global [let] @gIndirectNone: $Optional - -// CHECK-LABEL: sil_global [let] @gIndirectSome : $Optional = { -// CHECK-NEXT: %0 = integer_literal $Builtin.Int32, 11 -// CHECK-NEXT: %1 = struct $Int32 (%0) -// CHECK-NEXT: %2 = integer_literal $Builtin.Int32, 10 -// CHECK-NEXT: %3 = struct $Int32 (%2) -// CHECK-NEXT: %4 = struct $TwoFields (%1, %3) -// CHECK-NEXT: %initval = enum $Optional, #Optional.some!enumelt, %4 -// CHECK-NEXT: } -sil_global [let] @gIndirectSome: $Optional - sil @unknownfunc : $@convention(thin) () -> () // CHECK-LABEL: sil [global_init_once_fn] [ossa] @globalinit_trivialglobal_func : @@ -594,29 +579,3 @@ bb0(%0 : $Builtin.RawPointer): return %21 } -sil [global_init_once_fn] [ossa] @globalinit_indirect_none: $@convention(c) (Builtin.RawPointer) -> () { -bb0(%0 : $Builtin.RawPointer): - alloc_global @gIndirectNone - %2 = global_addr @gIndirectNone : $*Optional - inject_enum_addr %2, #Optional.none!enumelt - %21 = tuple () - return %21 -} - -sil [global_init_once_fn] [ossa] @globalinit_indirect_some : $@convention(c) () -> () { -bb0: - alloc_global @gIndirectSome - %1 = global_addr @gIndirectSome : $*Optional - %2 = init_enum_data_addr %1, #Optional.some!enumelt - %3 = integer_literal $Builtin.Int32, 10 - %4 = struct $Int32 (%3) - %5 = struct_element_addr %2, #TwoFields.b - store %4 to [trivial] %5 - %7 = integer_literal $Builtin.Int32, 11 - %8 = struct $Int32 (%7) - %9 = struct_element_addr %2, #TwoFields.a - store %8 to [trivial] %9 - %10 = tuple () - return %10 : $() -} - diff --git a/test/SILOptimizer/static_atomics.swift b/test/SILOptimizer/static_atomics.swift deleted file mode 100644 index 9ee6d23c9893e..0000000000000 --- a/test/SILOptimizer/static_atomics.swift +++ /dev/null @@ -1,65 +0,0 @@ -// RUN: %target-build-swift -parse-as-library -Xfrontend -disable-availability-checking -O %s -module-name=test -emit-sil | %FileCheck %s - -// RUN: %empty-directory(%t) -// RUN: %target-build-swift -parse-as-library -Xfrontend -disable-availability-checking -O -module-name=test %s -o %t/a.out -// RUN: %target-run %t/a.out | %FileCheck %s -check-prefix=CHECK-OUTPUT - -// REQUIRES: executable_test,swift_stdlib_no_asserts,optimized_stdlib -// REQUIRES: synchronization -// UNSUPPORTED: back_deployment_runtime - -import Synchronization - - -struct TwoAtomics: ~Copyable { - let a: Atomic - let b: Atomic -} - -// CHECK-LABEL: sil_global hidden @$s4test7atomic1AA10TwoAtomicsVSgvp : $Optional = { -var atomic1: TwoAtomics? = nil - -// CHECK-LABEL: sil_global hidden @$s4test7atomic2AA10TwoAtomicsVvp : $TwoAtomics = { -let atomic2: TwoAtomics = TwoAtomics(a: Atomic(29), b: Atomic(30)) - -// TODO: this is not initialized statically, because missing IRGen support -var atomic3: TwoAtomics? = TwoAtomics(a: Atomic(27), b: Atomic(28)) - -// CHECK-LABEL: sil_global hidden @$s4test5mutex15Synchronization5MutexVySiGvp : $Mutex = { -let mutex = Mutex(123) - -@main -struct Main { - static func main() { - - precondition(atomic1 == nil) - - // CHECK-OUTPUT: atomic2: 29 30 - print("atomic2:", atomic2.a.load(ordering: .relaxed), atomic2.b.load(ordering: .relaxed)) - - // CHECK-OUTPUT: atomic3: 27 28 - switch atomic3 { - case .some(let a): - print("atomic3:", a.a.load(ordering: .relaxed), a.b.load(ordering: .relaxed)) - case .none: - break - } - - atomic1 = TwoAtomics(a: Atomic(1), b: Atomic(2)) - - // CHECK-OUTPUT: atomic2: 29 30 - print("atomic2:", atomic2.a.load(ordering: .relaxed), atomic2.b.load(ordering: .relaxed)) - - - mutex.withLock { - $0 = $0 + 1 - } - - // CHECK-OUTPUT: mutex: 124 - mutex.withLock { - print("mutex:", $0) - } - } -} - - diff --git a/test/api-digester/Outputs/cake-abi.json b/test/api-digester/Outputs/dump-module/cake-abi.json similarity index 100% rename from test/api-digester/Outputs/cake-abi.json rename to test/api-digester/Outputs/dump-module/cake-abi.json index a1697144c7a31..3dc45f9312fce 100644 --- a/test/api-digester/Outputs/cake-abi.json +++ b/test/api-digester/Outputs/dump-module/cake-abi.json @@ -232,20 +232,6 @@ "Frozen" ], "conformances": [ - { - "kind": "Conformance", - "name": "P1", - "printedName": "P1", - "usr": "s:4cake2P1P", - "mangledName": "$s4cake2P1P" - }, - { - "kind": "Conformance", - "name": "Sendable", - "printedName": "Sendable", - "usr": "s:s8SendableP", - "mangledName": "$ss8SendableP" - }, { "kind": "Conformance", "name": "BitwiseCopyable", @@ -267,6 +253,13 @@ "usr": "s:s9EscapableP", "mangledName": "$ss9EscapableP" }, + { + "kind": "Conformance", + "name": "Sendable", + "printedName": "Sendable", + "usr": "s:s8SendableP", + "mangledName": "$ss8SendableP" + }, { "kind": "Conformance", "name": "SendableMetatype", @@ -274,6 +267,13 @@ "usr": "s:s16SendableMetatypeP", "mangledName": "$ss16SendableMetatypeP" }, + { + "kind": "Conformance", + "name": "P1", + "printedName": "P1", + "usr": "s:4cake2P1P", + "mangledName": "$s4cake2P1P" + }, { "kind": "Conformance", "name": "P2", @@ -801,6 +801,13 @@ "enumRawTypeName": "Int", "isEnumExhaustive": true, "conformances": [ + { + "kind": "Conformance", + "name": "Copyable", + "printedName": "Copyable", + "usr": "s:s8CopyableP", + "mangledName": "$ss8CopyableP" + }, { "kind": "Conformance", "name": "Equatable", @@ -808,6 +815,13 @@ "usr": "s:SQ", "mangledName": "$sSQ" }, + { + "kind": "Conformance", + "name": "Escapable", + "printedName": "Escapable", + "usr": "s:s9EscapableP", + "mangledName": "$ss9EscapableP" + }, { "kind": "Conformance", "name": "Hashable", @@ -836,20 +850,6 @@ ], "usr": "s:SY", "mangledName": "$sSY" - }, - { - "kind": "Conformance", - "name": "Copyable", - "printedName": "Copyable", - "usr": "s:s8CopyableP", - "mangledName": "$ss8CopyableP" - }, - { - "kind": "Conformance", - "name": "Escapable", - "printedName": "Escapable", - "usr": "s:s9EscapableP", - "mangledName": "$ss9EscapableP" } ] }, @@ -1047,13 +1047,6 @@ "Frozen" ], "conformances": [ - { - "kind": "Conformance", - "name": "Sendable", - "printedName": "Sendable", - "usr": "s:s8SendableP", - "mangledName": "$ss8SendableP" - }, { "kind": "Conformance", "name": "BitwiseCopyable", @@ -1075,6 +1068,13 @@ "usr": "s:s9EscapableP", "mangledName": "$ss9EscapableP" }, + { + "kind": "Conformance", + "name": "Sendable", + "printedName": "Sendable", + "usr": "s:s8SendableP", + "mangledName": "$ss8SendableP" + }, { "kind": "Conformance", "name": "SendableMetatype", @@ -1998,24 +1998,10 @@ "conformances": [ { "kind": "Conformance", - "name": "FixedWidthInteger", - "printedName": "FixedWidthInteger", - "usr": "s:s17FixedWidthIntegerP", - "mangledName": "$ss17FixedWidthIntegerP" - }, - { - "kind": "Conformance", - "name": "SignedInteger", - "printedName": "SignedInteger", - "usr": "s:SZ", - "mangledName": "$sSZ" - }, - { - "kind": "Conformance", - "name": "_ExpressibleByBuiltinIntegerLiteral", - "printedName": "_ExpressibleByBuiltinIntegerLiteral", - "usr": "s:s35_ExpressibleByBuiltinIntegerLiteralP", - "mangledName": "$ss35_ExpressibleByBuiltinIntegerLiteralP" + "name": "AdditiveArithmetic", + "printedName": "AdditiveArithmetic", + "usr": "s:s18AdditiveArithmeticP", + "mangledName": "$ss18AdditiveArithmeticP" }, { "kind": "Conformance", @@ -2041,97 +2027,24 @@ }, { "kind": "Conformance", - "name": "LosslessStringConvertible", - "printedName": "LosslessStringConvertible", - "usr": "s:s25LosslessStringConvertibleP", - "mangledName": "$ss25LosslessStringConvertibleP" - }, - { - "kind": "Conformance", - "name": "SignedNumeric", - "printedName": "SignedNumeric", - "usr": "s:s13SignedNumericP", - "mangledName": "$ss13SignedNumericP" - }, - { - "kind": "Conformance", - "name": "Numeric", - "printedName": "Numeric", - "children": [ - { - "kind": "TypeWitness", - "name": "Magnitude", - "printedName": "Magnitude", - "children": [ - { - "kind": "TypeNominal", - "name": "UInt", - "printedName": "Swift.UInt", - "usr": "s:Su" - } - ] - } - ], - "usr": "s:Sj", - "mangledName": "$sSj" - }, - { - "kind": "Conformance", - "name": "CustomStringConvertible", - "printedName": "CustomStringConvertible", - "usr": "s:s23CustomStringConvertibleP", - "mangledName": "$ss23CustomStringConvertibleP" - }, - { - "kind": "Conformance", - "name": "Strideable", - "printedName": "Strideable", - "children": [ - { - "kind": "TypeWitness", - "name": "Stride", - "printedName": "Stride", - "children": [ - { - "kind": "TypeNominal", - "name": "Int", - "printedName": "Swift.Int", - "usr": "s:Si" - } - ] - } - ], - "usr": "s:Sx", - "mangledName": "$sSx" + "name": "BitwiseCopyable", + "printedName": "BitwiseCopyable", + "usr": "s:s15BitwiseCopyableP", + "mangledName": "$ss15BitwiseCopyableP" }, { "kind": "Conformance", - "name": "AdditiveArithmetic", - "printedName": "AdditiveArithmetic", - "usr": "s:s18AdditiveArithmeticP", - "mangledName": "$ss18AdditiveArithmeticP" + "name": "CVarArg", + "printedName": "CVarArg", + "usr": "s:s7CVarArgP", + "mangledName": "$ss7CVarArgP" }, { "kind": "Conformance", - "name": "ExpressibleByIntegerLiteral", - "printedName": "ExpressibleByIntegerLiteral", - "children": [ - { - "kind": "TypeWitness", - "name": "IntegerLiteralType", - "printedName": "IntegerLiteralType", - "children": [ - { - "kind": "TypeNominal", - "name": "Int", - "printedName": "Swift.Int", - "usr": "s:Si" - } - ] - } - ], - "usr": "s:s27ExpressibleByIntegerLiteralP", - "mangledName": "$ss27ExpressibleByIntegerLiteralP" + "name": "CodingKeyRepresentable", + "printedName": "CodingKeyRepresentable", + "usr": "s:s22CodingKeyRepresentableP", + "mangledName": "$ss22CodingKeyRepresentableP" }, { "kind": "Conformance", @@ -2149,24 +2062,17 @@ }, { "kind": "Conformance", - "name": "Escapable", - "printedName": "Escapable", - "usr": "s:s9EscapableP", - "mangledName": "$ss9EscapableP" - }, - { - "kind": "Conformance", - "name": "P1", - "printedName": "P1", - "usr": "s:4cake2P1P", - "mangledName": "$s4cake2P1P" + "name": "CustomReflectable", + "printedName": "CustomReflectable", + "usr": "s:s17CustomReflectableP", + "mangledName": "$ss17CustomReflectableP" }, { "kind": "Conformance", - "name": "Encodable", - "printedName": "Encodable", - "usr": "s:SE", - "mangledName": "$sSE" + "name": "CustomStringConvertible", + "printedName": "CustomStringConvertible", + "usr": "s:s23CustomStringConvertibleP", + "mangledName": "$ss23CustomStringConvertibleP" }, { "kind": "Conformance", @@ -2177,38 +2083,53 @@ }, { "kind": "Conformance", - "name": "CodingKeyRepresentable", - "printedName": "CodingKeyRepresentable", - "usr": "s:s22CodingKeyRepresentableP", - "mangledName": "$ss22CodingKeyRepresentableP" + "name": "Encodable", + "printedName": "Encodable", + "usr": "s:SE", + "mangledName": "$sSE" }, { "kind": "Conformance", - "name": "CustomReflectable", - "printedName": "CustomReflectable", - "usr": "s:s17CustomReflectableP", - "mangledName": "$ss17CustomReflectableP" + "name": "Equatable", + "printedName": "Equatable", + "usr": "s:SQ", + "mangledName": "$sSQ" }, { "kind": "Conformance", - "name": "_CustomPlaygroundQuickLookable", - "printedName": "_CustomPlaygroundQuickLookable", - "usr": "s:s30_CustomPlaygroundQuickLookableP", - "mangledName": "$ss30_CustomPlaygroundQuickLookableP" + "name": "Escapable", + "printedName": "Escapable", + "usr": "s:s9EscapableP", + "mangledName": "$ss9EscapableP" }, { "kind": "Conformance", - "name": "MirrorPath", - "printedName": "MirrorPath", - "usr": "s:s10MirrorPathP", - "mangledName": "$ss10MirrorPathP" + "name": "ExpressibleByIntegerLiteral", + "printedName": "ExpressibleByIntegerLiteral", + "children": [ + { + "kind": "TypeWitness", + "name": "IntegerLiteralType", + "printedName": "IntegerLiteralType", + "children": [ + { + "kind": "TypeNominal", + "name": "Int", + "printedName": "Swift.Int", + "usr": "s:Si" + } + ] + } + ], + "usr": "s:s27ExpressibleByIntegerLiteralP", + "mangledName": "$ss27ExpressibleByIntegerLiteralP" }, { "kind": "Conformance", - "name": "CVarArg", - "printedName": "CVarArg", - "usr": "s:s7CVarArgP", - "mangledName": "$ss7CVarArgP" + "name": "FixedWidthInteger", + "printedName": "FixedWidthInteger", + "usr": "s:s17FixedWidthIntegerP", + "mangledName": "$ss17FixedWidthIntegerP" }, { "kind": "Conformance", @@ -2219,31 +2140,39 @@ }, { "kind": "Conformance", - "name": "Equatable", - "printedName": "Equatable", - "usr": "s:SQ", - "mangledName": "$sSQ" - }, - { - "kind": "Conformance", - "name": "_HasCustomAnyHashableRepresentation", - "printedName": "_HasCustomAnyHashableRepresentation", - "usr": "s:s35_HasCustomAnyHashableRepresentationP", - "mangledName": "$ss35_HasCustomAnyHashableRepresentationP" + "name": "LosslessStringConvertible", + "printedName": "LosslessStringConvertible", + "usr": "s:s25LosslessStringConvertibleP", + "mangledName": "$ss25LosslessStringConvertibleP" }, { "kind": "Conformance", - "name": "Sendable", - "printedName": "Sendable", - "usr": "s:s8SendableP", - "mangledName": "$ss8SendableP" + "name": "MirrorPath", + "printedName": "MirrorPath", + "usr": "s:s10MirrorPathP", + "mangledName": "$ss10MirrorPathP" }, { "kind": "Conformance", - "name": "SendableMetatype", - "printedName": "SendableMetatype", - "usr": "s:s16SendableMetatypeP", - "mangledName": "$ss16SendableMetatypeP" + "name": "Numeric", + "printedName": "Numeric", + "children": [ + { + "kind": "TypeWitness", + "name": "Magnitude", + "printedName": "Magnitude", + "children": [ + { + "kind": "TypeNominal", + "name": "UInt", + "printedName": "Swift.UInt", + "usr": "s:Su" + } + ] + } + ], + "usr": "s:Sj", + "mangledName": "$sSj" }, { "kind": "Conformance", @@ -2347,10 +2276,81 @@ }, { "kind": "Conformance", - "name": "BitwiseCopyable", - "printedName": "BitwiseCopyable", - "usr": "s:s15BitwiseCopyableP", - "mangledName": "$ss15BitwiseCopyableP" + "name": "Sendable", + "printedName": "Sendable", + "usr": "s:s8SendableP", + "mangledName": "$ss8SendableP" + }, + { + "kind": "Conformance", + "name": "SendableMetatype", + "printedName": "SendableMetatype", + "usr": "s:s16SendableMetatypeP", + "mangledName": "$ss16SendableMetatypeP" + }, + { + "kind": "Conformance", + "name": "SignedInteger", + "printedName": "SignedInteger", + "usr": "s:SZ", + "mangledName": "$sSZ" + }, + { + "kind": "Conformance", + "name": "SignedNumeric", + "printedName": "SignedNumeric", + "usr": "s:s13SignedNumericP", + "mangledName": "$ss13SignedNumericP" + }, + { + "kind": "Conformance", + "name": "Strideable", + "printedName": "Strideable", + "children": [ + { + "kind": "TypeWitness", + "name": "Stride", + "printedName": "Stride", + "children": [ + { + "kind": "TypeNominal", + "name": "Int", + "printedName": "Swift.Int", + "usr": "s:Si" + } + ] + } + ], + "usr": "s:Sx", + "mangledName": "$sSx" + }, + { + "kind": "Conformance", + "name": "_CustomPlaygroundQuickLookable", + "printedName": "_CustomPlaygroundQuickLookable", + "usr": "s:s30_CustomPlaygroundQuickLookableP", + "mangledName": "$ss30_CustomPlaygroundQuickLookableP" + }, + { + "kind": "Conformance", + "name": "_ExpressibleByBuiltinIntegerLiteral", + "printedName": "_ExpressibleByBuiltinIntegerLiteral", + "usr": "s:s35_ExpressibleByBuiltinIntegerLiteralP", + "mangledName": "$ss35_ExpressibleByBuiltinIntegerLiteralP" + }, + { + "kind": "Conformance", + "name": "_HasCustomAnyHashableRepresentation", + "printedName": "_HasCustomAnyHashableRepresentation", + "usr": "s:s35_HasCustomAnyHashableRepresentationP", + "mangledName": "$ss35_HasCustomAnyHashableRepresentationP" + }, + { + "kind": "Conformance", + "name": "P1", + "printedName": "P1", + "usr": "s:4cake2P1P", + "mangledName": "$s4cake2P1P" } ] } diff --git a/test/api-digester/Outputs/cake.json b/test/api-digester/Outputs/dump-module/cake.json similarity index 100% rename from test/api-digester/Outputs/cake.json rename to test/api-digester/Outputs/dump-module/cake.json index 5f1d958671cea..ddd11114a05fd 100644 --- a/test/api-digester/Outputs/cake.json +++ b/test/api-digester/Outputs/dump-module/cake.json @@ -237,20 +237,6 @@ "Frozen" ], "conformances": [ - { - "kind": "Conformance", - "name": "P1", - "printedName": "P1", - "usr": "s:4cake2P1P", - "mangledName": "$s4cake2P1P" - }, - { - "kind": "Conformance", - "name": "Sendable", - "printedName": "Sendable", - "usr": "s:s8SendableP", - "mangledName": "$ss8SendableP" - }, { "kind": "Conformance", "name": "BitwiseCopyable", @@ -272,6 +258,13 @@ "usr": "s:s9EscapableP", "mangledName": "$ss9EscapableP" }, + { + "kind": "Conformance", + "name": "Sendable", + "printedName": "Sendable", + "usr": "s:s8SendableP", + "mangledName": "$ss8SendableP" + }, { "kind": "Conformance", "name": "SendableMetatype", @@ -279,6 +272,13 @@ "usr": "s:s16SendableMetatypeP", "mangledName": "$ss16SendableMetatypeP" }, + { + "kind": "Conformance", + "name": "P1", + "printedName": "P1", + "usr": "s:4cake2P1P", + "mangledName": "$s4cake2P1P" + }, { "kind": "Conformance", "name": "P2", @@ -814,6 +814,13 @@ "enumRawTypeName": "Int", "isEnumExhaustive": true, "conformances": [ + { + "kind": "Conformance", + "name": "Copyable", + "printedName": "Copyable", + "usr": "s:s8CopyableP", + "mangledName": "$ss8CopyableP" + }, { "kind": "Conformance", "name": "Equatable", @@ -821,6 +828,13 @@ "usr": "s:SQ", "mangledName": "$sSQ" }, + { + "kind": "Conformance", + "name": "Escapable", + "printedName": "Escapable", + "usr": "s:s9EscapableP", + "mangledName": "$ss9EscapableP" + }, { "kind": "Conformance", "name": "Hashable", @@ -849,20 +863,6 @@ ], "usr": "s:SY", "mangledName": "$sSY" - }, - { - "kind": "Conformance", - "name": "Copyable", - "printedName": "Copyable", - "usr": "s:s8CopyableP", - "mangledName": "$ss8CopyableP" - }, - { - "kind": "Conformance", - "name": "Escapable", - "printedName": "Escapable", - "usr": "s:s9EscapableP", - "mangledName": "$ss9EscapableP" } ] }, @@ -990,13 +990,6 @@ "Frozen" ], "conformances": [ - { - "kind": "Conformance", - "name": "Sendable", - "printedName": "Sendable", - "usr": "s:s8SendableP", - "mangledName": "$ss8SendableP" - }, { "kind": "Conformance", "name": "BitwiseCopyable", @@ -1018,6 +1011,13 @@ "usr": "s:s9EscapableP", "mangledName": "$ss9EscapableP" }, + { + "kind": "Conformance", + "name": "Sendable", + "printedName": "Sendable", + "usr": "s:s8SendableP", + "mangledName": "$ss8SendableP" + }, { "kind": "Conformance", "name": "SendableMetatype", @@ -1885,17 +1885,10 @@ "conformances": [ { "kind": "Conformance", - "name": "FixedWidthInteger", - "printedName": "FixedWidthInteger", - "usr": "s:s17FixedWidthIntegerP", - "mangledName": "$ss17FixedWidthIntegerP" - }, - { - "kind": "Conformance", - "name": "SignedInteger", - "printedName": "SignedInteger", - "usr": "s:SZ", - "mangledName": "$sSZ" + "name": "AdditiveArithmetic", + "printedName": "AdditiveArithmetic", + "usr": "s:s18AdditiveArithmeticP", + "mangledName": "$ss18AdditiveArithmeticP" }, { "kind": "Conformance", @@ -1921,46 +1914,45 @@ }, { "kind": "Conformance", - "name": "LosslessStringConvertible", - "printedName": "LosslessStringConvertible", - "usr": "s:s25LosslessStringConvertibleP", - "mangledName": "$ss25LosslessStringConvertibleP" + "name": "BitwiseCopyable", + "printedName": "BitwiseCopyable", + "usr": "s:s15BitwiseCopyableP", + "mangledName": "$ss15BitwiseCopyableP" }, { "kind": "Conformance", - "name": "SignedNumeric", - "printedName": "SignedNumeric", - "usr": "s:s13SignedNumericP", - "mangledName": "$ss13SignedNumericP" + "name": "CVarArg", + "printedName": "CVarArg", + "usr": "s:s7CVarArgP", + "mangledName": "$ss7CVarArgP" }, { "kind": "Conformance", - "name": "Numeric", - "printedName": "Numeric", - "children": [ - { - "kind": "TypeWitness", - "name": "Magnitude", - "printedName": "Magnitude", - "children": [ - { - "kind": "TypeNameAlias", - "name": "Magnitude", - "printedName": "Swift.Int.Magnitude", - "children": [ - { - "kind": "TypeNominal", - "name": "UInt", - "printedName": "Swift.UInt", - "usr": "s:Su" - } - ] - } - ] - } - ], - "usr": "s:Sj", - "mangledName": "$sSj" + "name": "CodingKeyRepresentable", + "printedName": "CodingKeyRepresentable", + "usr": "s:s22CodingKeyRepresentableP", + "mangledName": "$ss22CodingKeyRepresentableP" + }, + { + "kind": "Conformance", + "name": "Comparable", + "printedName": "Comparable", + "usr": "s:SL", + "mangledName": "$sSL" + }, + { + "kind": "Conformance", + "name": "Copyable", + "printedName": "Copyable", + "usr": "s:s8CopyableP", + "mangledName": "$ss8CopyableP" + }, + { + "kind": "Conformance", + "name": "CustomReflectable", + "printedName": "CustomReflectable", + "usr": "s:s17CustomReflectableP", + "mangledName": "$ss17CustomReflectableP" }, { "kind": "Conformance", @@ -1971,32 +1963,31 @@ }, { "kind": "Conformance", - "name": "Strideable", - "printedName": "Strideable", - "children": [ - { - "kind": "TypeWitness", - "name": "Stride", - "printedName": "Stride", - "children": [ - { - "kind": "TypeNominal", - "name": "Int", - "printedName": "Swift.Int", - "usr": "s:Si" - } - ] - } - ], - "usr": "s:Sx", - "mangledName": "$sSx" + "name": "Decodable", + "printedName": "Decodable", + "usr": "s:Se", + "mangledName": "$sSe" }, { "kind": "Conformance", - "name": "AdditiveArithmetic", - "printedName": "AdditiveArithmetic", - "usr": "s:s18AdditiveArithmeticP", - "mangledName": "$ss18AdditiveArithmeticP" + "name": "Encodable", + "printedName": "Encodable", + "usr": "s:SE", + "mangledName": "$sSE" + }, + { + "kind": "Conformance", + "name": "Equatable", + "printedName": "Equatable", + "usr": "s:SQ", + "mangledName": "$sSQ" + }, + { + "kind": "Conformance", + "name": "Escapable", + "printedName": "Escapable", + "usr": "s:s9EscapableP", + "mangledName": "$ss9EscapableP" }, { "kind": "Conformance", @@ -2029,73 +2020,10 @@ }, { "kind": "Conformance", - "name": "Comparable", - "printedName": "Comparable", - "usr": "s:SL", - "mangledName": "$sSL" - }, - { - "kind": "Conformance", - "name": "Copyable", - "printedName": "Copyable", - "usr": "s:s8CopyableP", - "mangledName": "$ss8CopyableP" - }, - { - "kind": "Conformance", - "name": "Escapable", - "printedName": "Escapable", - "usr": "s:s9EscapableP", - "mangledName": "$ss9EscapableP" - }, - { - "kind": "Conformance", - "name": "P1", - "printedName": "P1", - "usr": "s:4cake2P1P", - "mangledName": "$s4cake2P1P" - }, - { - "kind": "Conformance", - "name": "Encodable", - "printedName": "Encodable", - "usr": "s:SE", - "mangledName": "$sSE" - }, - { - "kind": "Conformance", - "name": "Decodable", - "printedName": "Decodable", - "usr": "s:Se", - "mangledName": "$sSe" - }, - { - "kind": "Conformance", - "name": "CodingKeyRepresentable", - "printedName": "CodingKeyRepresentable", - "usr": "s:s22CodingKeyRepresentableP", - "mangledName": "$ss22CodingKeyRepresentableP" - }, - { - "kind": "Conformance", - "name": "CustomReflectable", - "printedName": "CustomReflectable", - "usr": "s:s17CustomReflectableP", - "mangledName": "$ss17CustomReflectableP" - }, - { - "kind": "Conformance", - "name": "MirrorPath", - "printedName": "MirrorPath", - "usr": "s:s10MirrorPathP", - "mangledName": "$ss10MirrorPathP" - }, - { - "kind": "Conformance", - "name": "CVarArg", - "printedName": "CVarArg", - "usr": "s:s7CVarArgP", - "mangledName": "$ss7CVarArgP" + "name": "FixedWidthInteger", + "printedName": "FixedWidthInteger", + "usr": "s:s17FixedWidthIntegerP", + "mangledName": "$ss17FixedWidthIntegerP" }, { "kind": "Conformance", @@ -2106,24 +2034,46 @@ }, { "kind": "Conformance", - "name": "Equatable", - "printedName": "Equatable", - "usr": "s:SQ", - "mangledName": "$sSQ" + "name": "LosslessStringConvertible", + "printedName": "LosslessStringConvertible", + "usr": "s:s25LosslessStringConvertibleP", + "mangledName": "$ss25LosslessStringConvertibleP" }, { "kind": "Conformance", - "name": "Sendable", - "printedName": "Sendable", - "usr": "s:s8SendableP", - "mangledName": "$ss8SendableP" + "name": "MirrorPath", + "printedName": "MirrorPath", + "usr": "s:s10MirrorPathP", + "mangledName": "$ss10MirrorPathP" }, { "kind": "Conformance", - "name": "SendableMetatype", - "printedName": "SendableMetatype", - "usr": "s:s16SendableMetatypeP", - "mangledName": "$ss16SendableMetatypeP" + "name": "Numeric", + "printedName": "Numeric", + "children": [ + { + "kind": "TypeWitness", + "name": "Magnitude", + "printedName": "Magnitude", + "children": [ + { + "kind": "TypeNameAlias", + "name": "Magnitude", + "printedName": "Swift.Int.Magnitude", + "children": [ + { + "kind": "TypeNominal", + "name": "UInt", + "printedName": "Swift.UInt", + "usr": "s:Su" + } + ] + } + ] + } + ], + "usr": "s:Sj", + "mangledName": "$sSj" }, { "kind": "Conformance", @@ -2234,10 +2184,60 @@ }, { "kind": "Conformance", - "name": "BitwiseCopyable", - "printedName": "BitwiseCopyable", - "usr": "s:s15BitwiseCopyableP", - "mangledName": "$ss15BitwiseCopyableP" + "name": "Sendable", + "printedName": "Sendable", + "usr": "s:s8SendableP", + "mangledName": "$ss8SendableP" + }, + { + "kind": "Conformance", + "name": "SendableMetatype", + "printedName": "SendableMetatype", + "usr": "s:s16SendableMetatypeP", + "mangledName": "$ss16SendableMetatypeP" + }, + { + "kind": "Conformance", + "name": "SignedInteger", + "printedName": "SignedInteger", + "usr": "s:SZ", + "mangledName": "$sSZ" + }, + { + "kind": "Conformance", + "name": "SignedNumeric", + "printedName": "SignedNumeric", + "usr": "s:s13SignedNumericP", + "mangledName": "$ss13SignedNumericP" + }, + { + "kind": "Conformance", + "name": "Strideable", + "printedName": "Strideable", + "children": [ + { + "kind": "TypeWitness", + "name": "Stride", + "printedName": "Stride", + "children": [ + { + "kind": "TypeNominal", + "name": "Int", + "printedName": "Swift.Int", + "usr": "s:Si" + } + ] + } + ], + "usr": "s:Sx", + "mangledName": "$sSx" + }, + { + "kind": "Conformance", + "name": "P1", + "printedName": "P1", + "usr": "s:4cake2P1P", + "mangledName": "$s4cake2P1P" } ] } diff --git a/test/api-digester/dump-module.swift b/test/api-digester/dump-module.swift index 9f37802413831..d6c4abefb94a5 100644 --- a/test/api-digester/dump-module.swift +++ b/test/api-digester/dump-module.swift @@ -1,19 +1,22 @@ // REQUIRES: OS=macosx + // RUN: %empty-directory(%t.mod) // RUN: %empty-directory(%t.sdk) // RUN: %empty-directory(%t.module-cache) + // RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -emit-module -o %t.mod/cake.swiftmodule %S/Inputs/cake.swift -parse-as-library -I %S/Inputs/ClangCake %clang-importer-sdk-nosource // RUN: %api-digester -dump-sdk -module cake -o %t.dump.json -module-cache-path %t.module-cache -swift-only -I %t.mod -I %S/Inputs/ClangCake %clang-importer-sdk-nosource -avoid-tool-args -// RUN: diff -u %S/Outputs/cake.json %t.dump.json +// RUN: diff -u %S/Outputs/dump-module/cake.json %t.dump.json // RUN: %api-digester -dump-sdk -module cake -o %t.dump.json -module-cache-path %t.module-cache -swift-only -I %t.mod -abi -I %S/Inputs/ClangCake %clang-importer-sdk-nosource -avoid-tool-args -// RUN: diff -u %S/Outputs/cake-abi.json %t.dump.json -// RUN: %api-digester -diagnose-sdk --input-paths %t.dump.json -input-paths %S/Outputs/cake.json +// RUN: diff -u %S/Outputs/dump-module/cake-abi.json %t.dump.json + +// RUN: %api-digester -diagnose-sdk --input-paths %t.dump.json -input-paths %S/Outputs/dump-module/cake.json // Round-trip testing: -// RUN: %api-digester -deserialize-sdk --input-paths %S/Outputs/cake.json -o %t.dump.json -// RUN: diff -u %S/Outputs/cake.json %t.dump.json -// RUN: %api-digester -deserialize-sdk --input-paths %S/Outputs/cake-abi.json -o %t.dump.json -// RUN: diff -u %S/Outputs/cake-abi.json %t.dump.json +// RUN: %api-digester -deserialize-sdk --input-paths %S/Outputs/dump-module/cake.json -o %t.dump.json +// RUN: diff -u %S/Outputs/dump-module/cake.json %t.dump.json +// RUN: %api-digester -deserialize-sdk --input-paths %S/Outputs/dump-module/cake-abi.json -o %t.dump.json +// RUN: diff -u %S/Outputs/dump-module/cake-abi.json %t.dump.json // The input JSON files need to be modified when standard library declarations // are reordered. This is expected behavior and we simply shouldn't run the test diff --git a/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp b/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp index 59fcdca5af705..39d06a12a279f 100644 --- a/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp +++ b/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp @@ -174,6 +174,7 @@ bool TestOptions::parseArgs(llvm::ArrayRef Args) { << "- complete.setpopularapi\n" << "- typecontextinfo\n" << "- conformingmethods\n" + << "- signaturehelp\n" << "- cursor\n" << "- related-idents\n" << "- syntax-map\n" diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp index 704aeb452bb88..fb5af648f676e 100644 --- a/tools/swift-ide-test/swift-ide-test.cpp +++ b/tools/swift-ide-test/swift-ide-test.cpp @@ -4571,8 +4571,8 @@ int main(int argc, char *argv[]) { options::ModuleCachePath[options::ModuleCachePath.size()-1]; } if (!options::AccessNotesPath.empty()) { - InitInvok.getFrontendOptions().AccessNotesPath = - options::AccessNotesPath[options::AccessNotesPath.size()-1]; + InitInvok.getLangOptions().AccessNotesPath = + options::AccessNotesPath[options::AccessNotesPath.size() - 1]; } if (options::ParseAsLibrary) { InitInvok.getFrontendOptions().InputMode = diff --git a/unittests/runtime/CompatibilityOverrideRuntime.cpp b/unittests/runtime/CompatibilityOverrideRuntime.cpp index 63a7cb5110d02..46e4ed0c54a83 100644 --- a/unittests/runtime/CompatibilityOverrideRuntime.cpp +++ b/unittests/runtime/CompatibilityOverrideRuntime.cpp @@ -12,7 +12,7 @@ #if defined(__APPLE__) && defined(__MACH__) -#define SWIFT_TARGET_LIBRARY_NAME swiftRuntime +#define SWIFT_TARGET_LIBRARY_NAME swiftRuntimeCore #include "../../stdlib/public/CompatibilityOverride/CompatibilityOverride.h" #include "swift/Runtime/Casting.h" @@ -55,14 +55,14 @@ namespace { struct OverrideSection { uintptr_t version; - + #define OVERRIDE(name, ret, attrs, ccAttrs, namespace, typedArgs, namedArgs) \ Override_ ## name name; #include "../../stdlib/public/CompatibilityOverride/CompatibilityOverrideRuntime.def" }; OverrideSection RuntimeOverrides - __attribute__((section("__DATA," COMPATIBILITY_OVERRIDE_SECTION_NAME_swiftRuntime))) = { + __attribute__((section("__DATA," COMPATIBILITY_OVERRIDE_SECTION_NAME_swiftRuntimeCore))) = { 0, #define OVERRIDE(name, ret, attrs, ccAttrs, namespace, typedArgs, namedArgs) \ name ## Override, diff --git a/utils/update_checkout/update-checkout-config.json b/utils/update_checkout/update-checkout-config.json index 003b8ab6bc274..c3389f9838a13 100644 --- a/utils/update_checkout/update-checkout-config.json +++ b/utils/update_checkout/update-checkout-config.json @@ -137,7 +137,7 @@ "cmark": "gfm", "llbuild": "main", "swift-build": "main", - "swift-toolchain-sqlite": "1.0.1", + "swift-toolchain-sqlite": "1.0.7", "swift-tools-support-core": "main", "swiftpm": "main", "swift-argument-parser": "1.5.1", @@ -181,7 +181,7 @@ "libxml2": "v2.11.5", "zlib": "v1.3.1", "mimalloc": "v3.0.3", - "swift-subprocess": "development-snapshot-2025-07-21" + "swift-subprocess": "0.1" } }, "release/6.2": { @@ -565,7 +565,7 @@ "cmark": "gfm", "llbuild": "main", "swift-build": "main", - "swift-toolchain-sqlite": "1.0.1", + "swift-toolchain-sqlite": "1.0.7", "swift-tools-support-core": "main", "swiftpm": "main", "swift-argument-parser": "1.5.1", @@ -609,7 +609,7 @@ "libxml2": "v2.11.5", "zlib": "v1.3.1", "mimalloc": "v3.0.3", - "swift-subprocess": "development-snapshot-2025-07-21" + "swift-subprocess": "0.1" } }, "next" : { @@ -623,7 +623,7 @@ "cmark": "gfm", "llbuild": "main", "swift-build": "main", - "swift-toolchain-sqlite": "1.0.1", + "swift-toolchain-sqlite": "1.0.7", "swift-tools-support-core": "main", "swiftpm": "main", "swift-argument-parser": "1.5.1", @@ -667,7 +667,7 @@ "libxml2": "v2.11.5", "zlib": "v1.3.1", "mimalloc": "v3.0.3", - "swift-subprocess": "development-snapshot-2025-07-21" + "swift-subprocess": "0.1" } } } diff --git a/validation-test/compiler_crashers_2/eeeed99e112fc53.swift b/validation-test/compiler_crashers_2_fixed/eeeed99e112fc53.swift similarity index 85% rename from validation-test/compiler_crashers_2/eeeed99e112fc53.swift rename to validation-test/compiler_crashers_2_fixed/eeeed99e112fc53.swift index 48ba58782e9d1..d00e4e36312cd 100644 --- a/validation-test/compiler_crashers_2/eeeed99e112fc53.swift +++ b/validation-test/compiler_crashers_2_fixed/eeeed99e112fc53.swift @@ -1,3 +1,3 @@ // {"kind":"typecheck","signature":"swift::Parser::parseTypeAttribute(llvm::PointerUnion&, swift::SourceLoc, swift::SourceLoc, swift::Parser::ParseTypeReason, bool)","signatureAssert":"Assertion failed: (Tok.is(K) && \"Consuming wrong token kind\"), function consumeToken"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s @opened)