Skip to content

🌸 [6.1] Work around Foundation NS_TYPED_ENUM bug #78989

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions include/swift/SIL/PrettyStackTrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "swift/SIL/SILLocation.h"
#include "swift/SIL/SILNode.h"
#include "swift/SIL/SILDeclRef.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/PrettyStackTrace.h"
Expand Down Expand Up @@ -82,6 +83,18 @@ class PrettyStackTraceSILNode : public llvm::PrettyStackTraceEntry {
virtual void print(llvm::raw_ostream &OS) const override;
};

/// Observe that we are processing a reference to a SIL decl.
class PrettyStackTraceSILDeclRef : public llvm::PrettyStackTraceEntry {
SILDeclRef declRef;
StringRef action;

public:
PrettyStackTraceSILDeclRef(const char *action, SILDeclRef declRef)
: declRef(declRef), action(action) {}

virtual void print(llvm::raw_ostream &os) const override;
};

} // end namespace swift

#endif
3 changes: 3 additions & 0 deletions lib/AST/ASTDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5777,6 +5777,7 @@ namespace {
printCommon(#Name, label); \
\
printFieldQuoted(T->getDecl()->printRef(), Label::always("decl")); \
printFlag(T->getDecl()->hasClangNode(), "foreign"); \
\
if (T->getParent()) \
printRec(T->getParent(), Label::always("parent")); \
Expand All @@ -5790,6 +5791,7 @@ namespace {
BoundGeneric##TypeClass *T, Label label) { \
printCommon("bound_generic_" #Name, label); \
printFieldQuoted(T->getDecl()->printRef(), Label::always("decl")); \
printFlag(T->getDecl()->hasClangNode(), "foreign"); \
if (T->getParent()) \
printRec(T->getParent(), Label::always("parent")); \
printList(T->getGenericArgs(), [&](auto arg, Label label) { \
Expand Down Expand Up @@ -5838,6 +5840,7 @@ namespace {
void visitModuleType(ModuleType *T, Label label) {
printCommon("module_type", label);
printDeclName(T->getModule(), Label::always("module"));
printFlag(T->getModule()->isNonSwiftModule(), "foreign");
printFoot();
}

Expand Down
13 changes: 13 additions & 0 deletions lib/ClangImporter/ImportDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6277,6 +6277,19 @@ SwiftDeclConverter::importSwiftNewtype(const clang::TypedefNameDecl *decl,
synthesizedProtocols.push_back(kind);
return true;
}
// HACK: This method may be called before all extensions have been bound.
// This is a problem for newtypes in Foundation, which is what provides the
// `String: _ObjectiveCBridgeable` conformance; it can cause us to create
// `String`-backed newtypes which aren't bridgeable, causing typecheck
// failures and crashes down the line (rdar://142693093). Hardcode knowledge
// that this conformance will exist.
// FIXME: Defer adding conformances to newtypes instead of this. (#78731)
if (structDecl->getModuleContext()->isFoundationModule()
&& kind == KnownProtocolKind::ObjectiveCBridgeable
&& computedNominal == ctx.getStringDecl()) {
synthesizedProtocols.push_back(kind);
return true;
}

return false;
};
Expand Down
3 changes: 3 additions & 0 deletions lib/IRGen/GenCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "swift/AST/ASTContext.h"
#include "swift/AST/ClangModuleLoader.h"
#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/PrettyStackTrace.h"
#include "swift/Basic/Assertions.h"
#include "swift/IRGen/Linking.h"
#include "swift/Runtime/Config.h"
Expand Down Expand Up @@ -1473,6 +1474,8 @@ static bool doesClangExpansionMatchSchema(IRGenModule &IGM,
/// Expand the result and parameter types to the appropriate LLVM IR
/// types for C, C++ and Objective-C signatures.
void SignatureExpansion::expandExternalSignatureTypes() {
PrettyStackTraceType entry(IGM.Context, "using clang to expand signature for",
FnType);
assert(FnType->getLanguage() == SILFunctionLanguage::C);

auto SILResultTy = [&]() {
Expand Down
2 changes: 2 additions & 0 deletions lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "swift/IRGen/Linking.h"
#include "swift/Runtime/HeapObject.h"
#include "swift/SIL/FormalLinkage.h"
#include "swift/SIL/PrettyStackTrace.h"
#include "swift/SIL/SILDebugScope.h"
#include "swift/SIL/SILModule.h"
#include "swift/Subsystems.h"
Expand Down Expand Up @@ -3512,6 +3513,7 @@ llvm::Function *IRGenModule::getAddrOfSILFunction(
assert(forDefinition || !isDynamicallyReplaceableImplementation);
assert(!forDefinition || !shouldCallPreviousImplementation);

PrettyStackTraceSILFunction entry("lowering address of", f);
LinkEntity entity =
LinkEntity::forSILFunction(f, shouldCallPreviousImplementation);

Expand Down
3 changes: 3 additions & 0 deletions lib/IRGen/GenObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "swift/ClangImporter/ClangImporter.h"
#include "swift/Demangling/ManglingMacros.h"
#include "swift/IRGen/Linking.h"
#include "swift/SIL/PrettyStackTrace.h"
#include "swift/SIL/SILModule.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclObjC.h"
Expand Down Expand Up @@ -779,6 +780,8 @@ Callee irgen::getObjCMethodCallee(IRGenFunction &IGF,
llvm::Value *selfValue,
CalleeInfo &&info) {
SILDeclRef method = methodInfo.getMethod();
PrettyStackTraceSILDeclRef entry("lowering reference to ObjC method", method);

// Note that isolated deallocator is never called directly, only from regular
// deallocator
assert((method.kind == SILDeclRef::Kind::Initializer
Expand Down
7 changes: 7 additions & 0 deletions lib/IRGen/IRGenSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3118,6 +3118,8 @@ static bool mayDirectlyCallAsync(SILFunction *fn) {

void IRGenSILFunction::visitFunctionRefBaseInst(FunctionRefBaseInst *i) {
auto fn = i->getInitiallyReferencedFunction();
PrettyStackTraceSILFunction entry("lowering reference to", fn);

auto fnType = fn->getLoweredFunctionType();

auto fpKind = irgen::classifyFunctionPointerKind(fn);
Expand Down Expand Up @@ -8101,6 +8103,8 @@ void IRGenSILFunction::visitWitnessMethodInst(swift::WitnessMethodInst *i) {
CanType baseTy = i->getLookupType();
ProtocolConformanceRef conformance = i->getConformance();
SILDeclRef member = i->getMember();
PrettyStackTraceSILDeclRef entry("lowering use of witness method", member);

auto fnType = IGM.getSILTypes().getConstantFunctionType(
IGM.getMaximalTypeExpansionContext(), member);

Expand Down Expand Up @@ -8285,6 +8289,7 @@ void IRGenSILFunction::visitSuperMethodInst(swift::SuperMethodInst *i) {
llvm::Value *baseValue = base.claimNext();

auto method = i->getMember().getOverriddenVTableEntry();
PrettyStackTraceSILDeclRef entry("lowering super call to", method);
auto methodType = i->getType().castTo<SILFunctionType>();

auto *classDecl = cast<ClassDecl>(method.getDecl()->getDeclContext());
Expand Down Expand Up @@ -8381,6 +8386,8 @@ void IRGenSILFunction::visitClassMethodInst(swift::ClassMethodInst *i) {
llvm::Value *baseValue = base.claimNext();

SILDeclRef method = i->getMember().getOverriddenVTableEntry();
PrettyStackTraceSILDeclRef entry("lowering class method call to", method);

auto methodType = i->getType().castTo<SILFunctionType>();

auto *classDecl = cast<ClassDecl>(method.getDecl()->getDeclContext());
Expand Down
6 changes: 6 additions & 0 deletions lib/SIL/Utils/PrettyStackTrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,9 @@ void PrettyStackTraceSILNode::print(llvm::raw_ostream &out) const {
if (Node)
out << *Node;
}

void PrettyStackTraceSILDeclRef::print(llvm::raw_ostream &out) const {
out << "While " << action << " SIL decl '";
declRef.print(out);
out << "'\n";
}
4 changes: 3 additions & 1 deletion test/ClangImporter/newtype_conformance.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func acceptHashable<T: Hashable>(_: T) {}
func acceptComparable<T: Comparable>(_: T) {}
// expected-note@-1 {{where 'T' = 'NSNotification.Name'}}

func testNewTypeWrapper(x: NSNotification.Name, y: NSNotification.Name) {
func testNewTypeWrapper(x: NSNotification.Name, y: NSNotification.Name, z: NSFileAttributeKey) {
acceptEquatable(x)
acceptHashable(x)
acceptComparable(x) // expected-error {{global function 'acceptComparable' requires that 'NSNotification.Name' conform to 'Comparable'}}
Expand All @@ -28,6 +28,8 @@ func testNewTypeWrapper(x: NSNotification.Name, y: NSNotification.Name) {
_ = x != y
_ = x.hashValue
_ = x as NSString

_ = z as NSString
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

public let NSUTF8StringEncoding: UInt = 8

// This extension will cause ClangImporter/newtype_conformance.swift to fail
// unless rdar://142693093 is fixed. To reproduce, it's important that this
// extension come *before* the _ObjectiveCBridgeable extension for String.
extension NSFileAttributeKey { }

extension AnyHashable : _ObjectiveCBridgeable {
public func _bridgeToObjectiveC() -> NSObject {
return NSObject()
Expand Down
2 changes: 2 additions & 0 deletions test/Inputs/clang-importer-sdk/usr/include/Foundation.h
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,8 @@ extern void CGColorRelease(CGColorRef color) __attribute__((availability(macosx,

typedef NSString *_Nonnull NSNotificationName
__attribute((swift_newtype(struct)));
typedef NSString *_Nonnull NSFileAttributeKey
__attribute((swift_newtype(struct)));

NS_SWIFT_UNAVAILABLE("Use NSXPCConnection instead")
extern NSString * const NSConnectionReplyMode;
Expand Down