Skip to content

Commit 2e0b9d7

Browse files
authored
Merge pull request #82743 from hamishknight/diag-it-6.2
2 parents 6b838fb + ce273f4 commit 2e0b9d7

File tree

4 files changed

+63
-11
lines changed

4 files changed

+63
-11
lines changed

include/swift/AST/DiagnosticEngine.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -995,7 +995,10 @@ namespace swift {
995995

996996
/// Figure out the Behavior for the given diagnostic, taking current
997997
/// state such as fatality into account.
998-
DiagnosticBehavior determineBehavior(const Diagnostic &diag);
998+
DiagnosticBehavior determineBehavior(const Diagnostic &diag) const;
999+
1000+
/// Updates the diagnostic state for a diagnostic to emit.
1001+
void updateFor(DiagnosticBehavior behavior);
9991002

10001003
bool hadAnyError() const { return anyErrorOccurred; }
10011004
bool hasFatalErrorOccurred() const { return fatalErrorOccurred; }
@@ -1023,7 +1026,7 @@ namespace swift {
10231026

10241027
/// Returns a Boolean value indicating whether warnings belonging to the
10251028
/// diagnostic group identified by `id` should be escalated to errors.
1026-
bool getWarningsAsErrorsForDiagGroupID(DiagGroupID id) {
1029+
bool getWarningsAsErrorsForDiagGroupID(DiagGroupID id) const {
10271030
return warningsAsErrors[(unsigned)id];
10281031
}
10291032

lib/AST/DiagnosticEngine.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,7 +1263,8 @@ llvm::cl::opt<bool> AssertOnError("swift-diagnostics-assert-on-error",
12631263
llvm::cl::opt<bool> AssertOnWarning("swift-diagnostics-assert-on-warning",
12641264
llvm::cl::init(false));
12651265

1266-
DiagnosticBehavior DiagnosticState::determineBehavior(const Diagnostic &diag) {
1266+
DiagnosticBehavior
1267+
DiagnosticState::determineBehavior(const Diagnostic &diag) const {
12671268
// We determine how to handle a diagnostic based on the following rules
12681269
// 1) Map the diagnostic to its "intended" behavior, applying the behavior
12691270
// limit for this particular emission
@@ -1310,21 +1311,23 @@ DiagnosticBehavior DiagnosticState::determineBehavior(const Diagnostic &diag) {
13101311
if (suppressRemarks)
13111312
lvl = DiagnosticBehavior::Ignore;
13121313
}
1314+
return lvl;
1315+
}
13131316

1314-
// 5) Update current state for use during the next diagnostic
1315-
if (lvl == DiagnosticBehavior::Fatal) {
1317+
void DiagnosticState::updateFor(DiagnosticBehavior behavior) {
1318+
// Update current state for use during the next diagnostic
1319+
if (behavior == DiagnosticBehavior::Fatal) {
13161320
fatalErrorOccurred = true;
13171321
anyErrorOccurred = true;
1318-
} else if (lvl == DiagnosticBehavior::Error) {
1322+
} else if (behavior == DiagnosticBehavior::Error) {
13191323
anyErrorOccurred = true;
13201324
}
13211325

13221326
ASSERT((!AssertOnError || !anyErrorOccurred) && "We emitted an error?!");
1323-
ASSERT((!AssertOnWarning || (lvl != DiagnosticBehavior::Warning)) &&
1327+
ASSERT((!AssertOnWarning || (behavior != DiagnosticBehavior::Warning)) &&
13241328
"We emitted a warning?!");
13251329

1326-
previousBehavior = lvl;
1327-
return lvl;
1330+
previousBehavior = behavior;
13281331
}
13291332

13301333
void DiagnosticEngine::flushActiveDiagnostic() {
@@ -1369,6 +1372,8 @@ std::optional<DiagnosticInfo>
13691372
DiagnosticEngine::diagnosticInfoForDiagnostic(const Diagnostic &diagnostic,
13701373
bool includeDiagnosticName) {
13711374
auto behavior = state.determineBehavior(diagnostic);
1375+
state.updateFor(behavior);
1376+
13721377
if (behavior == DiagnosticBehavior::Ignore)
13731378
return std::nullopt;
13741379

lib/Sema/TypeCheckExpr.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -774,14 +774,30 @@ Expr *CallerSideDefaultArgExprRequest::evaluate(
774774
if (!TypeChecker::typeCheckParameterDefault(initExpr, dc, paramTy,
775775
param->isAutoClosure(),
776776
/*atCallerSide=*/true)) {
777-
if (param->hasDefaultExpr()) {
777+
auto isSimpleLiteral = [&]() -> bool {
778+
switch (param->getDefaultArgumentKind()) {
779+
#define MAGIC_IDENTIFIER(NAME, STRING) \
780+
case DefaultArgumentKind::NAME: return true;
781+
#include "swift/AST/MagicIdentifierKinds.def"
782+
case DefaultArgumentKind::NilLiteral:
783+
case DefaultArgumentKind::EmptyArray:
784+
case DefaultArgumentKind::EmptyDictionary:
785+
return true;
786+
default:
787+
return false;
788+
}
789+
};
790+
if (param->hasDefaultExpr() && isSimpleLiteral()) {
778791
// HACK: If we were unable to type-check the default argument in context,
779792
// then retry by type-checking it within the parameter decl, which should
780793
// also fail. This will present the user with a better error message and
781794
// allow us to avoid diagnosing on each call site.
795+
// Note we can't do this for expression macros since name lookup may
796+
// differ at the call side vs the declaration. We can however do it for
797+
// simple literals.
782798
transaction.abort();
783799
(void)param->getTypeCheckedDefaultExpr();
784-
assert(ctx.Diags.hadAnyError());
800+
CONDITIONAL_ASSERT(ctx.Diags.hadAnyError());
785801
}
786802
return new (ctx) ErrorExpr(initExpr->getSourceRange(), paramTy);
787803
}

test/Macros/rdar154771596.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// REQUIRES: swift_swift_parser
2+
3+
// RUN: %empty-directory(%t)
4+
// RUN: split-file %s %t
5+
6+
// RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %S/Inputs/syntax_macro_definitions.swift -g -no-toolchain-stdlib-rpath
7+
8+
// RUN: %target-swift-frontend -emit-module %t/Lib.swift -module-name Lib -emit-module-path %t/Lib.swiftmodule
9+
10+
// RUN: %target-swift-frontend -typecheck -verify -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -I %t %t/a.swift -primary-file %t/b.swift
11+
12+
//--- Lib.swift
13+
14+
@freestanding(expression)
15+
public macro magicFile() -> String = #externalMacro(module: "MacroDefinition", type: "MagicFileMacro")
16+
17+
//--- a.swift
18+
19+
import Lib
20+
21+
func foo(x: String = #magicFile) {}
22+
23+
//--- b.swift
24+
25+
// We're missing the necessary import in this file, make sure we diagnose.
26+
func bar() {
27+
foo() // expected-error {{no macro named 'magicFile'}}
28+
}

0 commit comments

Comments
 (0)