Skip to content

Commit 5e4ece7

Browse files
committed
[lldb] Handle diagnostics better around expression evaulation retries
The error message produced when expression evaluation parsing failed with automatic retries was not great, and would confuse many users. Change the logic around what diagnostics should be displayed to the user if expression evaluation parsing retry also fails to show the original error message. rdar://118057664
1 parent 0309db7 commit 5e4ece7

File tree

2 files changed

+38
-9
lines changed

2 files changed

+38
-9
lines changed

lldb/source/Plugins/ExpressionParser/Swift/SwiftUserExpression.cpp

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -755,13 +755,40 @@ exe_scope = exe_ctx.GetBestExecutionContextScope();
755755
m_options.SetGenerateDebugInfo(generate_debug_info);
756756

757757
using ParseResult = SwiftExpressionParser::ParseResult;
758-
758+
// Use a separate diagnostic manager instead of the main one, the reason we do
759+
// this is that on retries we would like to ignore diagnostics produced by
760+
// either the first or second try.
761+
DiagnosticManager first_try_diagnostic_manager;
762+
DiagnosticManager second_try_diagnostic_manager;
763+
764+
bool retry = false;
759765
while (true) {
760-
SwiftExpressionParser::ParseResult parse_result =
761-
GetTextAndSetExpressionParser(diagnostic_manager, source_code, exe_ctx,
762-
exe_scope);
766+
SwiftExpressionParser::ParseResult parse_result;
767+
if (!retry) {
768+
parse_result = GetTextAndSetExpressionParser(
769+
first_try_diagnostic_manager, source_code, exe_ctx, exe_scope);
770+
if (parse_result != SwiftExpressionParser::ParseResult::
771+
retry_no_bind_generic_params ||
772+
m_options.GetBindGenericTypes() != lldb::eBindAuto)
773+
// If we're not retrying, just copy the diagnostics over.
774+
diagnostic_manager.Consume(std::move(first_try_diagnostic_manager));
775+
} else {
776+
parse_result = GetTextAndSetExpressionParser(
777+
second_try_diagnostic_manager, source_code, exe_ctx, exe_scope);
778+
if (parse_result == SwiftExpressionParser::ParseResult::success)
779+
// If we succeeded the second time around, copy any diagnostics we
780+
// produced in the success case over, and ignore the first attempt's
781+
// failures.
782+
diagnostic_manager.Consume(std::move(second_try_diagnostic_manager));
783+
else
784+
// If we failed though, copy the diagnostics of the first attempt, and
785+
// silently ignore any errors produced by the retry, as the retry was
786+
// not what the user asked, and any diagnostics produced by it will
787+
// most likely confuse the user.
788+
diagnostic_manager.Consume(std::move(first_try_diagnostic_manager));
789+
}
763790

764-
if (parse_result == ParseResult::success)
791+
if (parse_result == SwiftExpressionParser::ParseResult::success)
765792
break;
766793

767794
switch (parse_result) {
@@ -770,13 +797,10 @@ exe_scope = exe_ctx.GetBestExecutionContextScope();
770797
// BindGenericTypes was in the auto setting, give up otherwise.
771798
if (m_options.GetBindGenericTypes() != lldb::eBindAuto)
772799
return false;
773-
diagnostic_manager.Clear();
774-
diagnostic_manager.PutString(eDiagnosticSeverityRemark,
775-
"Expression evaluation failed. Retrying "
776-
"without binding generic parameters");
777800
// Retry without binding generic parameters, this is the only
778801
// case that will loop.
779802
m_options.SetBindGenericTypes(lldb::eDontBind);
803+
retry = true;
780804
break;
781805

782806
case ParseResult::retry_fresh_context:

lldb/test/API/lang/swift/private_generic_type/TestSwiftPrivateGenericType.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,8 @@ def test_private_generic_type(self):
151151
substrs=["Could not evaluate the expression without binding generic types."],
152152
error=True)
153153

154+
# Check that if both binding and not binding the generic type parameters fail, we report
155+
# the "bind generic params" error message, as that's the default case that runs first.
156+
self.expect("e --bind-generic-types auto -- self",
157+
substrs=["Couldn't realize Swift AST type of self."],
158+
error=True)

0 commit comments

Comments
 (0)