From 67b212869a65d95be86eaf414495b94418c9e518 Mon Sep 17 00:00:00 2001 From: Jonathan Grynspan Date: Wed, 25 Jun 2025 15:49:37 -0400 Subject: [PATCH] Lower the "ambiguous display name" diagnostic to a warning for some names. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR modifies the behaviour of this compile-time macro diagnostic: > 🛑 "Attribute 'Test' specifies display name 'foo' for function with implicit > display name 'bar' If `bar` (in the above context) is _not_ considered a raw identifier by the language, we emit a warning instead of an error. This will allow us to adjust display-name-from-backticked-name inference (see #1174) without introducing a source-breaking change for a declaration such as: ```swift @Test("subscript([K]) operator") func `subscript`() ``` (The above is a real-world test function in our own package that would be impacted.) Note that we don't actually have a code path that triggers this warning yet. #1174, if approved and merged, would introduce such a code path. --- .../TestingMacros/Support/AttributeDiscovery.swift | 3 ++- .../TestingMacros/Support/DiagnosticMessage.swift | 12 +++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Sources/TestingMacros/Support/AttributeDiscovery.swift b/Sources/TestingMacros/Support/AttributeDiscovery.swift index a61989aef..3d95df294 100644 --- a/Sources/TestingMacros/Support/AttributeDiscovery.swift +++ b/Sources/TestingMacros/Support/AttributeDiscovery.swift @@ -144,8 +144,9 @@ struct AttributeInfo { let rawIdentifier = namedDecl.name.rawIdentifier { if let displayName, let displayNameArgument { context.diagnose(.declaration(namedDecl, hasExtraneousDisplayName: displayName, fromArgument: displayNameArgument, using: attribute)) + } else { + displayName = StringLiteralExprSyntax(content: rawIdentifier) } - displayName = StringLiteralExprSyntax(content: rawIdentifier) } // Remove leading "Self." expressions from the arguments of the attribute. diff --git a/Sources/TestingMacros/Support/DiagnosticMessage.swift b/Sources/TestingMacros/Support/DiagnosticMessage.swift index b7103bcc6..9f155b63a 100644 --- a/Sources/TestingMacros/Support/DiagnosticMessage.swift +++ b/Sources/TestingMacros/Support/DiagnosticMessage.swift @@ -657,10 +657,16 @@ struct DiagnosticMessage: SwiftDiagnostics.DiagnosticMessage { fromArgument argumentContainingDisplayName: LabeledExprListSyntax.Element, using attribute: AttributeSyntax ) -> Self { - Self( + // If the name of the ambiguously-named symbol should be derived from a raw + // identifier, this situation is an error. If the name is not raw but is + // still surrounded by backticks (e.g. "func `foo`()" or "struct `if`") then + // lower the severity to a warning. That way, existing code structured this + // way doesn't suddenly fail to build. + let severity: DiagnosticSeverity = (decl.name.rawIdentifier != nil) ? .error : .warning + return Self( syntax: Syntax(decl), - message: "Attribute \(_macroName(attribute)) specifies display name '\(displayNameFromAttribute.representedLiteralValue!)' for \(_kindString(for: decl)) with implicit display name '\(decl.name.rawIdentifier!)'", - severity: .error, + message: "Attribute \(_macroName(attribute)) specifies display name '\(displayNameFromAttribute.representedLiteralValue!)' for \(_kindString(for: decl)) with implicit display name '\(decl.name.textWithoutBackticks)'", + severity: severity, fixIts: [ FixIt( message: MacroExpansionFixItMessage("Remove '\(displayNameFromAttribute.representedLiteralValue!)'"),